From fd2a92e2c2fd80a0d34feee64f19c5c4dd1dfce0 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 24 Aug 2018 22:37:26 -1000 Subject: [PATCH] Allow MIDIDecoder to handle multiple messages per pass --- lib/audiodev/MIDIDecoder.cpp | 270 +++++++++++++++++------------------ 1 file changed, 135 insertions(+), 135 deletions(-) diff --git a/lib/audiodev/MIDIDecoder.cpp b/lib/audiodev/MIDIDecoder.cpp index bf99a59..38dee6a 100644 --- a/lib/audiodev/MIDIDecoder.cpp +++ b/lib/audiodev/MIDIDecoder.cpp @@ -41,124 +41,31 @@ MIDIDecoder::receiveBytes(std::vector::const_iterator begin, std::vector::const_iterator end) { std::vector::const_iterator it = begin; - if (it == end) - return begin; - - uint8_t a = *it++; - uint8_t b; - if (a & 0x80) - m_status = a; - else - it--; - - if (m_status == 0xff) + while (it != end) { - /* Meta events (ignored for now) */ - if (it == end) - return begin; - a = *it++; + uint8_t a = *it++; + uint8_t b; + if (a & 0x80) + m_status = a; + else + it--; - uint32_t length; - _readContinuedValue(it, end, length); - it += length; - } - else - { - uint8_t chan = m_status & 0xf; - switch (Status(m_status & 0xf0)) - { - case Status::NoteOff: + if (m_status == 0xff) { + /* Meta events (ignored for now) */ if (it == end) return begin; a = *it++; - if (it == end) - return begin; - b = *it++; - m_out.noteOff(chan, clamp7(a), clamp7(b)); - break; - } - case Status::NoteOn: + + uint32_t length; + _readContinuedValue(it, end, length); + it += length; + } else { - if (it == end) - return begin; - a = *it++; - if (it == end) - return begin; - b = *it++; - m_out.noteOn(chan, clamp7(a), clamp7(b)); - break; - } - case Status::NotePressure: - { - if (it == end) - return begin; - a = *it++; - if (it == end) - return begin; - b = *it++; - m_out.notePressure(chan, clamp7(a), clamp7(b)); - break; - } - case Status::ControlChange: - { - if (it == end) - return begin; - a = *it++; - if (it == end) - return begin; - b = *it++; - m_out.controlChange(chan, clamp7(a), clamp7(b)); - break; - } - case Status::ProgramChange: - { - if (it == end) - return begin; - a = *it++; - m_out.programChange(chan, clamp7(a)); - break; - } - case Status::ChannelPressure: - { - if (it == end) - return begin; - a = *it++; - m_out.channelPressure(chan, clamp7(a)); - break; - } - case Status::PitchBend: - { - if (it == end) - return begin; - a = *it++; - if (it == end) - return begin; - b = *it++; - m_out.pitchBend(chan, clamp7(b) * 128 + clamp7(a)); - break; - } - case Status::SysEx: - { - switch (Status(m_status & 0xff)) + uint8_t chan = m_status & 0xf; + switch (Status(m_status & 0xf0)) { - case Status::SysEx: - { - uint32_t len; - if (!_readContinuedValue(it, end, len) || end - it < len) - return begin; - m_out.sysex(&*it, len); - break; - } - case Status::TimecodeQuarterFrame: - { - if (it == end) - return begin; - a = *it++; - m_out.timeCodeQuarterFrame(a >> 4 & 0x7, a & 0xf); - break; - } - case Status::SongPositionPointer: + case Status::NoteOff: { if (it == end) return begin; @@ -166,43 +73,136 @@ MIDIDecoder::receiveBytes(std::vector::const_iterator begin, if (it == end) return begin; b = *it++; - m_out.songPositionPointer(clamp7(b) * 128 + clamp7(a)); + m_out.noteOff(chan, clamp7(a), clamp7(b)); break; } - case Status::SongSelect: + case Status::NoteOn: { if (it == end) return begin; a = *it++; - m_out.songSelect(clamp7(a)); + if (it == end) + return begin; + b = *it++; + m_out.noteOn(chan, clamp7(a), clamp7(b)); break; } - case Status::TuneRequest: - m_out.tuneRequest(); + case Status::NotePressure: + { + if (it == end) + return begin; + a = *it++; + if (it == end) + return begin; + b = *it++; + m_out.notePressure(chan, clamp7(a), clamp7(b)); + break; + } + case Status::ControlChange: + { + if (it == end) + return begin; + a = *it++; + if (it == end) + return begin; + b = *it++; + m_out.controlChange(chan, clamp7(a), clamp7(b)); + break; + } + case Status::ProgramChange: + { + if (it == end) + return begin; + a = *it++; + m_out.programChange(chan, clamp7(a)); + break; + } + case Status::ChannelPressure: + { + if (it == end) + return begin; + a = *it++; + m_out.channelPressure(chan, clamp7(a)); + break; + } + case Status::PitchBend: + { + if (it == end) + return begin; + a = *it++; + if (it == end) + return begin; + b = *it++; + m_out.pitchBend(chan, clamp7(b) * 128 + clamp7(a)); + break; + } + case Status::SysEx: + { + switch (Status(m_status & 0xff)) + { + case Status::SysEx: + { + uint32_t len; + if (!_readContinuedValue(it, end, len) || end - it < len) + return begin; + m_out.sysex(&*it, len); + break; + } + case Status::TimecodeQuarterFrame: + { + if (it == end) + return begin; + a = *it++; + m_out.timeCodeQuarterFrame(a >> 4 & 0x7, a & 0xf); + break; + } + case Status::SongPositionPointer: + { + if (it == end) + return begin; + a = *it++; + if (it == end) + return begin; + b = *it++; + m_out.songPositionPointer(clamp7(b) * 128 + clamp7(a)); + break; + } + case Status::SongSelect: + { + if (it == end) + return begin; + a = *it++; + m_out.songSelect(clamp7(a)); + break; + } + case Status::TuneRequest: + m_out.tuneRequest(); + break; + case Status::Start: + m_out.startSeq(); + break; + case Status::Continue: + m_out.continueSeq(); + break; + case Status::Stop: + m_out.stopSeq(); + break; + case Status::Reset: + m_out.reset(); + break; + case Status::SysExTerm: + case Status::TimingClock: + case Status::ActiveSensing: + default: + break; + } + break; + } + default: break; - case Status::Start: - m_out.startSeq(); - break; - case Status::Continue: - m_out.continueSeq(); - break; - case Status::Stop: - m_out.stopSeq(); - break; - case Status::Reset: - m_out.reset(); - break; - case Status::SysExTerm: - case Status::TimingClock: - case Status::ActiveSensing: - default: break; } - break; - } - default: break; } } - return it; }