DecodeIR: Where do we go from here?

Discussion forum for JP1 software tools currently in use, or being developed, such as IR, KM, RemoteMaster, and other misc apps/tools.

Moderator: Moderators

mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

DecodeIR.dll v2.38 Beta3

There is now a new DecodeIR version for testing, v2.38 Beta3. I have not posted it separately, but it is included in the package for IR 8.01 RC6. It acts with IRWidget/IRScope as described in my previous message. Betas 1 and 2 were only issued for private testing.

It should be less prone to give spurious decodes. Liz will see that this file of hers of JVC learns, which gave two decodes (JVC and JVC{2}) for each signal with IR 8.01 RC4 and three decodes (JVC, JVC{2} and Gap-??-??-??) with RC5 now only gives the one decode, JVC, for each signal. JVC{2} will still be reported when that really is the signal, but it will not appear as a secondary decode of a full JVC signal. The Dish_Network protocol is described in DecodeIR.html as not robust and prone to spurious decodes. With IRScope I was getting a lot of Gap-??-??-?? decodes with that, in addition to a valid Dish_Network decode. I can now not provoke it to give any of these spurious generic Gap decodes. Again, generic Gap decodes will appear as before for genuinely undecodable signals that fit the generic Gap pattern but they are much less likely to occur as noise on top of valid decodes.

Please try it and report whether you think it is, or is not, an improvement.
_____________
Graham
gfb107
Expert
Posts: 3411
Joined: Sun Aug 03, 2003 7:18 pm
Location: Cary, NC
Contact:

Post by gfb107 »

When I try DecodeIR.dll v2.38 Beta3 with RMIR v1.97, loading Liz's JVC learn .ir file, I see spurious Gap decodes along with the JVC and JVC{2} decodes.

At some point when you feel DecodeIR.dll v2.38 is ready, I'll need the source so I can build Linux versions.
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

Greg, are you sure you are using v2.38 Beta3? I haven't installed RMIR v1.97 yet, I'm still on 1.95, but with that I get only two decodes, JVC (with "2 frames" in the Misc column, which is exactly what should happen) and the generic Gap decode.

I know why you get the Gap when IR.exe doesn't. I think you pass the Once, Repeat and Extra bursts to DecodeIR as a single stream, with the TiSingleBurstCount = total number of bursts and TiRepeatBurstCount = 0. DecodeIR then cannot distinguish which are the Extra frames. The Gap data really IS in the learned signal - there is a final Extra frame that seems to have been systematically corrupted by the learning process. It is also possible, of course (but that is not the case here) for the end of a signal to be corrupted for other reasons. So if DecodeIR sees a generic (i.e unrecognised) decode in the Extra bursts when there is a well-recognised signal in the Once and Repeat bursts, it rejects the generic decode as spurious. It can't do that in RMIR as it doesn't know which are the Extra bursts.

I think you will find you see that Gap decode with v2.36 and earlier, as IR.exe has always worked differently. Before IR 8.01 RC5 it just didn't pass the extra bursts on at all, so didn't get this Gap decode. As ignoring the Extra bursts completely can lose real info, RC5 does pass them, hence their appearance there. If you load Liz's file into a remote and send the learned signals at IR Widget, you again get the Gap, as that signal really is there.

Incidentally, what Decode IR does is create a string of the Once bursts once, followed by 2 copies of the Repeat bursts (it always did that) but now also one copy of the Extra bursts. The use of 2 copies of the repeat, which it can only do if you tell it which are the repeat bursts, takes care of the occasions when the remote identifies the start of the repeat in the wrong place. I have one learned file in which IR recognises all the signals but RMIR leaves one blank, for just this reason.

As for the source, I intend to post the source in public access as John has done that with his versions. If you want the v2.38 Beta3 source, give me your e-mail address and I'll send it to you.
________________
Graham
gfb107
Expert
Posts: 3411
Joined: Sun Aug 03, 2003 7:18 pm
Location: Cary, NC
Contact:

Post by gfb107 »

Sorry I wasn't clear on what I'm seeing.

There's 2 decodes for every learned signal in Liz's file, a JVC decode and a Gap decode. There are no JVC{2} decodes.

I am definitely using v2.38 Beta3.


There is no difference between RMIR v1.95 and v1.97 as far as learned signals are concerned. So what you described is exactly what I see.

