(see also message:
[patch 0/2] Change of libconcord API for IR codes learning - Build 20080628)

Note on concordance UI:
=======================
To make use of the changed IR learning API of libconcord, after this patch 
concordance will:
- show the number of keys to be learned
- prompt for the next key to learn, asking for user response whether to:
- - navigate through the list of key names (Next/Previous),
- - Learn an IR code for this key or
- - Quit
- after an IR code has been received, display an ASCII-rendering of the
  received code. Even though not very accurate, it could give some indication
  whether something might have gone wrong
- prompt the user after learning whether the received code shall be
- - Uploaded (posted) to Logitech,
- - Discarded, proceeding with the next key or
- - Learned again.

Patch installation:
===================
This patch should be applied to concordance CVS release 0.20. It reqiures 
libconcord built and installed with the pervious patch [patch 1/2] applied.

Apply patch via:
  cd <wherever>/concordance
  patch -p1 < concordance-IRLearn-20080628.patch

Detailed comments on changes:
=============================

Index: concordance/concordance.1
===================================================================
+Learn IR from other remotes. Use <filename>. Supports also files with 
multiple key names, 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 or to learn the IR code from the original remote.

> added remark about changed IR learning

Index: concordance.c
===================================================================
+#define strdup _strdup
 
> fixed VC++ warning

+void _dump_new_code(uint32_t carrier_clock, uint32_t *ir_signal, 
+       uint32_t ir_signal_length, struct options_t *options)

> 'plot' received IR code as ASCII-art to identify bad IR signals

+int _learn_ir_commands(uint8_t *data, uint32_t size, struct options_t 
*options)

> adapt to changed libconcord API; added code to navigate through list
> with multiple keys to be learned and to accept/reject learned IR signal.
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	28 Jun 2008 12:56:35 -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>. Supports also files with multiple key names, 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 or to learn the IR code from the original remote.
 .TP
 .B \-r, \-\-reset
 Reset (power-cycle) the remote control
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	28 Jun 2008 12:56:35 -0000
@@ -37,6 +37,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 +141,175 @@ 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 *ir_signal, 
+	uint32_t ir_signal_length, struct options_t *options)
+{
+	uint32_t index;
+	printf("ASCII-graph of received IR signal:\n");
+	for (index=0; index < ir_signal_length; index += 2){
+		_printburst(ir_signal[index]);
+		_printspace(ir_signal[index+1]);
+	}
+	printf("\n");
+	if ((*options).verbose) {
+		printf("Carrier clock          : %u Hz\n", carrier_clock);
+		printf("Total mark/space pairs : %u\n", ir_signal_length/2);
+#ifdef _DEBUG
+		/*
+		 * full dump of new IR signal:
+		 */
+		for (index=0; index < ir_signal_length; index += 2){
+			printf("\tP:%6u\tS:%6u\n", ir_signal[index],
+				ir_signal[index+1]);
+		}
+#endif
+	}
+}
+
+char _get_cmd(char *allowed, char def) {
+	char result;
+	uint32_t this;
+	while ( 1 ) {
+		result = getchar();
+		if (result == '\n') {
+			return def;
+		}
+		getchar(); /* consume newline */
+		for (this = 0; this < strlen(allowed); this++) {
+			if (allowed[this] == result) {
+				return result;
+			}
+		}
+		printf("[%s] (%c)?", allowed, def);
+	}
+}	
+
+int _learn_ir_commands(uint8_t *data, uint32_t size, struct options_t *options)
+{
+	int err = 0;
+	uint32_t carrier_clock = 0;
+	uint32_t *ir_signal = NULL;
+	uint32_t ir_signal_length = 0;
+	uint32_t index = 0;
+	char **key_names;
+	uint32_t key_names_length = 0;
+	char *post_string = NULL;
+	char user_cmd;
+
+	err = get_key_names(data, size, &key_names, &key_names_length);
+	if ((err != 0) || (key_names_length == 0)) { return err; }
+	
+	printf("Received file contains %u key names to be learned.\n", key_names_length);
+	
+	while (1) {
+		if (index >= key_names_length) {
+			printf("\nNo more keys : [P]revious, [Q]uit (Q)?");
+			user_cmd = _get_cmd("PpQq", 'Q');
+		} else {
+			printf("\nKey name : <%s> : \n", key_names[index]);
+			printf("\t[L]earn, [N]ext, [P]revious, [Q]uit (L)?");
+			user_cmd = _get_cmd("LlNnPpQq", 'L');
+		}				
+		index++;
+		err = 1; /* have no code yet */
+		switch (user_cmd) {
+			case 'L':
+			case 'l': /* learn from remote: */
+				printf("press corresponding ");
+				printf("key on original remote within 4 sec:\n");
+				err = learn_from_remote(&carrier_clock, &ir_signal,
+					&ir_signal_length);
+				if (err != 0) {
+					printf("???\tLearning failed - try again!\n");
+					index--;
+				}
+				break;
+			case 'P':
+			case 'p':
+				if (index > 1) {
+					index -= 2;
+				} else {
+					printf("First key already reached!\n");
+					index = 0;
+				}
+				break;
+			default:
+				break;
+		}				
+		if ( err == 0 ) {   /* have new IR code: */
+			_dump_new_code(carrier_clock, ir_signal, ir_signal_length, options);
+			err = encode_for_posting(carrier_clock, ir_signal,
+					ir_signal_length, &post_string);
+			
+			if ( err == 0 ) {
+#ifdef _DEBUG				
+				if ((*options).verbose) {
+					printf("%s\n\n", post_string );
+				}
+#endif
+				if (!(*options).noweb) {
+					printf("\t[U]pload new code, [R]etry same key, [N]ext key, [Q]uit (U)?");
+					user_cmd = _get_cmd("UuRrNnQq", 'U');
+				} else {
+					printf("\t[R]etry same key, [N]ext key, [Q]uit (N)?");
+					user_cmd = _get_cmd("RrNnQq", 'N');
+				}
+				switch (user_cmd) {
+					case 'U':
+					case 'u':
+						err = post_new_code(data, size, 
+							key_names[index], post_string);
+						if ( err == 0 ) {
+							printf("..upload successful!\n");
+						}
+						break;
+					case 'R':
+					case 'r':
+						index--;
+						break;
+					default:
+						break;
+				}
+				delete_encoded_signal(post_string);    /* done, free memory */
+			} else {
+				printf("???\tFailed to convert - bad code? try again!\n");
+				index--;
+			}
+			delete_ir_signal(ir_signal);    /* done, free memory */
+		}
+				
+		if (user_cmd == 'Q' || user_cmd == 'q') {
+			break;
+		}
+	}
+	delete_key_names(key_names, key_names_length); /* done, free memory */
+	return 0; /* considering always kind of success */
+}
+
 /*
  * Start helper functions
  */
@@ -1032,7 +1202,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:
-------------------------------------------------------------------------
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