Next, here comes the latest version of my IR learning patch for
libconcord. As my first try, it changes the API from one
'learnIR' function to four functions:

This patch is a full patch against the CVS version of concordance.
Compared to the first version, it removes again the -o option that
would enforce to give Pronto hex code for all keys. Instead,
the user may now specify whether to:
- Learn code from other remote via the Harmony
- Input Pronto hex code
- Skip to next or previous key command in the list, or
- Quit all learning from this file

It also fixes all warnings from the Microsoft C++ compiler.

Those who don't want to use libIRremotes may apply the second patch
concordance.c-no_irremotes-20080615.patch on top of the first one, 
which will remove all Pronto/libIRremotes related code from concordance.c.

Andreas
Index: concordance/Makefile.am
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/Makefile.am,v
retrieving revision 1.7
diff -u -3 -p -u -p -r1.7 Makefile.am
--- concordance/Makefile.am	14 Apr 2008 01:55:46 -0000	1.7
+++ concordance/Makefile.am	15 Jun 2008 10:44:20 -0000
@@ -1,6 +1,6 @@
 bin_PROGRAMS = concordance
 concordance_SOURCES = concordance.c
-concordance_LDFLAGS = -lconcord
+concordance_LDFLAGS = -lconcord -lIRremotes
 # -Wall just makes good sense
 # -ansi and -pednatic errors are needed to ensure we're compatible with
 # crappy Microsoft compilers - phil
Index: concordance/concordance.1
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.1,v
retrieving revision 1.9
diff -u -3 -p -u -p -r1.9 concordance.1
--- concordance/concordance.1	15 Apr 2008 02:32:32 -0000	1.9
+++ concordance/concordance.1	15 Jun 2008 10:44:20 -0000
@@ -60,7 +60,7 @@ Get time from the remote
 Set the time on the remote
 .TP
 .B \-l, \-\-learn-ir <filename>
-Learn IR from other remotes. Use <filename>.
+Learn IR from other remotes. Use <filename>. Current version also supports files with multiple codes, i.e. when you checked multiple commands on the Logitech website. For each command, you have the choice to skip to the next or previous command, learn the IR code fromthe original remote or enter a raw Philips Pronto hex code, which will be translated to a format that the Logitech database recognizes.
 .TP
 .B \-r, \-\-reset
 Reset (power-cycle) the remote control
@@ -90,13 +90,16 @@ Enable verbose output.
 .TP
 .B \-w, \-\-no\-web
 Do not attempt to talk to the website. This is useful for re-programming the remote from a saved file, or for debugging.
+.TP
 .SH BUGS
 None known at time of release, but check the website.
 .SH BUG REPORTS
 Please file all bug reports in the bugs section of our SourceForge Project page.
 .SH NOTES
 This software is not supported, affiliated, or controlled by Logitech in any way.
+.TP
+Pronto hex codes for many remote controlled devices can be found e.g. at http://www.remotecentral.com.
 .SH AUTHOR
-\fBconcordance\fP was written by Kevin Timmerman and Phil Dibowitz
+\fBconcordance\fP was written by Kevin Timmerman and Phil Dibowitz; IR learning update by Andreas Schulz
 .br
 http://www.phildev.net/concordance/
Index: concordance/concordance.c
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.c,v
retrieving revision 1.32
diff -u -3 -p -u -p -r1.32 concordance.c
--- concordance/concordance.c	15 Apr 2008 06:17:02 -0000	1.32
+++ concordance/concordance.c	15 Jun 2008 10:44:20 -0000
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <libIRremotes.h>
 
 #ifdef WIN32
 /* Windows includes*/
@@ -37,6 +38,7 @@
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
 #define sleep(x) Sleep((x) * 1000)
