Merge pull request #33 from lioncash/midi-dec

MIDIDecoder: Make readContinuedValue internal + other cleanups
This commit is contained in:
Phillip Stephens 2019-08-24 20:45:57 -07:00 committed by GitHub
commit b9971502a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 21 deletions

View File

@ -9,8 +9,6 @@ class IMIDIReader;
class MIDIDecoder { class MIDIDecoder {
IMIDIReader& m_out; IMIDIReader& m_out;
uint8_t m_status = 0; uint8_t m_status = 0;
bool _readContinuedValue(std::vector<uint8_t>::const_iterator& it, std::vector<uint8_t>::const_iterator end,
uint32_t& valOut);
public: public:
MIDIDecoder(IMIDIReader& out) : m_out(out) {} MIDIDecoder(IMIDIReader& out) : m_out(out) {}

View File

@ -1,42 +1,46 @@
#include "boo/audiodev/MIDIDecoder.hpp" #include "boo/audiodev/MIDIDecoder.hpp"
#include <algorithm> #include <algorithm>
#include <optional>
#include "boo/audiodev/IMIDIReader.hpp" #include "boo/audiodev/IMIDIReader.hpp"
#include "lib/audiodev/MIDICommon.hpp" #include "lib/audiodev/MIDICommon.hpp"
namespace boo { namespace boo {
namespace {
constexpr uint8_t clamp7(uint8_t val) { return std::clamp(val, uint8_t{0}, uint8_t{127}); }
constexpr uint8_t clamp7(uint8_t val) { return std::max(0, std::min(127, int(val))); } std::optional<uint32_t> readContinuedValue(std::vector<uint8_t>::const_iterator& it,
std::vector<uint8_t>::const_iterator end) {
bool MIDIDecoder::_readContinuedValue(std::vector<uint8_t>::const_iterator& it,
std::vector<uint8_t>::const_iterator end, uint32_t& valOut) {
uint8_t a = *it++; uint8_t a = *it++;
valOut = a & 0x7f; uint32_t valOut = a & 0x7f;
if (a & 0x80) { if ((a & 0x80) != 0) {
if (it == end) if (it == end) {
return false; return std::nullopt;
}
valOut <<= 7; valOut <<= 7;
a = *it++; a = *it++;
valOut |= a & 0x7f; valOut |= a & 0x7f;
if (a & 0x80) { if ((a & 0x80) != 0) {
if (it == end) if (it == end) {
return false; return std::nullopt;
}
valOut <<= 7; valOut <<= 7;
a = *it++; a = *it++;
valOut |= a & 0x7f; valOut |= a & 0x7f;
} }
} }
return true; return valOut;
} }
} // Anonymous namespace
std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8_t>::const_iterator begin, std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8_t>::const_iterator begin,
std::vector<uint8_t>::const_iterator end) { std::vector<uint8_t>::const_iterator end) {
std::vector<uint8_t>::const_iterator it = begin; auto it = begin;
while (it != end) { while (it != end) {
uint8_t a = *it++; uint8_t a = *it++;
uint8_t b; uint8_t b;
@ -51,9 +55,8 @@ std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8
return begin; return begin;
a = *it++; a = *it++;
uint32_t length; const auto length = readContinuedValue(it, end);
_readContinuedValue(it, end, length); it += *length;
it += length;
} else { } else {
uint8_t chan = m_status & 0xf; uint8_t chan = m_status & 0xf;
switch (Status(m_status & 0xf0)) { switch (Status(m_status & 0xf0)) {
@ -124,10 +127,11 @@ std::vector<uint8_t>::const_iterator MIDIDecoder::receiveBytes(std::vector<uint8
case Status::SysEx: { case Status::SysEx: {
switch (Status(m_status & 0xff)) { switch (Status(m_status & 0xff)) {
case Status::SysEx: { case Status::SysEx: {
uint32_t len; const auto len = readContinuedValue(it, end);
if (!_readContinuedValue(it, end, len) || end - it < len) if (!len || end - it < *len) {
return begin; return begin;
m_out.sysex(&*it, len); }
m_out.sysex(&*it, *len);
break; break;
} }
case Status::TimecodeQuarterFrame: { case Status::TimecodeQuarterFrame: {