From 4fa9e167b27f59490f86d74f628cc7e624c1c4fd Mon Sep 17 00:00:00 2001 From: Kevin <68612569+diyelectromusic@users.noreply.github.com> Date: Thu, 25 Apr 2024 18:30:02 +0100 Subject: [PATCH] Initial implementation of USB MIDI SysEx message handling. (#634) * Initial implementation of USB MIDI SysEx message handling. * Remove unused parameter from USB message handling. --- src/mididevice.h | 3 ++ src/midikeyboard.cpp | 67 +++++++++++++++++++++++++++++++++++++--- src/midikeyboard.h | 7 +++++ src/serialmididevice.cpp | 4 +-- src/serialmididevice.h | 3 -- 5 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/mididevice.h b/src/mididevice.h index 44be25a..0fc027c 100644 --- a/src/mididevice.h +++ b/src/mididevice.h @@ -30,6 +30,9 @@ #include #include "userinterface.h" +#define MAX_DX7_SYSEX_LENGTH 4104 +#define MAX_MIDI_MESSAGE MAX_DX7_SYSEX_LENGTH + class CMiniDexed; class CMIDIDevice diff --git a/src/midikeyboard.cpp b/src/midikeyboard.cpp index 169f165..2eae9d8 100644 --- a/src/midikeyboard.cpp +++ b/src/midikeyboard.cpp @@ -37,6 +37,7 @@ TMIDIPacketHandler * const CMIDIKeyboard::s_pMIDIPacketHandler[MaxInstances] = CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI, unsigned nInstance) : CMIDIDevice (pSynthesizer, pConfig, pUI), + m_nSysExIdx (0), m_nInstance (nInstance), m_pMIDIDevice (0) { @@ -100,28 +101,86 @@ void CMIDIKeyboard::Send (const u8 *pMessage, size_t nLength, unsigned nCable) m_SendQueue.push (Entry); } +// Most packets will be passed straight onto the main MIDI message handler +// but SysEx messages are multiple USB packets and so will need building up +// before parsing. +void CMIDIKeyboard::USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable) +{ + if ((pPacket[0] == 0xF0) && (m_nSysExIdx == 0)) + { + // Start of SysEx message + //printf("SysEx Start Idx=%d, (%d)\n", m_nSysExIdx, nLength); + for (unsigned i=0; i= USB_SYSEX_BUFFER_SIZE) { + // Run out of space, so reset and ignore rest of the message + m_nSysExIdx = 0; + break; + } + else if (pPacket[i] == 0xF7) { + // End of SysEx message + m_SysEx[m_nSysExIdx++] = pPacket[i]; + //printf ("SysEx End Idx=%d\n", m_nSysExIdx); + MIDIMessageHandler (m_SysEx, m_nSysExIdx, nCable); + // Reset ready for next time + m_nSysExIdx = 0; + } + else if ((pPacket[i] & 0x80) != 0) { + // Received another command, so reset processing as something has gone wrong + //printf ("SysEx Reset\n"); + m_nSysExIdx = 0; + break; + } + else + { + // Store the byte + m_SysEx[m_nSysExIdx++] = pPacket[i]; + } + } + } + else + { + // Assume it is a standard message + MIDIMessageHandler (pPacket, nLength, nCable); + } +} + void CMIDIKeyboard::MIDIPacketHandler0 (unsigned nCable, u8 *pPacket, unsigned nLength) { assert (s_pThis[0] != 0); - s_pThis[0]->MIDIMessageHandler (pPacket, nLength, nCable); + s_pThis[0]->USBMIDIMessageHandler (pPacket, nLength, nCable); } void CMIDIKeyboard::MIDIPacketHandler1 (unsigned nCable, u8 *pPacket, unsigned nLength) { assert (s_pThis[1] != 0); - s_pThis[1]->MIDIMessageHandler (pPacket, nLength, nCable); + s_pThis[1]->USBMIDIMessageHandler (pPacket, nLength, nCable); } void CMIDIKeyboard::MIDIPacketHandler2 (unsigned nCable, u8 *pPacket, unsigned nLength) { assert (s_pThis[2] != 0); - s_pThis[2]->MIDIMessageHandler (pPacket, nLength, nCable); + s_pThis[2]->USBMIDIMessageHandler (pPacket, nLength, nCable); } void CMIDIKeyboard::MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength) { assert (s_pThis[3] != 0); - s_pThis[3]->MIDIMessageHandler (pPacket, nLength, nCable); + s_pThis[3]->USBMIDIMessageHandler (pPacket, nLength, nCable); } void CMIDIKeyboard::DeviceRemovedHandler (CDevice *pDevice, void *pContext) diff --git a/src/midikeyboard.h b/src/midikeyboard.h index 0868f9c..047fa52 100644 --- a/src/midikeyboard.h +++ b/src/midikeyboard.h @@ -31,6 +31,8 @@ #include #include +#define USB_SYSEX_BUFFER_SIZE (MAX_DX7_SYSEX_LENGTH+128) // Allow a bit spare to handle unexpected SysEx messages + class CMiniDexed; class CMIDIKeyboard : public CMIDIDevice @@ -53,6 +55,8 @@ private: static void MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength); static void DeviceRemovedHandler (CDevice *pDevice, void *pContext); + + void USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable); private: struct TSendQueueEntry @@ -61,6 +65,8 @@ private: size_t nLength; unsigned nCable; }; + uint8_t m_SysEx[USB_SYSEX_BUFFER_SIZE]; + unsigned m_nSysExIdx; private: unsigned m_nInstance; @@ -73,6 +79,7 @@ private: static CMIDIKeyboard *s_pThis[MaxInstances]; static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances]; + }; #endif diff --git a/src/serialmididevice.cpp b/src/serialmididevice.cpp index b37a498..3fe01e8 100644 --- a/src/serialmididevice.cpp +++ b/src/serialmididevice.cpp @@ -75,7 +75,7 @@ void CSerialMIDIDevice::Process (void) return; } - if (m_pConfig->GetMIDIDumpEnabled ()) +/* if (m_pConfig->GetMIDIDumpEnabled ()) { printf("Incoming MIDI data:"); for (uint16_t i = 0; i < nResult; i++) @@ -85,7 +85,7 @@ void CSerialMIDIDevice::Process (void) printf(" 0x%02x",Buffer[i]); } printf("\n"); - } + }*/ // Process MIDI messages // See: https://www.midi.org/specifications/item/table-1-summary-of-midi-message diff --git a/src/serialmididevice.h b/src/serialmididevice.h index 1a5b465..fdf61b2 100644 --- a/src/serialmididevice.h +++ b/src/serialmididevice.h @@ -30,9 +30,6 @@ #include #include -#define MAX_DX7_SYSEX_LENGTH 4104 -#define MAX_MIDI_MESSAGE MAX_DX7_SYSEX_LENGTH - class CMiniDexed; class CSerialMIDIDevice : public CMIDIDevice