113 lines
3.3 KiB
C++
113 lines
3.3 KiB
C++
#include "USBMIDI_Interface.hpp"
|
|
|
|
BEGIN_CS_NAMESPACE
|
|
|
|
void USBMIDI_Interface::update() {
|
|
tud_task();
|
|
MIDI_Interface::updateIncoming(this);
|
|
}
|
|
|
|
MIDIReadEvent USBMIDI_Interface::read() {
|
|
return parser.pull(TinyUSBPuller{cableNum});
|
|
}
|
|
|
|
ChannelMessage USBMIDI_Interface::getChannelMessage() const {
|
|
return parser.getChannelMessage();
|
|
}
|
|
|
|
SysCommonMessage USBMIDI_Interface::getSysCommonMessage() const {
|
|
return parser.getSysCommonMessage();
|
|
}
|
|
|
|
RealTimeMessage USBMIDI_Interface::getRealTimeMessage() const {
|
|
return parser.getRealTimeMessage();
|
|
}
|
|
|
|
SysExMessage USBMIDI_Interface::getSysExMessage() const {
|
|
return parser.getSysExMessage();
|
|
}
|
|
|
|
// Map MIDI status high nibble to USB MIDI Code Index Number
|
|
MIDICodeIndexNumber USBMIDI_Interface::CIN(uint8_t status) {
|
|
if (status >= 0x80 && status < 0xF0)
|
|
return static_cast<MIDICodeIndexNumber>((status >> 4) & 0x0F);
|
|
switch (status) {
|
|
case 0xF1: // MTC Quarter Frame
|
|
case 0xF3: // Song Select
|
|
return MIDICodeIndexNumber::SystemCommon2B;
|
|
case 0xF2: // Song Position Pointer
|
|
return MIDICodeIndexNumber::SystemCommon3B;
|
|
case 0xF6: // Tune Request
|
|
case 0xF7: // SysEx End (bare)
|
|
return MIDICodeIndexNumber::SystemCommon1B;
|
|
default:
|
|
if (status >= 0xF8)
|
|
return MIDICodeIndexNumber::SingleByte;
|
|
return MIDICodeIndexNumber::MiscFunctionCodes;
|
|
}
|
|
}
|
|
|
|
void USBMIDI_Interface::writePacket(uint8_t cin, uint8_t b0,
|
|
uint8_t b1, uint8_t b2) {
|
|
uint8_t packet[4] = {
|
|
static_cast<uint8_t>((cableNum << 4) | (cin & 0x0F)),
|
|
b0, b1, b2
|
|
};
|
|
tud_midi_n_packet_write(cableNum, packet);
|
|
}
|
|
|
|
void USBMIDI_Interface::sendChannelMessageImpl(ChannelMessage msg) {
|
|
auto cin = CIN(msg.header);
|
|
if (msg.hasTwoDataBytes())
|
|
writePacket(uint8_t(cin), msg.header, msg.data1, msg.data2);
|
|
else
|
|
writePacket(uint8_t(cin), msg.header, msg.data1, 0);
|
|
}
|
|
|
|
void USBMIDI_Interface::sendSysCommonImpl(SysCommonMessage msg) {
|
|
auto cin = CIN(msg.header);
|
|
uint8_t ndata = msg.getNumberOfDataBytes();
|
|
if (ndata == 2)
|
|
writePacket(uint8_t(cin), msg.header, msg.data1, msg.data2);
|
|
else if (ndata == 1)
|
|
writePacket(uint8_t(cin), msg.header, msg.data1, 0);
|
|
else
|
|
writePacket(uint8_t(cin), msg.header, 0, 0);
|
|
}
|
|
|
|
void USBMIDI_Interface::sendSysExImpl(SysExMessage msg) {
|
|
const uint8_t *data = msg.data;
|
|
uint16_t remaining = msg.length;
|
|
|
|
while (remaining > 3) {
|
|
writePacket(uint8_t(MIDICodeIndexNumber::SysExStartCont),
|
|
data[0], data[1], data[2]);
|
|
data += 3;
|
|
remaining -= 3;
|
|
}
|
|
|
|
switch (remaining) {
|
|
case 3:
|
|
writePacket(uint8_t(MIDICodeIndexNumber::SysExEnd3B),
|
|
data[0], data[1], data[2]);
|
|
break;
|
|
case 2:
|
|
writePacket(uint8_t(MIDICodeIndexNumber::SysExEnd2B),
|
|
data[0], data[1], 0);
|
|
break;
|
|
case 1:
|
|
writePacket(uint8_t(MIDICodeIndexNumber::SysExEnd1B),
|
|
data[0], 0, 0);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void USBMIDI_Interface::sendRealTimeImpl(RealTimeMessage msg) {
|
|
writePacket(uint8_t(MIDICodeIndexNumber::SingleByte),
|
|
msg.message, 0, 0);
|
|
}
|
|
|
|
END_CS_NAMESPACE
|