+#define strdup _strdup
 
 /*
  * Windows, in it's infinite awesomeness doesn't include POSIX things
@@ -140,6 +142,188 @@ void cb_print_percent_status(uint32_t co
 	fflush(stdout);
 }
 
+void _printburst(uint32_t length)
+{
+	if (length < 250) {
+		printf("|");
+	} else if (length < 1000) {
+		printf("#");
+	} else {
+		printf("##");
+	}
+}
+
+void _printspace(uint32_t length)
+{
+	if (length < 250) {
+		printf(".");
+	} else if (length < 1000) {
+		printf("_");
+	} else if (length < 10000) {
+		printf("__");
+	} else {
+		printf("\n");
+	}
+}
+
+void _dump_new_code(uint32_t carrier_clock, uint32_t *pulses, 
+	uint32_t pulse_count, struct options_t *options)
+{
+	uint32_t index;
+	printf("ASCII-graph of received IR signal:\n");
+	for (index=0; index < pulse_count; index += 2){
+		_printburst(pulses[index]);
+		_printspace(pulses[index+1]);
+	}
+	printf("\n");
+	if ((*options).verbose) {
+		/*
+		 * full dump of new IR signal:
+		 */
+		printf("Carrier clock            : %u Hz\n", carrier_clock);
+		printf("Total pulse/space pairs  : %u\n", pulse_count/2);
+		for (index=0; index < pulse_count; index += 2){
+			printf("\tP:%6u\tS:%6u\n", pulses[index],
+				pulses[index+1]);
+		}
+	}
+}
+
+int _read_pronto_code(uint32_t *carrier_clock, 
+	uint32_t **pulses, uint32_t *pulse_count)
+{
+	struct pronto_hex code;
+	char pronto_string[1000];
+	int err;
+
+	/*  read code from stdin: */
+	printf("Enter Pronto code:\n");
+	if (fgets(pronto_string, 1000, stdin) == NULL) {
+		err = IRR_ERROR_BAD_CODE;
+	}
+
+	err = sscanf_pronto_hex(pronto_string, &code);
+
+	if (err == 0) {
+		/*
+		 * If code has a repeat part, include it 2 times, so the
+		 * Logitech database might recognize it as repeat code:
+		 */
+		err = pronto_to_pulses(code, carrier_clock, 2,
+			pulse_count, pulses);
+	}
+	return err;
+}
+
+char _get_cmd(char *allowed) {
+	char result;
+	uint32_t this;
+	while ( 1 ) {
+		result = getchar();
+		getchar(); /* consume newline */
+		for (this = 0; this < strlen(allowed); this++) {
+			if (allowed[this] == result) {
+				return result;
+			}
+		}
+		printf("[%s] ?", allowed);
+	}
+}	
+
+int _learn_ir_commands(uint8_t *data, uint32_t size, struct options_t *options)
+{
+	int err = 0;
+	uint32_t carrier_clock = 0;
+	uint32_t *pulses = NULL;
+	uint32_t pulse_count = 0;
+	int next_index = 1;
+	char *key_name = NULL;
+	char *post_string = NULL;
+	char user_cmd;
+
+	while (1) {
+		key_name = get_key_name(data, size, next_index);
+		if (key_name == NULL) {
+			printf("\nNo more keys : [P]revious, [Q]uit ?");
+			user_cmd = _get_cmd("PpQq");
+		} else {
+			printf("\nKey name : <%s> : \n", key_name);
+			printf("\t[L]earn, Pronto [H]ex code, [N]ext, [P]revious, [Q]uit ?");
+			user_cmd = _get_cmd("LlHhNnPpQq");
+		}				
+		next_index++;
+		err = 1; /* have no code yet */
+		switch (user_cmd) {
+			case 'L':
+			case 'l': /* learn from remote: */
+				printf("press <return>, then corresponding ");
+				printf("key on original remote within 4 sec:\n");
+				getchar();
+				err = learn_from_remote(&carrier_clock, &pulses,
+					&pulse_count);
+				if (err != 0) {
+					printf("???\tLearning failed - try again!\n");
+					next_index--;
+				}
+				break;
+			case 'H':
+			case 'h': /* requested to get Pronto (from stdin): */
+				err = _read_pronto_code(&carrier_clock, &pulses,
+					&pulse_count);
+				if (err != 0) {
+					printf("???\tBad hex code - try again!\n");
+					next_index--;
+				}
+				break;
+			case 'P':
+			case 'p':
+				if (next_index > 2) {
+					next_index -= 2;
+				} else {
+					printf("First key already reached!\n");
+					next_index = 1;
+				}
+				break;
+			default:
+				break;
+		}				
+		if ( err == 0 ) {   /* have new IR code: */
+			_dump_new_code(carrier_clock, pulses, pulse_count, options);
+			post_string = encode_for_posting(carrier_clock, pulses,
+					pulse_count);
+			if ( post_string != NULL ) {
+				if ((*options).verbose) {
+					printf("%s\n\n", post_string );
+				}
+				printf("\t[U]pload new code, [R]etry same key, [N]ext key, [Q]uit ?");
+				user_cmd = _get_cmd("UuRrNnQq");
+				switch (user_cmd) {
+					case 'U':
+					case 'u':
+						if (!(*options).noweb) {
+							err = post_new_code(data, size, 
+								key_name, post_string);
+						}
+						break;
+					case 'R':
+					case 'r':
+						next_index--;
+						break;
+					default:
+						break;
+				}
+			} else {
+				printf("???\tFailed to convert - bad code? try again!\n");
+				next_index--;
+			}
+		}
+		if (user_cmd == 'Q' || user_cmd == 'q') {
+			break;
+		}
+	}
+	return 0; /* considering always kind of success */
+}
+
 /*
  * Start helper functions
  */
