MIDI-OX User Forum (http://www.midiox.com/cgi-bin/yabb/YaBB.pl)
MIDI-OX >> Mapping Questions >> Incomplete NRPN - how to treat it?
(Message started by: Dave_Windsor on Jun 19th, 2002, 5:35am)

Title: Incomplete NRPN - how to treat it?
Post by Dave_Windsor on Jun 19th, 2002, 5:35am
Hi Jamie + others,

I'm working on a plugin for MIDI-Ox, and am wondering how to treat incomplete NRPN data and possibly asynchronous NRPN data.

My PhatBoy device sends incomplete NRPN data in Mode I:



TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT              
   264402   1    178    99     1    3   --  CC: NRPN MSB          
   264403   1    178    98    33    3   --  CC: NRPN LSB          
   264404   1    178     6    81    3   --  CC: Data Entry MSB  



And complete NRPN data in Mode II:



   109420   1    178    99   127    3   --  CC: NRPN MSB          
   109421   1    178    98    21    3   --  CC: NRPN LSB        
   109422   1    178     6    64    3   --  CC: Data Entry MSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  


When the data is sent, I don't know what Mode the PhatBoy is in.

What do you suggest for determining a complete NRPN?
I thought of: hold 4 values in a buffer when a ctrl 99 message arrives, but continue if: 1) the fourth message is not ctrl 38 OR 2) in the last 2 ms no fourth message has arrived.

But is this complete?

Can NRPN data come in asynchroneously? i.e. (the previous two examples mixed together):



TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT              
   264402   1    178    99     1    3   --  CC: NRPN MSB          
   109420   1    178    99   127    3   --  CC: NRPN MSB          
   264403   1    178    98    33    3   --  CC: NRPN LSB          
   109421   1    178    98    21    3   --  CC: NRPN LSB          
   264404   1    178     6    81    3   --  CC: Data Entry MSB  
   109422   1    178     6    64    3   --  CC: Data Entry MSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  


?

Probably not, it does not seem to make sense.
But maybe this one does (different channels):



TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT              
   264402   1    178    99     1    3   --  CC: NRPN MSB          
   109420   1    176    99   127    1   --  CC: NRPN MSB          
   264403   1    178    98    33    3   --  CC: NRPN LSB          
   109421   1    176    98    21    1   --  CC: NRPN LSB          
   264404   1    178     6    81    3   --  CC: Data Entry MSB  
   109422   1    176     6    64    1   --  CC: Data Entry MSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  


Is this possible incoming data?
Additional question: do midi merge devices always wait for complete NRPN?

---------------------------------------------------------

An what about NRPN out-of order like:



   109420   1    178    99   127    3   --  CC: NRPN MSB          
   109422   1    178     6    64    3   --  CC: Data Entry MSB    
   109421   1    178    98    21    3   --  CC: NRPN LSB        
   109423   1    178    38    70    3   --  CC: Data Entry LSB  


Is this valid incoming MIDI NRPN data?

Or NRPN mixed with other (non-nrpn) controllers like:



TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT              
   264402   1    178    99     1    3   --  CC: NRPN MSB          
   264403   1    178    98    33    3   --  CC: NRPN LSB          
    12323   1    176    71    81    1   --  CC: Harmonic Content  
   264404   1    178     6    81    3   --  CC: Data Entry MSB  



Any help appreciated, cheers Dave

Title: Re: Incomplete NRPN - how to treat it?
Post by Jamie OConnell on Jun 19th, 2002, 6:59pm
There are actually a couple of different issues at play here, and NRPN's and RPN's are one of the most confusing and ambiguous of the MIDI controllers.  Still, they are pretty useful.

The NRPN itself is defined by CC 99 followed by CC 98.  Once you have received each of these on a channel you know what the NRPN number is: the combined 14 bit value resulting from the MSB and LSB.  The MIDI spec. recommends that they both should be issued to change the parameter number, but it also says that a "receiver should be able to respond accordingly if the transmitter sends only an LSB or MSB to change the parameter number".

After you know the NRPN or RPN parameter number, the value can come from several sources: 1) The combined Data Entry CC's: 6 and 38; 2) The lone Data Entry MSB: CC 6; 3) A Data Increment CC 96; or 4) a Data Decrement CC 97.  [Obviously for Data Increment/Decrement to work, a CC 6 and/or 38 must have been previously issued].   There is no requirement for gear to re-issue the parameter number while changing Data Entry/Increment/Decrement.  So you could receive a CC 6 several seconds (or even minutes) after the last NRPN or RPN parameter number was set.  Any Data Entry value should be applied to the last NRPN (or RPN!) received.  Deciding to act upon receiving the Data Entry MSB, or waiting until you get a Data Entry LSB is a difficult choice, with no absolute right answer.  You could wait a (short) while to see if the LSB shows up, or you could act immediately and revise your reaction if/when the LSB does show up.

What I have done when writing MIDI software is to keep track of what has been received for each channel with regard to NRPN, RPN, and Data Entry.  I keep a little channel array of structures around.  Each structure contains NRPN MSB, NRPN LSB, RPN MSB, RPN LSB, flag whether the last received was RPN or NRPN, Data Entry MSB, Data Entry LSB.  And flags or initial values to determine what has been received.  I haven't really done much to support Data Increment/Decrement, but they would be applied to the most recent Data Entry if I did.

Specific comments on your examples in following message (too long)...  :)

Title: Re: Incomplete NRPN - how to treat it?
Post by Jamie OConnell on Jun 19th, 2002, 6:59pm
Specific comments on your examples:


