Skip to content

Commit

Permalink
Initial implementation of USB MIDI SysEx message handling. (#634)
Browse files Browse the repository at this point in the history
* Initial implementation of USB MIDI SysEx message handling.

* Remove unused parameter from USB message handling.
  • Loading branch information
diyelectromusic authored Apr 25, 2024
1 parent e2dc897 commit 4fa9e16
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/mididevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
#include <circle/spinlock.h>
#include "userinterface.h"

#define MAX_DX7_SYSEX_LENGTH 4104
#define MAX_MIDI_MESSAGE MAX_DX7_SYSEX_LENGTH

class CMiniDexed;

class CMIDIDevice
Expand Down
67 changes: 63 additions & 4 deletions src/midikeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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; i++) {
m_SysEx[i] = 0;
}
for (unsigned i=0; i<nLength; i++) {
m_SysEx[m_nSysExIdx++] = pPacket[i];
}
}
else if (m_nSysExIdx != 0)
{
// Continue processing SysEx message
//printf("SysEx Packet Idx=%d, (%d)\n", m_nSysExIdx, nLength);
for (unsigned i=0; i<nLength; i++) {
if (pPacket[i] == 0xF8 || pPacket[i] == 0xFA || pPacket[i] == 0xFB || pPacket[i] == 0xFC || pPacket[i] == 0xFE || pPacket[i] == 0xFF) {
// Singe-byte System Realtime Messages can happen at any time!
MIDIMessageHandler (&pPacket[i], 1, nCable);
}
else if (m_nSysExIdx >= 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)
Expand Down
7 changes: 7 additions & 0 deletions src/midikeyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <circle/types.h>
#include <queue>

#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
Expand All @@ -53,6 +55,8 @@ class CMIDIKeyboard : public CMIDIDevice
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
Expand All @@ -61,6 +65,8 @@ class CMIDIKeyboard : public CMIDIDevice
size_t nLength;
unsigned nCable;
};
uint8_t m_SysEx[USB_SYSEX_BUFFER_SIZE];
unsigned m_nSysExIdx;

private:
unsigned m_nInstance;
Expand All @@ -73,6 +79,7 @@ class CMIDIKeyboard : public CMIDIDevice
static CMIDIKeyboard *s_pThis[MaxInstances];

static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances];

};

#endif
4 changes: 2 additions & 2 deletions src/serialmididevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand All @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/serialmididevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@
#include <circle/writebuffer.h>
#include <circle/types.h>

#define MAX_DX7_SYSEX_LENGTH 4104
#define MAX_MIDI_MESSAGE MAX_DX7_SYSEX_LENGTH

class CMiniDexed;

class CSerialMIDIDevice : public CMIDIDevice
Expand Down

0 comments on commit 4fa9e16

Please sign in to comment.