@@ -1032,7 +1216,7 @@ int main(int argc, char *argv[])
 			break;
 
 		case MODE_LEARN_IR:
-			err = learn_ir_commands(data, size, !options.noweb);
+			err = _learn_ir_commands(data, size, &options);
 			break;
 
 		case MODE_GET_TIME:
*** concordance/concordance.c	2008-06-15 12:42:05.000000000 +0200
--- concordance.nopronto/concordance.c	2008-06-15 22:20:09.000000000 +0200
***************
*** 27,33 ****
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
- #include <libIRremotes.h>
  
  #ifdef WIN32
  /* Windows includes*/
--- 27,32 ----
*************** void _dump_new_code(uint32_t carrier_clo
*** 189,220 ****
  	}
  }
  
- int _read_pronto_code(uint32_t *carrier_clock, 
- 	uint32_t **pulses, uint32_t *pulse_count)
- {
- 	struct pronto_hex code;
- 	char pronto_string[1000];
- 	int err;
- 
- 	/*  read code from stdin: */
- 	printf("Enter Pronto code:\n");
- 	if (fgets(pronto_string, 1000, stdin) == NULL) {
- 		err = IRR_ERROR_BAD_CODE;
- 	}
- 
- 	err = sscanf_pronto_hex(pronto_string, &code);
- 
- 	if (err == 0) {
- 		/*
- 		 * If code has a repeat part, include it 2 times, so the
- 		 * Logitech database might recognize it as repeat code:
- 		 */
- 		err = pronto_to_pulses(code, carrier_clock, 2,
- 			pulse_count, pulses);
- 	}
- 	return err;
- }
- 
  char _get_cmd(char *allowed) {
  	char result;
  	uint32_t this;
--- 188,193 ----
*************** int _learn_ir_commands(uint8_t *data, ui
*** 248,255 ****
  			user_cmd = _get_cmd("PpQq");
  		} else {
  			printf("\nKey name : <%s> : \n", key_name);
! 			printf("\t[L]earn, Pronto [H]ex code, [N]ext, [P]revious, [Q]uit ?");
! 			user_cmd = _get_cmd("LlHhNnPpQq");
  		}				
  		next_index++;
  		err = 1; /* have no code yet */
--- 221,228 ----
  			user_cmd = _get_cmd("PpQq");
  		} else {
  			printf("\nKey name : <%s> : \n", key_name);
! 			printf("\t[L]earn, [N]ext, [P]revious, [Q]uit ?");
! 			user_cmd = _get_cmd("LlNnPpQq");
  		}				
  		next_index++;
  		err = 1; /* have no code yet */
*************** int _learn_ir_commands(uint8_t *data, ui
*** 266,280 ****
  					next_index--;
  				}
  				break;
- 			case 'H':
- 			case 'h': /* requested to get Pronto (from stdin): */
- 				err = _read_pronto_code(&carrier_clock, &pulses,
- 					&pulse_count);
- 				if (err != 0) {
- 					printf("???\tBad hex code - try again!\n");
- 					next_index--;
- 				}
- 				break;
  			case 'P':
  			case 'p':
  				if (next_index > 2) {
--- 239,244 ----
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to