167 lines
4.7 KiB
C++
167 lines
4.7 KiB
C++
#include "USBMIDI_Parser.hpp"
|
|
#include <Settings/SettingsWrapper.hpp>
|
|
|
|
BEGIN_CS_NAMESPACE
|
|
|
|
MIDIReadEvent USBMIDI_Parser::handleChannelMessage(MIDIUSBPacket_t packet,
|
|
Cable cable) {
|
|
midimsg.header = packet[1];
|
|
midimsg.data1 = packet[2];
|
|
midimsg.data2 = packet[3];
|
|
midimsg.cable = cable;
|
|
return MIDIReadEvent::CHANNEL_MESSAGE;
|
|
}
|
|
|
|
MIDIReadEvent USBMIDI_Parser::handleSysExStartCont(MIDIUSBPacket_t packet,
|
|
Cable cable) {
|
|
#if !IGNORE_SYSEX
|
|
if (packet[1] == uint8_t(MIDIMessageType::SysExStart)) {
|
|
startSysEx(cable);
|
|
} else if (!receivingSysEx(cable)) {
|
|
DEBUGREF(F("No SysExStart received"));
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
}
|
|
|
|
if (!hasSysExSpace(cable, 3)) {
|
|
storePacket(packet);
|
|
endSysExChunk(cable);
|
|
return MIDIReadEvent::SYSEX_CHUNK;
|
|
}
|
|
|
|
addSysExBytes(cable, &packet[1], 3);
|
|
#else
|
|
(void)packet;
|
|
(void)cable;
|
|
#endif
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
}
|
|
|
|
template <uint8_t NumBytes>
|
|
MIDIReadEvent USBMIDI_Parser::handleSysExEnd(MIDIUSBPacket_t packet,
|
|
Cable cable) {
|
|
static_assert(NumBytes == 2 || NumBytes == 3,
|
|
"Only 2- or 3-byte SysEx packets are supported");
|
|
|
|
#if !IGNORE_SYSEX
|
|
if (packet[1] == uint8_t(MIDIMessageType::SysExStart)) {
|
|
startSysEx(cable);
|
|
} else if (!receivingSysEx(cable)) {
|
|
DEBUGFN(F("No SysExStart received"));
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
}
|
|
|
|
if (!hasSysExSpace(cable, NumBytes)) {
|
|
storePacket(packet);
|
|
endSysExChunk(cable);
|
|
return MIDIReadEvent::SYSEX_CHUNK;
|
|
}
|
|
|
|
addSysExBytes(cable, &packet[1], NumBytes);
|
|
endSysEx(cable);
|
|
return MIDIReadEvent::SYSEX_MESSAGE;
|
|
#else
|
|
(void)packet;
|
|
(void)cable;
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
#endif
|
|
}
|
|
|
|
template <>
|
|
MIDIReadEvent USBMIDI_Parser::handleSysExEnd<1>(MIDIUSBPacket_t packet,
|
|
Cable cable) {
|
|
if (packet[1] != uint8_t(MIDIMessageType::SysExEnd)) {
|
|
midimsg.header = packet[1];
|
|
midimsg.cable = cable;
|
|
return MIDIReadEvent::SYSCOMMON_MESSAGE;
|
|
}
|
|
|
|
#if !IGNORE_SYSEX
|
|
else {
|
|
if (!receivingSysEx(cable)) {
|
|
DEBUGREF(F("No SysExStart received"));
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
}
|
|
|
|
if (!hasSysExSpace(cable, 1)) {
|
|
storePacket(packet);
|
|
endSysExChunk(cable);
|
|
return MIDIReadEvent::SYSEX_CHUNK;
|
|
}
|
|
|
|
addSysExByte(cable, packet[1]);
|
|
endSysEx(cable);
|
|
return MIDIReadEvent::SYSEX_MESSAGE;
|
|
}
|
|
#else
|
|
(void)packet;
|
|
(void)cable;
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
#endif
|
|
}
|
|
|
|
MIDIReadEvent USBMIDI_Parser::handleSysCommon(MIDIUSBPacket_t packet,
|
|
Cable cable) {
|
|
midimsg.header = packet[1];
|
|
midimsg.data1 = packet[2];
|
|
midimsg.data2 = packet[3];
|
|
midimsg.cable = cable;
|
|
return MIDIReadEvent::SYSCOMMON_MESSAGE;
|
|
}
|
|
|
|
MIDIReadEvent USBMIDI_Parser::handleSingleByte(MIDIUSBPacket_t packet,
|
|
Cable cable) {
|
|
rtmsg.message = packet[1];
|
|
rtmsg.cable = cable;
|
|
return MIDIReadEvent::REALTIME_MESSAGE;
|
|
}
|
|
|
|
MIDIReadEvent USBMIDI_Parser::feed(MIDIUSBPacket_t packet) {
|
|
Cable cable = Cable(packet[0] >> 4);
|
|
MIDICodeIndexNumber CIN = MIDICodeIndexNumber(packet[0] & 0xF);
|
|
|
|
if (cable.getRaw() >= USB_MIDI_NUMBER_OF_CABLES)
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
|
|
using M = MIDICodeIndexNumber;
|
|
switch (CIN) {
|
|
case M::MiscFunctionCodes: break;
|
|
case M::CableEvents: break;
|
|
case M::SystemCommon2B:
|
|
case M::SystemCommon3B: return handleSysCommon(packet, cable);
|
|
case M::SysExStartCont: return handleSysExStartCont(packet, cable);
|
|
case M::SysExEnd1B: return handleSysExEnd<1>(packet, cable);
|
|
case M::SysExEnd2B: return handleSysExEnd<2>(packet, cable);
|
|
case M::SysExEnd3B: return handleSysExEnd<3>(packet, cable);
|
|
case M::NoteOff:
|
|
case M::NoteOn:
|
|
case M::KeyPressure:
|
|
case M::ControlChange:
|
|
case M::ProgramChange:
|
|
case M::ChannelPressure:
|
|
case M::PitchBend: return handleChannelMessage(packet, cable);
|
|
case M::SingleByte: return handleSingleByte(packet, cable);
|
|
default: break;
|
|
}
|
|
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
}
|
|
|
|
MIDIReadEvent USBMIDI_Parser::resume() {
|
|
#if !IGNORE_SYSEX
|
|
if (!hasStoredPacket())
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
|
|
MIDIUSBPacket_t packet = popStoredPacket();
|
|
|
|
if (receivingSysEx(activeCable)) {
|
|
startSysEx(activeCable);
|
|
}
|
|
|
|
return feed(packet);
|
|
#else
|
|
return MIDIReadEvent::NO_MESSAGE;
|
|
#endif
|
|
}
|
|
|
|
END_CS_NAMESPACE
|