+bool
+MidiBuffer::second_simultaneous_midi_byte_is_first (uint8_t a, uint8_t b)
+{
+ bool b_first = false;
+
+ /* two events at identical times. we need to determine
+ the order in which they should occur.
+
+ the rule is:
+
+ Controller messages
+ Program Change
+ Note Off
+ Note On
+ Note Pressure
+ Channel Pressure
+ Pitch Bend
+ */
+
+ if ((a) >= 0xf0 || (b) >= 0xf0 || ((a & 0xf) != (b & 0xf))) {
+
+ /* if either message is not a channel message, or if the channels are
+ * different, we don't care about the type.
+ */
+
+ b_first = true;
+
+ } else {
+
+ switch (b & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ b_first = true;
+ break;
+
+ case MIDI_CMD_PGM_CHANGE:
+ switch (a & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ break;
+ case MIDI_CMD_PGM_CHANGE:
+ case MIDI_CMD_NOTE_OFF:
+ case MIDI_CMD_NOTE_ON:
+ case MIDI_CMD_NOTE_PRESSURE:
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ case MIDI_CMD_BENDER:
+ b_first = true;
+ }
+ break;
+
+ case MIDI_CMD_NOTE_OFF:
+ switch (a & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ case MIDI_CMD_PGM_CHANGE:
+ break;
+ case MIDI_CMD_NOTE_OFF:
+ case MIDI_CMD_NOTE_ON:
+ case MIDI_CMD_NOTE_PRESSURE:
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ case MIDI_CMD_BENDER:
+ b_first = true;
+ }
+ break;
+
+ case MIDI_CMD_NOTE_ON:
+ switch (a & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ case MIDI_CMD_PGM_CHANGE:
+ case MIDI_CMD_NOTE_OFF:
+ break;
+ case MIDI_CMD_NOTE_ON:
+ case MIDI_CMD_NOTE_PRESSURE:
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ case MIDI_CMD_BENDER:
+ b_first = true;
+ }
+ break;
+ case MIDI_CMD_NOTE_PRESSURE:
+ switch (a & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ case MIDI_CMD_PGM_CHANGE:
+ case MIDI_CMD_NOTE_OFF:
+ case MIDI_CMD_NOTE_ON:
+ break;
+ case MIDI_CMD_NOTE_PRESSURE:
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ case MIDI_CMD_BENDER:
+ b_first = true;
+ }
+ break;
+
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ switch (a & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ case MIDI_CMD_PGM_CHANGE:
+ case MIDI_CMD_NOTE_OFF:
+ case MIDI_CMD_NOTE_ON:
+ case MIDI_CMD_NOTE_PRESSURE:
+ break;
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ case MIDI_CMD_BENDER:
+ b_first = true;
+ }
+ break;
+ case MIDI_CMD_BENDER:
+ switch (a & 0xf0) {
+ case MIDI_CMD_CONTROL:
+ case MIDI_CMD_PGM_CHANGE:
+ case MIDI_CMD_NOTE_OFF:
+ case MIDI_CMD_NOTE_ON:
+ case MIDI_CMD_NOTE_PRESSURE:
+ case MIDI_CMD_CHANNEL_PRESSURE:
+ break;
+ case MIDI_CMD_BENDER:
+ b_first = true;
+ }
+ break;
+ }
+ }
+
+ return b_first;
+}
+