I'm not clear on what changes I should make to RMIR to provide DecodeIR with the data in the proper format that would allow DecodeIR to produce the same decodes when called from RMIR as it does when called from IR.
gfb107
Expert
Posts: 3411
Joined: Sun Aug 03, 2003 7:18 pm
Location: Cary, NC
Contact:

Post by gfb107 »

I don't need the source until it's ready for public release.
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

I hadn't looked at the Java caller parameters until now, as I don't know Java. I've just had a look and realized that there isn't a one-to-one correspondence between the Java parameters and the C++ ones. I think it may take a change to the Java interface even though it didn't need one to the C++ interface, only a change in IR.exe. I'll look into it in more detail and get back to you.
______________
Graham
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

A few short questions, Greg, to help me sort this out. I'm sorry if they are naive, but as I have said, I don't know Java. I'm just working on the fact that it looks rather like C++.

1) I believe you call a function setBursts(int[] b, int r) to pass the burst info. To get the behaviour you currently have, I think you must always call this with r=0. Is this true? If it is, is there a reason for this?

2) To distinguish between Once, Repeat and Extra bursts there would need to be a third argument, say setBursts(int[] b, int r, int e) where r and e are the number of repeat and extra bursts. My hunting on the web indicates that Java allows overloaded functions, so both forms could be defined. This would keep a new DecodeIR compatible with old RMIR versions. Is this true?

3) If that is not possible, so that compatibility could not be maintained, is that a serious obstacle for you, bearing in mind that DecodeIR is distributed with RM/RMIR?
________________
Graham
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

Greg, I've posted a test version DecodeIR.dll v2.38 Beta4 for you in a zip file that includes new versions of DecodeIRCaller.java, .class and .h. I've just used common sense and its similarity to C++ to revise the Java. It now has two versions (overloaded) of setBursts:

setBursts(int[] b, int r) and setBursts(int[] b, int r, int e).

There's not much point in retaining the 2-arg form but it would allow this revised class to be used with Java code written for the earlier form.

The only change you should need to make is to replace calls to the 2-arg form with calls to the 3-arg form and set r to the number of values (not number of bursts, which I said in previous message) in the repeat part of the signal, e to the number of values in the extra part.

DecodeIR v2.38 Beta4 should work with all existing applications (whether using C or Java API) and also with Java apps that include the revised caller class. However, Java apps compiled with the revised Java class will not work with earlier versions of DecodeIR.

That is the only incompatibility I am aware of, and I think it is unavoidable. Passing an extra argument to code that does not expect it seems to be an insuperable problem. I've managed it in the C API by using an existing argument whose value is a pointer to integer and was formerly only used as an output value. John's instructions were to set it to -1 before calling DecodeIR. It would be changed to a value >=0 on output. Since any negative input value serves equally well, I've used negative values to pass the new input argument.

Obviously I cannot test the new Java class, but it does compile and I've tested DecodeIR v2.38 Beta4 with RMIR 1.95 as well as with IR.exe. So the backward compatibility with RMIR seems to work.

Please try the revised Java class and report the outcome.
_____________
Graham
gfb107
Expert
Posts: 3411
Joined: Sun Aug 03, 2003 7:18 pm
Location: Cary, NC
Contact:

Post by gfb107 »

Graham,

Thanks for that. But how do I figure out the values for e?

I have some code that unpacks and does some parsing of the learned signal before calling DecodeIR. I think John wrote it, or maybe I just ported it from the IR source. I really don't understand it. I see nothing in that code that helps me figure out what e should be.

http://controlremote.cvs.sourceforge.ne ... iew=markup

I do use the calculated repeat value as r when calling DecodeIR, so I don't think it should always be 0. I have no idea how to compute e.
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

Sorry, I assumed you knew since RMIR had to unpack the code. I don't know, either, but I'll look at the code in IR.exe and at what you've given me a link to and get back to you on it.
___________
Graham
johnsfine
Site Admin
Posts: 4766
Joined: Sun Aug 10, 2003 5:00 pm
Location: Bedford, MA
Contact:

Post by johnsfine »

I've forgotten some important details, but I think I should tell you what I remember before you invest time in a wrong path.

The UEI format for learned signals has the data in one, two or three chunks. There are two different reasons for having three chunks, which other people who have worked on this have ignored, creating a mess.

