Initial implementation of USB MIDI SysEx message handling. (#634)

* Initial implementation of USB MIDI SysEx message handling.

* Remove unused parameter from USB message handling.
pull/446/merge
Kevin 7 months ago committed by GitHub
parent e2dc897c8a
commit 4fa9e167b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      src/mididevice.h
  2. 67
      src/midikeyboard.cpp
  3. 7
      src/midikeyboard.h
  4. 4
      src/serialmididevice.cpp
  5. 3
      src/serialmididevice.h

@ -30,6 +30,9 @@
#include <circle/spinlock.h> #include <circle/spinlock.h>
#include "userinterface.h" #include "userinterface.h"
#define MAX_DX7_SYSEX_LENGTH 4104
#define MAX_MIDI_MESSAGE MAX_DX7_SYSEX_LENGTH
class CMiniDexed; class CMiniDexed;
class CMIDIDevice class CMIDIDevice

@ -37,6 +37,7 @@ TMIDIPacketHandler * const CMIDIKeyboard::s_pMIDIPacketHandler[MaxInstances] =
CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI, unsigned nInstance) CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI, unsigned nInstance)
: CMIDIDevice (pSynthesizer, pConfig, pUI), : CMIDIDevice (pSynthesizer, pConfig, pUI),
m_nSysExIdx (0),
m_nInstance (nInstance), m_nInstance (nInstance),
m_pMIDIDevice (0) m_pMIDIDevice (0)
{ {
@ -100,28 +101,86 @@ void CMIDIKeyboard::Send (const u8 *pMessage, size_t nLength, unsigned nCable)
m_SendQueue.push (Entry); 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) void CMIDIKeyboard::MIDIPacketHandler0 (unsigned nCable, u8 *pPacket, unsigned nLength)
{ {
assert (s_pThis[0] != 0); 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) void CMIDIKeyboard::MIDIPacketHandler1 (unsigned nCable, u8 *pPacket, unsigned nLength)
{ {
assert (s_pThis[1] != 0); 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) void CMIDIKeyboard::MIDIPacketHandler2 (unsigned nCable, u8 *pPacket, unsigned nLength)
{ {
assert (s_pThis[2] != 0); 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) void CMIDIKeyboard::MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength)
{ {
assert (s_pThis[3] != 0); 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) void CMIDIKeyboard::DeviceRemovedHandler (CDevice *pDevice, void *pContext)

@ -31,6 +31,8 @@
#include <circle/types.h> #include <circle/types.h>
#include <queue> #include <queue>
#define USB_SYSEX_BUFFER_SIZE (MAX_DX7_SYSEX_LENGTH+128) // Allow a bit spare to handle unexpected SysEx messages
class CMiniDexed; class CMiniDexed;
class CMIDIKeyboard : public CMIDIDevice class CMIDIKeyboard : public CMIDIDevice
@ -53,6 +55,8 @@ private:
static void MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength); static void MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength);
static void DeviceRemovedHandler (CDevice *pDevice, void *pContext); static void DeviceRemovedHandler (CDevice *pDevice, void *pContext);
void USBMIDIMessageHandler (u8 *pPacket, unsigned nLength, unsigned nCable);
private: private:
struct TSendQueueEntry struct TSendQueueEntry
@ -61,6 +65,8 @@ private:
size_t nLength; size_t nLength;
unsigned nCable; unsigned nCable;
}; };
uint8_t m_SysEx[USB_SYSEX_BUFFER_SIZE];
unsigned m_nSysExIdx;
private: private:
unsigned m_nInstance; unsigned m_nInstance;
@ -73,6 +79,7 @@ private:
static CMIDIKeyboard *s_pThis[MaxInstances]; static CMIDIKeyboard *s_pThis[MaxInstances];
static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances]; static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances];
}; };
#endif #endif

@ -75,7 +75,7 @@ void CSerialMIDIDevice::Process (void)
return; return;
} }
if (m_pConfig->GetMIDIDumpEnabled ()) /* if (m_pConfig->GetMIDIDumpEnabled ())
{ {
printf("Incoming MIDI data:"); printf("Incoming MIDI data:");
for (uint16_t i = 0; i < nResult; i++) for (uint16_t i = 0; i < nResult; i++)
@ -85,7 +85,7 @@ void CSerialMIDIDevice::Process (void)
printf(" 0x%02x",Buffer[i]); printf(" 0x%02x",Buffer[i]);
} }
printf("\n"); printf("\n");
} }*/
// Process MIDI messages // Process MIDI messages
// See: https://www.midi.org/specifications/item/table-1-summary-of-midi-message // See: https://www.midi.org/specifications/item/table-1-summary-of-midi-message

@ -30,9 +30,6 @@
#include <circle/writebuffer.h> #include <circle/writebuffer.h>
#include <circle/types.h> #include <circle/types.h>
#define MAX_DX7_SYSEX_LENGTH 4104
#define MAX_MIDI_MESSAGE MAX_DX7_SYSEX_LENGTH
class CMiniDexed; class CMiniDexed;
class CSerialMIDIDevice : public CMIDIDevice class CSerialMIDIDevice : public CMIDIDevice

Loading…
Cancel
Save