The preenfm2 expectes NRPN messages (not RPN).
Looking through the code solves the mystery of why Arpeggiator Pattern and Arpeggiator Direction aren't working. And it's not a good result. :-( :-(
The CC for these two (CC_ARP_PATTERN, CC_ARP_DIVISION) is 100 and 101, the two values for RPN. This means that if I send an RPN NULL, the PreenFM2 is presently interpreting it as changing the ARP pattern and ARP division (to 127!).
This is a problem. The industry best practice for NRPN is to send an NRPN message and then terminate it with an RPN NULL to make sure it's closed. See here for an example:
http://www.philrees.co.uk/nrpnq.htm Various controllers (including ones I've built) follow this practice. This means that the PreenFM2 can't be used with these controllers. If a synth handles NRPN, it also has to handle RPN at least enough to deal with RPN NULL.
There are some other problems with the NRPN handler: it's not properly parsing NRPN messages. The PreenFM2 requires you to submit 38 (LSB) even though that's not an NRPN requirement. Also you can't send a 38 first, then a 6 (which is also valid). And it doesn't handle running status, so you can't send a stream of 6 or 38. And I think you can interrupt an NRPN message with another random CC and it doesn't invalidate the NRPN message.
The Preen is presently doing this:
If I received a 99 then update paramMSB
Else if I received a 98 then update paramLSB
Else if I received a 6 then update MSB
Else if I received a 38 then
update LSB
Do(current param, current value)
Else if I receive anything else then
process it (but don't clear out the paramMSB, paramLSB, MSB, or LSB!)
The problem is that this is not stateful, so it has some problems. My C++ foo is not good but I might try to submit a patch which could fix things (it probably won't compile but it would give you an idea of what to do). I probably won't be able to enable running status or allowing just a 6 or 38, because in order to do that you have to change the preen's parameters every time a 6 *or* 38 is received, not wait for both of them.
In general, if you don't want your device to have to pause to wait for an (optional) additional 6 or 38, then NRPN works as follows.
If I received a 99 then
If I received a 98 then
MSB = 0, LSB = 0
Loop
If I received a 6 then
Update MSB
Do(param, MSB, LSB)
Else if I received a 38 then
Update LSB
Do(param, MSB, LSB)
Else if I received anything else then
push back into the CC stream
break from loop
Else if I received anything else then
push back into the CC stream
This pseudocode is easy but requires you to do partial updates with just the MSB or just the LSB (unfortunately, NRPN permits this). Your other option is to wait for a little bit to see if the LSB is coming next and then update, but this could slow down NRPN parsing slightly.
Some controllers send both LSB and MSB, but others (like the BeatStep series) only send LSB or only send MSB. And the order is not guaranteed. I think what should be done is to expect both MSB and LSB, but then continue to update single LSB or MSB updates on running status. And if you want to do NRPN, I think you really HAVE to reserve 100 and 101 for RPN or it won't work with certain controllers. This means moving or deleting arpeggiator direction and pattern.
This still doesn't solve the mystery of why sending CC 101 or CC 100 causes the PreenFM2 to slow down (a lot -- like 1 MS).