There was the case that someone here understood first, but it is actually less common:
A one time initial part, followed by the repeating middle part, followed by a one time end part. IIUC, Mathdon has changed DecodeIR to give you a way to communicate this unusual structure.
Signals with that structure are only moderately rare. But most of the time you fail to learn them preserving that structure. So learned signals correctly preserving that structure are very rare.

Much more common for three part learned signals is the situation where a one part signal is very long or the repeat pattern is not understood by the learning logic. Then you get three parts which are:
A one time initial part
A one time middle part
A one time end part
No repeat part.

IIRC, I made rmir able to understand those three part signals and pass them correctly to DecodeIr as one long one time part and no repeat part. If that is still working, please don't break it now in attempts to get the less common case working.
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

Thanks, Greg, for the link to your Java "UnpackLearned" code which I understand, from his comments, that John wrote. I understand what this is doing. Thanks also, John, for your comments on it. I promise that I will not break it, but I think there is an error in it. It seems to presume that if there is a repeat part then it is the last one. In the signals that RMIR passes to it, this is not always the case.

Greg's original comment stems from the data that Liz posted. Each signal in that has 3 parts and the middle one has a repeat flag. Your code tests the last part for a repeat flag, does not find it, and so says "no repeat". That's why I presumed, in my post for Greg, that the repeat value was always set at 0 since in this case it was, yet I knew there really was a repeat section.

I will provide Greg tomorrow (UK time) with an amendment to your code that I believe handles all cases correctly, and which in particular does not break your handling of three non-repeating parts. If Greg will incorporate that into RMIR together with my revised DecodeIR Caller, we can give it a thorough test.
_______________
Graham
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

An addendum to the message above. I now realise that John's code doesn't have an error, it has a "deliberate mistake". With SetBursts not having the "e" (Extra count) parameter, there was no way that a 3-part signal with a repeating middle part could be passed to DecodeIR other than by treating the middle part as non-repeating and passing the whole thing as a one-part non-repeating signal.

The "C" interface also could not handle a true 3-part signal, but as it used different parameters it was handled by omitting the third part. So it "saw" the repeat but missed anything in the Extra bursts.
____________
Graham
mathdon
Expert
Posts: 4725
Joined: Tue Jul 22, 2008 8:53 am
Location: Cambridge, UK

Post by mathdon »

Greg, here's some replacement code and an explanation of how it works. Following that I have given a manual decode of the first learned signal in Liz's sample to illustrate the entire process.

At the end of the "for" loop that finishes at line 193 of your/John's code, the variables hold the following values:

durations[ ] = integer array containing the list of signal times, on and off times alternating, starting with the first on-time.
total = integer number of signal times in durations[ ].
partNdx = integer number of parts into which the learned data is divided (1, 2 or 3).
parts[ ] = integer array of (partNdx) elements giving the number of signal times in each part, so which must add up to (total).
partTypes[ ] = boolean array of (partNdx) elements giving the repeat flags of each part.

The IR Engine sends in turn the bursts in each part. Those that have repeat flag = 0 (false) it sends once. Those that have repeat flag = 1 (true) it sends continuously while the key is held down. When the key is released it sends the remaining parts (only once, since even if the repeat flag is set then the key is no longer held).

I don't know if there are ever more than three parts in a valid signal. I've never heard of it, John's message implies that there are not and the code in IR.exe gives an error message if there are. But your/John's code allows it, as does the IR engine, so I suggest we retain that generality in any change to the code. This means that in SetBursts(int[ ] b, int r, int e) we need r to be the value in parts[ ] for the first part that has its partTypes[ ] value True, and e to be the sum of the values in parts[ ] for all the parts after that one. Replacing lines 194-196 with the following code would achieve that:

Code: Select all

/*  Add a new variable at the top of the class definition */

/**  The extras */
public int extra;

/* Code to replace lines 194-196 */

repeat = 0;
extra = 0;
for  (int n=0; n<partNdx; ++n )
{
    if ( partTypes[n] && repeat == 0 )
    {
        repeat = parts[n];
    }
    else if ( repeat > 0 )
    {
        extra += parts[n];
    }
}
oneTime = total - repeat - extra;

/* The call to SetBursts is then SetBursts(durations, repeat, extra) */

It might help to have a specific example. The first learned signal in Liz's sample unpacks as follows:

