📄 learndlg.cpp
字号:
return false;
waitgap=false;
}
else
{
/* we've hit the end */
if(is_space(data) && data>remote.gap-remote.gap*remote.eps/100)
return true;
signals[count]=data&(PULSE_BIT-1);
count++;
}
}
return false;
}
bool Clearndlg::GetButton(unsigned long *signals, bool repeating)
{
/* read 64 samples if repeating */
/* read 8 samples if non-repeating */
int count, i, j;
unsigned long sig[MAX_SIGNALS+1];
unsigned long last_sig[MAX_SIGNALS+1];
while(drv->readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */
int fault=0, expectfault=0;
bool match=false;
bool first=true;
char s[256];
if(repeating)
{
sprintf(s,"Please press and hold down the '%s' button until told to stop.",code.name);
output(s);
}
else
{
sprintf(s,"Please repeatedly press and release the '%s' button until",code.name);
output(s),
output("told to stop. You must wait at least half of a second");
output("between keypresses or they will not be recognized.");
}
while(!match)
{
/* read two in a row that match */
match=true;
if(!repeating)
while(drv->readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */
if(!GetRawButton(sig,count,repeating?first:true))
{
DEBUG("GetRawButton failed\n");
match=false;
}
if(count!=code.length)
{
DEBUG("Bad count: count=%d, code.length=%d\n",count,code.length);
match=false;
}
for(i=0;i<code.length&&match;i++)
if(!expect(&remote,last_sig[i],sig[i]))
{
expectfault++;
DEBUG("signal too far from old signal\n");
match=false;
}
if(!match)
{
fault++;
if(fault>(repeating?10:5))
{
DEBUG("failed to get consistent signal\n");
output("Stop. Failed to get a consistent initial signal. "
" Please try again.");
if(expectfault>(repeating?8:4))
{
output("You will probably get better results if you");
output("increase the margin of error for this remote.");
}
return false;
}
if(!repeating)
output("No match yet; please continue");
}
first=false;
for(i=0;i<code.length;i++)
last_sig[i]=sig[i];
}
if(repeating)
output("Baseline initialized.");
else
output("Baseline initialized. Please continue to press the button.");
fault=0;
for(i=0;i<code.length;i++) signals[i]=(sig[i]+last_sig[i])/2;
j=2;
output(""); // need this to prevent last line from being overwritten
while(j<(repeating?64:8))
{
sprintf(s,"matches=%d, faults=%d",j,fault);
output(s,true);
match=true;
if(!repeating)
while(drv->readdata(250*1000,LearnThreadEvent)!=0)
; /* wait for signals to stop coming for at least 0.25 sec */
if(!GetRawButton(sig,count,repeating?false:true))
{
DEBUG("GetRawButton failed\n");
match=false;
}
if(count!=code.length)
{
DEBUG("Bad count: count=%d, code.length=%d\n",count,code.length);
match=false;
}
for(i=0;i<code.length&&match;i++)
if(!expect(&remote,signals[i],sig[i]))
{
DEBUG("signal too far from old signal\n");
match=false;
}
if(!match)
{
fault++;
if(fault>(repeating?64:12))
{
DEBUG("failed to get consistent signal\n");
output("Stop. Failed to get a consistent signal. Please try again.");
return false;
}
}
else
{
for(i=0;i<code.length;i++)
signals[i]=(signals[i]*j + sig[i])/(j+1);
j++;
}
}
sprintf(s,"matches=%d, faults=%d",j,fault);
output(s,true);
output("Stop.");
return true;
}
void Clearndlg::DoGetButtons(void)
{
output("Step Two: Input buttons.");
output("----------------------------------------------------------------"
"----------------------------------------------------------------");
output("");
if(remote.prepeat==0)
{
DEBUG("this remote is a signal repeating remote\n");
output("This is a signal-repeating remote with no special repeat code.");
output("Holding down the button can quickly yield many copies of that "
"button's code.");
output("Therefore, 64 samples of each button will be taken.");
}
else
{
DEBUG("this remote has a special repeat code\n");
output("This remote has a special repeat code.");
output("The button needs to be pressed and released for each new copy of that");
output("button's code. 8 samples of each button will be taken.");
}
output("");
output("You will be prompted to enter each button's name in turn.");
output("To finish recording buttons, enter a blank button name.");
output("");
char buffer[BUTTON];
unsigned long signals[MAX_SIGNALS+1];
code.signals=signals;
char s[1024];
int button=1;
for(;;)
{
if(button>1)
sprintf(s,"Button %d name? (blank to stop)",button);
else
sprintf(s,"Button %d name?",button);
input(s,buffer,BUTTON,true);
if(strchr(buffer,' ') || strchr(buffer,'\t'))
{
output("A button name may not contain any whitespace.");
continue;
}
if(strlen(buffer)==0) break;
code.name=buffer;
bool res=false;
res=GetButton(signals,(remote.prepeat==0)?true:false);
if(!res)
{
DEBUG("GetButton failed\n");
continue;
}
output("");output("");
sprintf(s,"Button '%s' recorded. Do you wish to keep this recording?",buffer);
if(MessageBox(s,"Keep it?",MB_YESNO)==IDNO) continue;
fprint_remote_signal(fout,&remote,&code);
button++;
}
fprint_remote_signal_foot(fout,&remote);
fprint_remote_foot(fout,&remote);
}
void Clearndlg::LearnThreadProc(void)
{
char s[256];
char brand[64];
unsigned long data;
output("This will record the signals from your remote control");
output("and create a config file for WinLIRC.");
output("");
remote.flags=RAW_CODES;
remote.aeps=AEPS;
do {
input("Please enter a name for this remote.",brand,63);
if(strchr(brand,' ') || strchr(brand,'\t'))
{
output("The remote name may not contain any whitespace.");
brand[0]=0;
}
} while(brand[0]==0);
remote.name=brand;
output(brand);
output("");
output("When learning and analyzing signals, a margin of error is used in order to");
output("handle the normal variations in the received signal. The margin of error");
sprintf(s,"ranges from 1%% to 99%%. The default is %d%%, but larger values might",EPS);
output(s);
output("be necessary depending on your hardware and software. If you are having");
output("trouble using your remote, try increasing this value. You may enter the");
output("allowable margin of error now, or press ENTER to use the default.");
output("");
int user_eps=0;
do {
sprintf(s,"Desired margin of error for this remote? (1-99, enter=%d)",EPS);
input(s,s,63,true);
if(strlen(s)==0) user_eps=EPS;
else user_eps=atoi(s);
} while(user_eps<1 || user_eps>99);
remote.eps=user_eps;
/* Clear out the buffer */
while(drv->GetData(&data)==true)
;
output(NULL);
DoGetGap();
output(NULL);
DoGetButtons();
MessageBox("Configuration successfully written.","Success");
EndDialog2(IDOK);
DEBUG("LearnThread terminating\n");
AfxEndThread(0);
return;
}
void Clearndlg::RawThreadProc(void)
{
output("Outputting raw mode2 data.");
DEBUG("Raw mode2 data:\n");
output("");
unsigned long int x;
char s[256];
for(;;)
{
x=drv->readdata(0,LearnThreadEvent);
if(x&PULSE_BIT)
sprintf(s,"pulse %ld",x&~PULSE_BIT);
else
sprintf(s,"space %ld",x&~PULSE_BIT);
output(s);
strcat(s,"\n");
DEBUG(s);
}
}
void Clearndlg::AnalyzeThreadProc(void)
{
output("Analyzing data, please wait...");
/* Read it in */
struct ir_remote *myremotes, *sr;
myremotes=read_config(fout);
/* See if it's OK */
bool ok=true;
if(myremotes==(struct ir_remote *)-1 || myremotes==NULL)
ok=false;
for(sr=myremotes;sr!=NULL&&ok;sr=sr->next)
{
if(sr->codes==NULL)
{
free_config(myremotes);
myremotes=NULL;
ok=false;
}
}
if(!ok)
{
MessageBox("Error parsing configuration file.\n","Error");
EndDialog2(IDCANCEL);
DEBUG("AnalyzeThread terminating\n");
AfxEndThread(0);
return;
}
fclose(fout); fout=NULL;
/* Now analyze it */
if(analyze(myremotes)==-1)
{
free_config(myremotes);
myremotes=NULL;
MessageBox("Analysis failed. This remote is probably only\n"
"supported in raw mode. Configuration file is unchanged.","Error");
EndDialog2(IDCANCEL);
DEBUG("AnalyzeThread terminating\n");
AfxEndThread(0);
return;
}
/* Yay, success */
if((fout=fopen(filename,"w"))==NULL)
{
free_config(myremotes);
myremotes=NULL;
MessageBox("Analysis succeeded, but re-open of file failed."
"Configuration file is unchanged.","Error");
EndDialog2(IDCANCEL);
DEBUG("AnalyzeThread terminating\n");
AfxEndThread(0);
return;
}
fprint_remotes(fout,myremotes);
free_config(myremotes);
myremotes=NULL;
MessageBox("Analysis successful.\n","Success");
EndDialog2(IDOK);
DEBUG("AnalyzeThread terminating\n");
AfxEndThread(0);
return;
}
/* Analysis stuff from here down */
int Clearndlg::analyze(struct ir_remote *remotes)
{
int scheme;
while(remotes!=NULL)
{
if(remotes->flags&RAW_CODES)
{
scheme=get_scheme(remotes);
switch(scheme)
{
case 0:
output("Config file does not contain any buttons.");
return(-1);
break;
case SPACE_ENC:
if(-1==check_lengths(remotes))
{
output("check_lengths failed");
return(-1);
}
if(-1==get_lengths(remotes))
{
output("get_lengths failed");
return(-1);
}
remotes->flags&=~RAW_CODES;
remotes->flags|=SPACE_ENC;
if(-1==get_codes(remotes))
{
remotes->flags&=~SPACE_ENC;
remotes->flags|=RAW_CODES;
output("get_codes failed");
return(-1);
}
get_pre_data(remotes);
get_post_data(remotes);
break;
case SHIFT_ENC:
output("Shift encoded remotes are not supported yet.");
return(-1);
break;
}
}
remotes=remotes->next;
}
return(0);
}
int Clearndlg::get_sum(struct ir_remote *remote)
{
int sum,i;
struct ir_ncode *codes;
sum=0;
codes=remote->codes;
for(i=0;codes[i].name!=NULL;i++)
{
sum++;
}
return(sum);
}
int Clearndlg::get_scheme(struct ir_remote *remote)
{
struct ir_ncode *codes;
int match,sum,i,j;
sum=get_sum(remote);
if(sum==0)
{
return(0);
}
codes=remote->codes;
for(i=0;i<sum;i++)
{
match=0;
for(j=i+1;j<sum;j++)
{
if(codes[i].length==codes[j].length)
{
match++;
/* I want less than 20% mismatches */
if(match>=80*sum/100)
{
/* this is not yet the
number of bits */
remote->bits=codes[i].length;
return(SPACE_ENC);
}
}
}
}
return(SHIFT_ENC);
}
int Clearndlg::check_lengths(struct ir_remote *remote)
{
int i,flag;
struct ir_ncode *codes;
flag=0;
codes=remote->codes;
for(i=0;codes[i].name!=NULL;i++)
{
if(codes[i].length!=remote->bits)
{
char s[128];
_snprintf(s,127,"Button \"%s\" has wrong signal length.\r\n"
"Try to record it again.",codes[i].name);
output(s);
flag=-1;
}
}
return(flag);
}
struct lengths *Clearndlg::new_length(unsigned long length)
{
struct lengths *l;
l=(struct lengths *)malloc(sizeof(struct lengths));
if(l==NULL) return(NULL);
l->count=1;
l->sum=length;
l->lower_bound=length/100*100;
l->upper_bound=length/100*100+99;
l->min=l->max=length;
l->next=NULL;
return(l);
}
int Clearndlg::add_length(struct lengths **first,unsigned long length)
{
struct lengths *l,*last;
if(*first==NULL)
{
*first=new_length(length);
if(*first==NULL) return(-1);
return(0);
}
l=*first;
while(l!=NULL)
{
if(l->lower_bound<=length && length<=l->upper_bound)
{
l->count++;
l->sum+=length;
l->min=min(l->min,length);
l->max=max(l->max,length);
return(0);
}
last=l;
l=l->next;
}
last->next=new_length(length);
if(last->next==NULL) return(-1);
return(0);
}
void Clearndlg::free_lengths(struct lengths *first)
{
struct lengths *next;
if(first==NULL) return;
while(first!=NULL)
{
next=first->next;
free(first);
first=next;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -