inline int get_repeat(struct ir_remote *remote)
{
	if (!get_lead(remote))
		return (0);
	if (is_biphase(remote)) {
		if (!expectspace(remote, remote->srepeat))
			return (0);
		if (!expectpulse(remote, remote->prepeat))
			return (0);
	} else {
		if (!expectpulse(remote, remote->prepeat))
			return (0);
		set_pending_space(remote->srepeat);
	}
	if (!get_trail(remote))
		return (0);
	if (!get_gap
	    (remote,
	     is_const(remote) ? (min_gap(remote) >
				 rec_buffer.sum ? min_gap(remote) -
				 rec_buffer.sum : 0) : (has_repeat_gap(remote) ? remote->repeat_gap : min_gap(remote))
	    ))
		return (0);
	return (1);
}
Beispiel #2
0
void calculate_signal_lengths(struct ir_remote *remote)
{
	if(is_const(remote))
	{
		remote->min_total_signal_length = min_gap(remote);
		remote->max_total_signal_length = max_gap(remote);
	}
	else
	{
		remote->min_gap_length = min_gap(remote);
		remote->max_gap_length = max_gap(remote);
	}

	lirc_t min_signal_length = 0, max_signal_length = 0;
	lirc_t max_pulse = 0, max_space = 0;
	int first_sum = 1;
	struct ir_ncode *c = remote->codes;
	int i;

	while(c->name)
	{
		struct ir_ncode code = *c;
		struct ir_code_node *next = code.next;
		int first = 1;
		int repeat = 0;
		do{
			if(first)
			{
				first = 0;
			}
			else
			{
				code.code = next->code;
				next = next->next;
			}
			for(repeat = 0; repeat < 2; repeat++)
			{
				if(init_sim(remote, &code, repeat))
				{
					lirc_t sum = send_buffer.sum;

					if(sum)
					{
						if(first_sum ||
						   sum < min_signal_length)
						{
							min_signal_length = sum;
						}
						if(first_sum ||
						   sum > max_signal_length)
						{
							max_signal_length = sum;
						}
						first_sum = 0;
					}
					for(i=0; i<send_buffer.wptr; i++)
					{
						if(i&1) /* space */
						{
							if(send_buffer.data[i] > max_space)
							{
								max_space = send_buffer.data[i];
							}
						}
						else /* pulse */
						{
							if(send_buffer.data[i] > max_pulse)
							{
								max_pulse = send_buffer.data[i];
							}
						}
					}
				}
			}
		} while(next);
		c++;
	}
	if(first_sum)
	{
		/* no timing data, so assume gap is the actual total
		   length */
		remote->min_total_signal_length = min_gap(remote);
		remote->max_total_signal_length = max_gap(remote);
		remote->min_gap_length = min_gap(remote);
		remote->max_gap_length = max_gap(remote);
	}
	else if(is_const(remote))
	{
		if(remote->min_total_signal_length > max_signal_length)
		{
			remote->min_gap_length =
				remote->min_total_signal_length
				- max_signal_length;
		}
		else
		{
			logprintf(LOG_WARNING, "min_gap_length is 0 for "
				  "'%s' remote", remote->name);
			remote->min_gap_length = 0;
		}
		if(remote->max_total_signal_length > min_signal_length)
		{
			remote->max_gap_length =
				remote->max_total_signal_length
				- min_signal_length;
		}
		else
		{
			logprintf(LOG_WARNING, "max_gap_length is 0 for "
				  "'%s' remote", remote->name);
			remote->max_gap_length = 0;
		}
	}
	else
	{
		remote->min_total_signal_length = min_signal_length +
			remote->min_gap_length;
		remote->max_total_signal_length = max_signal_length +
			remote->max_gap_length;
	}
	LOGPRINTF(1, "lengths: %lu %lu %lu %lu",
		  remote->min_total_signal_length,
		  remote->max_total_signal_length,
		  remote->min_gap_length,
		  remote->max_gap_length);
}
Beispiel #3
0
int init_send(struct ir_remote *remote,struct ir_ncode *code)
{
	int i, repeat=0;
	
	if(is_grundig(remote) || 
	   is_goldstar(remote) || is_serial(remote) || is_bo(remote))
	{
		logprintf(LOG_ERR,"sorry, can't send this protocol yet");
		return(0);
	}
	clear_send_buffer();
	if(is_biphase(remote))
	{
		send_buffer.is_biphase=1;
	}
	if(repeat_remote==NULL)
	{
		remote->repeat_countdown=remote->min_repeat;
	}
	else
	{
		repeat = 1;
	}
	
 init_send_loop:
	if(repeat && has_repeat(remote))
	{
		if(remote->flags&REPEAT_HEADER && has_header(remote))
		{
			send_header(remote);
		}
		send_repeat(remote);
	}
	else
	{
		if(!is_raw(remote))
		{
			ir_code next_code;
			
			if(code->transmit_state == NULL)
			{
				next_code = code->code;
			}
			else
			{
				next_code = code->transmit_state->code;
			}
			send_code(remote, next_code, repeat);
			if(has_toggle_mask(remote))
			{
				remote->toggle_mask_state++;
				if(remote->toggle_mask_state==4)
				{
					remote->toggle_mask_state=2;
				}
			}
			send_buffer.data=send_buffer._data;
		}
		else
		{
			if(code->signals==NULL)
			{
				logprintf(LOG_ERR, "no signals for raw send");
				return 0;
			}
			if(send_buffer.wptr>0)
			{
				send_signals(code->signals, code->length);
			}
			else
			{
				send_buffer.data=code->signals;
				send_buffer.wptr=code->length;
				for(i=0; i<code->length; i++)
				{
					send_buffer.sum+=code->signals[i];
				}
			}
		}
	}
	sync_send_buffer();
	if(bad_send_buffer())
	{
		logprintf(LOG_ERR,"buffer too small");
		return(0);
	}
	if(has_repeat_gap(remote) && repeat && has_repeat(remote))
	{
		remote->min_remaining_gap=remote->repeat_gap;
		remote->max_remaining_gap=remote->repeat_gap;
	}
	else if(is_const(remote))
	{
		if(min_gap(remote)>send_buffer.sum)
		{
			remote->min_remaining_gap=min_gap(remote)-send_buffer.sum;
			remote->max_remaining_gap=max_gap(remote)-send_buffer.sum;
		}
		else
		{
			logprintf(LOG_ERR,"too short gap: %u",remote->gap);
			remote->min_remaining_gap=min_gap(remote);
			remote->max_remaining_gap=max_gap(remote);
			return(0);
		}
	}
	else
	{
		remote->min_remaining_gap=min_gap(remote);
		remote->max_remaining_gap=max_gap(remote);
	}
	/* update transmit state */
	if(code->next != NULL)
	{
		if(code->transmit_state == NULL)
		{
			code->transmit_state = code->next;
		}
		else
		{
			code->transmit_state = code->transmit_state->next;
		}
	}
	if((remote->repeat_countdown>0 || code->transmit_state != NULL) &&
	   remote->min_remaining_gap<LIRCD_EXACT_GAP_THRESHOLD)
	{
		if(send_buffer.data!=send_buffer._data)
		{
			lirc_t *signals;
			int n;
			
			LOGPRINTF(1, "unrolling raw signal optimisation");
			signals=send_buffer.data;
			n=send_buffer.wptr;
			send_buffer.data=send_buffer._data;
			send_buffer.wptr=0;
			
			send_signals(signals, n);
		}
		LOGPRINTF(1, "concatenating low gap signals");
		if(code->next == NULL || code->transmit_state == NULL)
		{
			remote->repeat_countdown--;
		}
		send_space(remote->min_remaining_gap);
		flush_send_buffer();
		send_buffer.sum=0;
		
		repeat = 1;
		goto init_send_loop;
	}
	LOGPRINTF(3, "transmit buffer ready");
	return(1);
}