+const Channel::RPNState Channel::RPN_READY_FOR_VALUE = RPNState (HaveLSB|HaveMSB);
+const Channel::RPNState Channel::RPN_VALUE_READY = RPNState (HaveLSB|HaveMSB|HaveValue);
+
+bool
+Channel::maybe_process_rpns (Parser& parser, EventTwoBytes *tb)
+{
+ switch (tb->controller_number) {
+ case 0x62:
+ _rpn_state = RPNState (_rpn_state|HaveMSB);
+ _rpn_lsb = tb->value;
+ if (_rpn_msb == 0x7f && _rpn_lsb == 0x7f) {
+ rpn_reset ();
+ }
+ return true;
+ case 0x63:
+ _rpn_state = RPNState (_rpn_state|HaveLSB);
+ _rpn_msb = tb->value;
+ if (_rpn_msb == 0x7f && _rpn_lsb == 0x7f) {
+ rpn_reset ();
+ }
+ return true;
+
+ case 0x64:
+ _nrpn_state = RPNState (_rpn_state|HaveMSB);
+ _rpn_lsb = tb->value;
+ if (_nrpn_msb == 0x7f && _nrpn_lsb == 0x7f) {
+ nrpn_reset ();
+ }
+ return true;
+ case 0x65:
+ _nrpn_state = RPNState (_rpn_state|HaveLSB);
+ _rpn_msb = tb->value;
+ if (_rpn_msb == 0x7f && _rpn_lsb == 0x7f) {
+ nrpn_reset ();
+ }
+ return true;
+ }
+
+ if ((_nrpn_state & RPN_READY_FOR_VALUE) == RPN_READY_FOR_VALUE) {
+
+ uint16_t rpn_id = (_rpn_msb << 7)|_rpn_lsb;
+
+ switch (tb->controller_number) {
+ case 0x60:
+ /* data increment */
+ _nrpn_state = RPNState (_nrpn_state|HaveValue);
+ parser.channel_nrpn_change[_channel_number] (parser, rpn_id, 1); /* EMIT SIGNAL */
+ return true;
+ case 0x61:
+ /* data decrement */
+ _nrpn_state = RPNState (_nrpn_state|HaveValue);
+ parser.channel_nrpn_change[_channel_number] (parser, rpn_id, -1); /* EMIT SIGNAL */
+ return true;
+ case 0x06:
+ /* data entry MSB */
+ _nrpn_state = RPNState (_nrpn_state|HaveValue);
+ _nrpn_val_msb = tb->value;
+ break;
+ case 0x26:
+ /* data entry LSB */
+ _nrpn_state = RPNState (_nrpn_state|HaveValue);
+ _nrpn_val_lsb = tb->value;
+ }
+
+ if (_nrpn_state == RPN_VALUE_READY) {
+
+ float rpn_val = ((_rpn_val_msb << 7)|_rpn_val_lsb)/16384.0;
+
+ std::pair<RPNList::iterator,bool> result = nrpns.insert (std::make_pair (rpn_id, rpn_val));
+
+ if (!result.second) {
+ result.first->second = rpn_val;
+ }
+
+ parser.channel_nrpn[_channel_number] (parser, rpn_id, rpn_val); /* EMIT SIGNAL */
+ return true;
+ }
+
+ } else if ((_rpn_state & RPN_READY_FOR_VALUE) == RPN_READY_FOR_VALUE) {
+
+ uint16_t rpn_id = (_rpn_msb << 7)|_rpn_lsb;
+
+ switch (tb->controller_number) {
+ case 0x60:
+ /* data increment */
+ _rpn_state = RPNState (_rpn_state|HaveValue);
+ parser.channel_rpn_change[_channel_number] (parser, rpn_id, 1); /* EMIT SIGNAL */
+ return true;
+ case 0x61:
+ /* data decrement */
+ _rpn_state = RPNState (_rpn_state|HaveValue);
+ parser.channel_rpn_change[_channel_number] (parser, rpn_id, -1); /* EMIT SIGNAL */
+ return true;
+ case 0x06:
+ /* data entry MSB */
+ _rpn_state = RPNState (_rpn_state|HaveValue);
+ _rpn_val_msb = tb->value;
+ break;
+ case 0x26:
+ /* data entry LSB */
+ _rpn_state = RPNState (_rpn_state|HaveValue);
+ _rpn_val_lsb = tb->value;
+ }
+
+ if (_rpn_state == RPN_VALUE_READY) {
+
+ float rpn_val = ((_rpn_val_msb << 7)|_rpn_val_lsb)/16384.0;
+
+ std::pair<RPNList::iterator,bool> result = rpns.insert (std::make_pair (rpn_id, rpn_val));
+
+ if (!result.second) {
+ result.first->second = rpn_val;
+ }
+
+ parser.channel_rpn[_channel_number] (parser, rpn_id, rpn_val); /* EMIT SIGNAL */
+ return true;
+ }
+ }
+
+ return false;
+}
+