cs-midi/MIDI_Parsers/USBMIDI_Parser.cpp

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