+Control & MackiePort::lookup_control( MIDI::byte * bytes, size_t count )
+{
+ // Don't instantiate a MidiByteArray here unless it's needed for exceptions.
+ // Reason being that this method is called for every single incoming
+ // midi event, and it needs to be as efficient as possible.
+
+ Control * control = 0;
+ MIDI::byte midi_type = bytes[0] & 0xf0; //0b11110000
+
+ switch (midi_type) {
+ // fader
+ case MackieMidiBuilder::midi_fader_id:
+ {
+ int midi_id = bytes[0] & 0x0f;
+ control = _mcp.surface().faders[midi_id];
+ if ( control == 0 )
+ {
+ MidiByteArray mba( count, bytes );
+ ostringstream os;
+ os << "control for fader" << bytes << " id " << midi_id << " is null";
+ throw MackieControlException( os.str() );
+ }
+ break;
+ }
+
+ // button
+ case MackieMidiBuilder::midi_button_id:
+ control = _mcp.surface().buttons[bytes[1]];
+ if ( control == 0 )
+ {
+ MidiByteArray mba( count, bytes );
+ ostringstream os;
+ os << "control for button " << bytes << " is null";
+ throw MackieControlException( os.str() );
+ }
+ break;
+
+ // pot (jog wheel, external control)
+ case MackieMidiBuilder::midi_pot_id:
+ control = _mcp.surface().pots[bytes[1]];
+ if ( control == 0 )
+ {
+ MidiByteArray mba( count, bytes );
+ ostringstream os;
+ os << "control for rotary " << mba << " is null";
+ throw MackieControlException( os.str() );
+ }
+ break;
+
+ default:
+ MidiByteArray mba( count, bytes );
+ ostringstream os;
+ os << "Cannot find control for " << bytes;
+ throw MackieControlException( os.str() );
+ }
+ return *control;
+}
+
+bool MackiePort::handle_control_timeout_event ( Control * control )
+{
+ // empty control_state
+ ControlState control_state;
+ control->in_use( false );
+ control_event( *this, *control, control_state );
+
+ // only call this method once from the timer
+ return false;
+}
+