Page 1 of 1

A main routine for DecodeIR

Posted: Sun Mar 14, 2010 2:47 pm
by Barf
On fixing the Nokia12 bug in DecodeIR, I wrote a main routine, which possibly can be of use for other people fumbling around with DecodeIR. So I publish it here as a diff to the 2.40 sources. To compile define the preprocessor symbol MAIN and leave out the options for generating a shared object. Thus a command line program will be produced, that takes a signal in Pronto format as its argument. This is the Makefile I used:

Code: Select all

NAME=DecodeIR
#INCLUDES=-I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -Icom/hifiremote/decodeir
INCLUDES=-Icom/hifiremote/decodeir

all:    lib$(NAME).so

clean:
        rm lib$(NAME).so

lib$(NAME).so:  $(NAME).cpp
        g++ -fPIC -shared -o $@ $(INCLUDES) $?

prog:   $(NAME).cpp
        g++ -DMAIN -o $@ $(INCLUDES) $<

install:
        install lib$(NAME).so /usr/local/lib

# Nokia12 1 123
test: prog
        ./prog 0000 0073 0000 0008 000f 000a 0006 000a 0006 0010 0006 0010 0006 001c 0006 0016 0006 001c 0006 0fd2
I have only tested with Linux, however there should be absolutely nothing system dependent, so it should work also on other systems.

Code: Select all

*** DecodeIR.cpp.orig   Sun Mar 14 18:29:52 2010
--- DecodeIR.cpp        Sun Mar 14 21:34:18 2010
***************
*** 17,22 ****
--- 17,25 ----
  #include "JNIUtil.h"
  #endif
  
+ #ifdef MAIN
+ #include <iostream>
+ #endif
  
  static char const version_cstr[]="2.40";      // Version 2.40 by GD 2010
  
***************
*** 5570,5572 ****
--- 5573,5635 ----
          && JNU_SetString(env, obj, "miscMessage", TsMisc)
          && JNU_SetString(env, obj, "errorMessage", TsError);
  }
+ 
+ #ifdef MAIN
+ #ifndef linux
+ #error this has not been tested outside of Linux. Feel free to do so, however.
+ #endif
+ int main(int argc, char* argv[])
+ {
+   unsigned int i = 1;
+   int type;
+   sscanf(argv[i++], "%x", &type);
+   if (type != 0)
+   {
+     std::cerr << "Can only handle type 0000\n";
+     exit(1);
+   }
+   int fcode;
+   sscanf(argv[i++], "%x", &fcode);
+   int frequency = (int) (1000000.0/((double)fcode * 0.241246));
+   int intro_length, rep_length;
+   sscanf(argv[i++], "%x", &intro_length);
+   sscanf(argv[i++], "%x", &rep_length);
+ 
+   int *data = new int[2*(intro_length+rep_length)];
+   for (int j = 0; j < 2*(intro_length+rep_length); j++)
+   {
+     int ncycles;
+     sscanf(argv[i++], "%x", &ncycles);
+     data[j] = (int)(1000000.0/frequency*ncycles);
+   }
+   unsigned int decodeir_context[2] = { 0, 0};
+   char protocol[255] = "";
+   int device = -1;
+   int subdevice = -1;
+   int obc = -1;
+   int hex[4] = { -1, -1, -1, -1};
+   char misc_message[255] = "";
+   char error_message[255] = "";
+ 
+   do
+   {
+     DecodeIR(decodeir_context, data, frequency, intro_length, rep_length,
+            protocol, &device, &subdevice, &obc, hex, misc_message,
+            error_message);
+     
+     if (protocol[0] != '\0')
+       std::cout 
+       << "protocol=" << protocol
+       << " device=" << device 
+       << " subdevice=" << subdevice
+       << " obc=" << obc
+       << " hex0=" << hex[0]
+       << " hex1=" << hex[1]
+       << " hex2=" << hex[2]
+       << " hex3=" << hex[3]
+       << " misc=" << misc_message
+       << " error=" << error_message << "\n";
+   }
+   while (protocol[0] != '\0');
+ }
+ #endif

Posted: Mon May 03, 2010 8:33 am
by tld
This looks like useful tool. I'm currently calling decodeIR from MATLAB and it seems to work fine for simple protocols like Sony20, Panasonic, RC5, etc. For these examples, I'm setting intro_length (TiSingleBurstCount) to zero, TiDevice to -1, and only calling decodeIR once.

I'm confused about how more complicated protocols are handled, e.g. those that require TiSingleBurstCount to be non-zero and, perhaps, TiDevice to be less than -1 (= -ExtraBurstCount).

If someone could post one or two of the more complicated pulses trains and the proper calls to decodeIR, I think I might be able to figure some of this out.

Also, I'm curious how programs that use decodeIR determine how to divide pulse trains into TiSingleBurstCount's, TiRepeatBurstCount's, ExtraBurstCount's. Do they look for large gaps between bursts and divide it up that way? And also, why does decodeIR sometimes need to be called more than once?

Thanks,
Tom

Posted: Mon May 03, 2010 8:58 am
by johnsfine
tld wrote:Also, I'm curious how programs that use decodeIR determine how to divide pulse trains into TiSingleBurstCount's, TiRepeatBurstCount's, ExtraBurstCount's.
They look for a large approximately repeating chunk in the raw data. The approximately may be hard to decide. The large isn't absolutely required. So it may be a tricky process.

Then the caller is expected to remove all but one copy of the repeating section and to set up the counts so DecodeIR can tell which section is repeating.

In my last version of DecodeIR, that job was entirely external to DecodeIR. IIUC, now it does some of that work itself when it sees that the caller hasn't done it. But I haven't had time to look at and understand that code.
why does decodeIR sometimes need to be called more than once?
1) Many IR protocols are terribly non robust, meaning there is a significant chance that a chunk from an unrelated IR signal will decode in one of those protocols. DecodeIR might find a spurious decode before finding the correct one. Calling it more than once gives the user all the decodes, so the user can evaluate them in context and decide which are spurious. That design assumes the decodes pass next to a user (rather than another layer of automation). For another layer of automation, deciding which decodes are spurious is harder.

2) Some IR signals have multiple parts and too much data to return reasonably in DecodeIR's output format, so DecodeIr must be called multiple times in order to return multiple decodes adding up to one signal.

3) An IR signals might actually be a macro, even a macro of commands to multiple devices. So the multiple decodes you get from multiple calls might really represent multiple IR signals that were captured together.

Posted: Mon May 03, 2010 11:24 am
by mathdon
Barf wrote:On fixing the Nokia12 bug in DecodeIR
I've only just come across this statement. Can you point me to a description of the required fix?
____________
Graham

Posted: Mon May 03, 2010 12:07 pm
by Barf
4 sure.

BTW, "porting" the main routine (which happens to be the topic of the thread ... :wink: ) to WIndows should only take a few minutes for anyone familiar with Windows programming; I might even do it myself if there is interest.

Posted: Mon May 03, 2010 3:28 pm
by mathdon
Thanks, Barf. Sorry I missed it. I'll see that this gets into v2.41, which will simply be v2.40 with a few additions and bug fixes,
____________
Graham