Quote:
TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT      
   264402   1    178    99     1    3   --  CC: NRPN MSB      
   264403   1    178    98    33    3   --  CC: NRPN LSB      
   264404   1    178     6    81    3   --  CC: Data Entry MSB  


Here is the classic difficult decision I spoke of,  This is a perfectly legal NRPN number and value.  But so is the following 4 message NRPN:

Quote:
109420   1    178    99   127    3   --  CC: NRPN MSB      
   109421   1    178    98    21    3   --  CC: NRPN LSB    
   109422   1    178     6    64    3   --  CC: Data Entry MSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  




Quote:

TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT      
   264402   1    178    99     1    3   --  CC: NRPN MSB      
   109420   1    178    99   127    3   --  CC: NRPN MSB      
   264403   1    178    98    33    3   --  CC: NRPN LSB      
   109421   1    178    98    21    3   --  CC: NRPN LSB      
   264404   1    178     6    81    3   --  CC: Data Entry MSB    
   109422   1    178     6    64    3   --  CC: Data Entry MSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  

The above is perfectly legal, but as you point out, not very practical.  By the end of this stream you'd have NRPN parameter of MSB:127, LSB:21 and value of MSB:64, LSB: 70.


Quote:
TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT      
   264402   1    178    99     1    3   --  CC: NRPN MSB      
   109420   1    176    99   127    1   --  CC: NRPN MSB      
   264403   1    178    98    33    3   --  CC: NRPN LSB      
   109421   1    176    98    21    1   --  CC: NRPN LSB      
   264404   1    178     6    81    3   --  CC: Data Entry MSB    
   109422   1    176     6    64    1   --  CC: Data Entry MSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  

The above type of stream is typical, although based on what you received, you might expect another CC 38 on channel 1 soon.


Quote:
109420   1    178    99   127    3   --  CC: NRPN MSB      
   109422   1    178     6    64    3   --  CC: Data Entry MSB    
   109421   1    178    98    21    3   --  CC: NRPN LSB    
   109423   1    178    38    70    3   --  CC: Data Entry LSB  


This one is questionable. Although the param number is established (MSB:127, LSB:21), you might discard the intervening CC 6 (and following CC 38 ), and wait for at least another CC 6 before doing anything.


Quote:
TIMESTAMP PORT STATUS DATA1 DATA2 CHAN NOTE EVENT      
   264402   1    178    99     1    3   --  CC: NRPN MSB      
   264403   1    178    98    33    3   --  CC: NRPN LSB      
    12323   1    176    71    81    1   --  CC: Harmonic Content  
   264404   1    178     6    81    3   --  CC: Data Entry MSB  


This is perfectly legal and to be expected, although the decision to act on the CC 6 or wait for a CC 38 is subjective.

Clear as mud?  ;)



Title: Re: Incomplete NRPN - how to treat it?
Post by Dave_Windsor on Jun 20th, 2002, 12:37am
Wow Jamie, thanks a bundle!

All perfectly clear, especially the struct you described! I'll probably copy that one-on-one :)

There remains one problem though - the 'wait for complete NRPN' issue. I assume you wait for MSB + LSB data entry? In no particular order? *

* - You mention "1) The combined Data Entry CC's: 6 and 38; 2) The lone Data Entry MSB: CC 6;", so the specs prescribe order of 6 and 38 is always in that order? Why didn't they make it "1) 38;6 and 2) 6" then... ?! Then I would have no trouble at all... '6' = end of message. Alas.

I still have to determine immediately if the nrpn is finished, even if it's incomplete. I want to respond to data of PhatBoy mode I/mode II the same way.

So I still have to hold an incomplete nrpn data entry (one MSB data entry or one LSB data entry) in a buffer for say 2 ms, I think. Agree?

Thanks again, cheers Dave

Title: Re: Incomplete NRPN - how to treat it?
Post by Jamie OConnell on Jun 20th, 2002, 2:22am

Quote:
There remains one problem though - the 'wait for complete NRPN' issue. I assume you wait for MSB + LSB data entry? In no particular order? *

* - You mention "1) The combined Data Entry CC's: 6 and 38; 2) The lone Data Entry MSB: CC 6;", so the specs prescribe order of 6 and 38 is always in that order? Why didn't they make it "1) 38;6 and 2) 6" then... ?! Then I would have no trouble at all... '6' = end of message. Alas.


The spec. says about Continous Controllers (of which Data Entry MSB and LSB are members), "If only seven bits of resolution are needed for any particular controllers, only the MSB is sent.  It is not necessary to send the LSB.  If more resolution is needed, then both are sent, first the MSB, then the LSB.  If only the LSB has changed in value, the LSB may be sent without re-sending the MSB".  So you can see that you need to expect all sorts of different combinations.

For MIDI-OX mapping I make the user tell MIDI-OX what to expect:  Full Data Entry (6, 38) or just MSB (6).  In fact, when a CC 6 is received, I always clear out any received 38 value (reset to 0), so I definitely expect them in the defined order (MSB, LSB).

Thanks for the encouragment, but that struct description is just from memory: I wouldn't necessarily recommend using it for a project.  For MIDI-OX I wrote a C++ NRPN listener class that takes care of the details and tracks messages.  I could probably send that if you're interested.

Title: Re: Incomplete NRPN - how to treat it?
Post by Dave_Windsor on Jun 20th, 2002, 2:30am
Thanks for your quick reply again :)

All is clear now, cheers Dave



MIDI-OX User Forum » Powered by YaBB 1 Gold - SP 1.3.1!
YaBB © 2000-2003. All Rights Reserved.