Code: Select all

Manual decode of learned signal starting at $0400 in EEPROM area

Header of learned data is 3 bytes:

15          Keycode 15 = '1'
00          Learned signal, Device Type 0 = TV
30          $30 = 48 bytes of signal data follow.

Hex code passed to RMIR UnpackLearned starts here.

00 D1       1 cycle of carrier is $D1 = 209 cycles of 8MHz bus, so carrier freq = 8000/209 KHz = 38.277 KHz
04          4 sets of burst times (each 2-byte On time, 2-byte Off time in units of 2us) follow 
0105  2559  Burst 0 has 2x$0105 = 522us On,  2x$2559 = 19122us Off  
106E  083A  Burst 1 has 2x$106E = 8412us On, 2x$083A = 4212us Off  
0105  0316  Burst 2 has 2x$0105 = 522us On,  2x$0316 = 1580us Off
0105  0108  Burst 3 has 2x$0105 = 522us On,  2x$0108 = 528us Off

First part of signal data starts here

12          Repeat flag (bit 7) = 0.  $12 = 18 nibbles follow, each being the index of a burst
12          Burst 1 then Burst 2 = +8412 -4212 +522 -1580 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580 
23          Burst 2 then Burst 3 = +522  -1580 +522 -528 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580   
33          Burst 3 then Burst 3 = +522  -528  +522 -528 
33          Burst 3 then Burst 3 = +522  -528  +522 -528 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580   
30          Burst 3 then Burst 0 = +522  -528  +522 -19122 

Second part of signal data starts here

91          Repeat flag (bit 7) = 1, $11 = 17 nibbles follow
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580  
32          Burst 3 then Burst 2 = +522  -528  +522 -1580 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580 
23          Burst 2 then Burst 3 = +522  -1580 +522 -528 
33          Burst 3 then Burst 3 = +522  -528  +522 -528 
32          Burst 3 then Burst 2 = +522  -528  +522 -1580   
23          Burst 2 then Burst 3 = +522  -1580 +522 -528 
00          Burst 0 = +522 -19122 (no more, this is 17th)

Third part of signal data starts here

10          Repeat flag (bit 7) = 0, $10 = 16 nibbles follow
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580  
32          Burst 3 then Burst 2 = +522  -528  +522 -1580 
22          Burst 2 then Burst 2 = +522  -1580 +522 -1580 
23          Burst 2 then Burst 3 = +522  -1580 +522 -528 
33          Burst 3 then Burst 3 = +522  -528  +522 -528 
32          Burst 3 then Burst 2 = +522  -528  +522 -1580   
20          Burst 2 then Burst 0 = +522  -1580  +522 -19122 

Then at the point where I propose the replacement code to start:

durations[ ] will be the array of all the timings (all as positive values)
partNdx = 3
partTypes = [false, true, false]
parts = [36, 34, 32]
total = 102

giving

repeat = 34
extra = 32
oneTime = 102 - 34 - 32 = 36

I hope this satisfies John that I haven't broken anything. I also hope that it works!

Edit: I've edited my bit of code to add an "else" between the two "if" statements, as originally the second "if" would would be satisfied in the same iteration as the first, leading to a double counting of one signal part.
_________________
Graham
ElizabethD
Advanced Member
Posts: 2348
Joined: Mon Feb 09, 2004 12:07 pm

Post by ElizabethD »

mathdon wrote:DecodeIR.dll v2.38 Beta3
Please try it and report whether you think it is, or is not, an improvement.
Inspite of your thorough description it freaked me out to not see, in IR, JVC{2} :twisted:

In IR, just one JVC decode, Code Summary looks good, and Timing details show everything.
In the Widget, DecodeIR reports JVC 3 frames and a GAP.
Your earlier design showed that it will report JVC then JVC{2} 2 frames -- here: https://www.hifi-remote.com/forums/viewt ... 9936#p79936

IMO this is more than very nice. But the experts might think otherwise, of course. Oh, if Rob could only finish his challenging elementary school homeworks :roll: , we might get comments as to whether this way of decoding and displaying is useful to him, since that's what he does most of.
Liz
Tweeking 8910, HTPro/9811, C7-7800, 6131o, 6131n, AtlasOCAP-1056B01, RCA-RCRP05B and enjoying the ride :)
Post Reply