⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 learndlg.cpp

📁 WinLIRC软件:WinLIRC是一个以 LIRC为基础而在Windows环境发展出来的模块, 而什么是LIRC呢...它其实是 Linux InfraredRemote Control的缩写, 本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				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 + -