From 33825f3f9e40e5dde1d0d30e9d6e98ebebdf666e Mon Sep 17 00:00:00 2001 From: Rene Stange Date: Wed, 2 Mar 2022 13:18:05 +0100 Subject: [PATCH] Support multiple USB MIDI inputs at once * Maximum 2 inputs on Raspberry Pi 1-3 * Maximum 4 inputs on Raspberry Pi 4 --- src/config.h | 6 +++++ src/midikeyboard.cpp | 58 +++++++++++++++++++++++++++++++++++--------- src/midikeyboard.h | 18 +++++++++++--- src/minidexed.cpp | 12 +++++++-- src/minidexed.h | 2 +- 5 files changed, 78 insertions(+), 18 deletions(-) diff --git a/src/config.h b/src/config.h index 085de66..698bca4 100644 --- a/src/config.h +++ b/src/config.h @@ -32,6 +32,12 @@ class CConfig // Configuration for MiniDexed public: static const unsigned MaxNotes = 16; // polyphony +#if RASPPI <= 3 + static const unsigned MaxUSBMIDIDevices = 2; +#else + static const unsigned MaxUSBMIDIDevices = 4; +#endif + static const unsigned LCDColumns = 16; // HD44780 LCD static const unsigned LCDRows = 2; diff --git a/src/midikeyboard.cpp b/src/midikeyboard.cpp index baf39ba..240d0b3 100644 --- a/src/midikeyboard.cpp +++ b/src/midikeyboard.cpp @@ -24,18 +24,31 @@ #include #include -CMIDIKeyboard *CMIDIKeyboard::s_pThis = 0; +CMIDIKeyboard *CMIDIKeyboard::s_pThis[MaxInstances] = {0}; -CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig) +TMIDIPacketHandler * const CMIDIKeyboard::s_pMIDIPacketHandler[MaxInstances] = +{ + MIDIPacketHandler0, + MIDIPacketHandler1, + MIDIPacketHandler2, + MIDIPacketHandler3 +}; + +CMIDIKeyboard::CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, unsigned nInstance) : CMIDIDevice (pSynthesizer, pConfig), + m_nInstance (nInstance), m_pMIDIDevice (0) { - s_pThis = this; + assert (m_nInstance < MaxInstances); + s_pThis[m_nInstance] = this; + + m_DeviceName.Format ("umidi%u", nInstance+1); } CMIDIKeyboard::~CMIDIKeyboard (void) { - s_pThis = 0; + assert (m_nInstance < MaxInstances); + s_pThis[m_nInstance] = 0; } void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated) @@ -48,24 +61,45 @@ void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated) if (m_pMIDIDevice == 0) { m_pMIDIDevice = - (CUSBMIDIDevice *) CDeviceNameService::Get ()->GetDevice ("umidi1", FALSE); + (CUSBMIDIDevice *) CDeviceNameService::Get ()->GetDevice (m_DeviceName, FALSE); if (m_pMIDIDevice != 0) { - m_pMIDIDevice->RegisterPacketHandler (MIDIPacketHandler); + assert (m_nInstance < MaxInstances); + m_pMIDIDevice->RegisterPacketHandler (s_pMIDIPacketHandler[m_nInstance]); - m_pMIDIDevice->RegisterRemovedHandler (DeviceRemovedHandler); + m_pMIDIDevice->RegisterRemovedHandler (DeviceRemovedHandler, this); } } } -void CMIDIKeyboard::MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength) +void CMIDIKeyboard::MIDIPacketHandler0 (unsigned nCable, u8 *pPacket, unsigned nLength) { - assert (s_pThis != 0); - s_pThis->MIDIMessageHandler (pPacket, nLength, nCable); + assert (s_pThis[0] != 0); + s_pThis[0]->MIDIMessageHandler (pPacket, nLength, nCable); +} + +void CMIDIKeyboard::MIDIPacketHandler1 (unsigned nCable, u8 *pPacket, unsigned nLength) +{ + assert (s_pThis[1] != 0); + s_pThis[1]->MIDIMessageHandler (pPacket, nLength, nCable); +} + +void CMIDIKeyboard::MIDIPacketHandler2 (unsigned nCable, u8 *pPacket, unsigned nLength) +{ + assert (s_pThis[2] != 0); + s_pThis[2]->MIDIMessageHandler (pPacket, nLength, nCable); +} + +void CMIDIKeyboard::MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength) +{ + assert (s_pThis[3] != 0); + s_pThis[3]->MIDIMessageHandler (pPacket, nLength, nCable); } void CMIDIKeyboard::DeviceRemovedHandler (CDevice *pDevice, void *pContext) { - assert (s_pThis != 0); - s_pThis->m_pMIDIDevice = 0; + CMIDIKeyboard *pThis = static_cast (pContext); + assert (pThis != 0); + + pThis->m_pMIDIDevice = 0; } diff --git a/src/midikeyboard.h b/src/midikeyboard.h index da9ae76..386d83b 100644 --- a/src/midikeyboard.h +++ b/src/midikeyboard.h @@ -27,6 +27,7 @@ #include "config.h" #include #include +#include #include class CMiniDexed; @@ -34,20 +35,31 @@ class CMiniDexed; class CMIDIKeyboard : public CMIDIDevice { public: - CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig); + static const unsigned MaxInstances = 4; + +public: + CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, unsigned nInstance = 0); ~CMIDIKeyboard (void); void Process (boolean bPlugAndPlayUpdated); private: - static void MIDIPacketHandler (unsigned nCable, u8 *pPacket, unsigned nLength); + static void MIDIPacketHandler0 (unsigned nCable, u8 *pPacket, unsigned nLength); + static void MIDIPacketHandler1 (unsigned nCable, u8 *pPacket, unsigned nLength); + static void MIDIPacketHandler2 (unsigned nCable, u8 *pPacket, unsigned nLength); + static void MIDIPacketHandler3 (unsigned nCable, u8 *pPacket, unsigned nLength); static void DeviceRemovedHandler (CDevice *pDevice, void *pContext); private: + unsigned m_nInstance; + CString m_DeviceName; + CUSBMIDIDevice * volatile m_pMIDIDevice; - static CMIDIKeyboard *s_pThis; + static CMIDIKeyboard *s_pThis[MaxInstances]; + + static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances]; }; #endif diff --git a/src/minidexed.cpp b/src/minidexed.cpp index ad23b4b..14d7251 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -28,7 +28,6 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt) : CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ()), m_pConfig (pConfig), m_UI (this, pConfig), - m_MIDIKeyboard (this, pConfig), m_PCKeyboard (this), m_SerialMIDI (this, pInterrupt, pConfig), m_bUseSerial (false), @@ -36,6 +35,11 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt) 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()), m_bProfileEnabled (m_pConfig->GetProfileEnabled ()) { + for (unsigned i = 0; i < CConfig::MaxUSBMIDIDevices; i++) + { + m_pMIDIKeyboard[i] = new CMIDIKeyboard (this, pConfig, i); + assert (m_pMIDIKeyboard[i]); + } }; bool CMiniDexed::Initialize (void) @@ -64,7 +68,11 @@ bool CMiniDexed::Initialize (void) void CMiniDexed::Process (bool bPlugAndPlayUpdated) { - m_MIDIKeyboard.Process (bPlugAndPlayUpdated); + for (unsigned i = 0; i < CConfig::MaxUSBMIDIDevices; i++) + { + assert (m_pMIDIKeyboard[i]); + m_pMIDIKeyboard[i]->Process (bPlugAndPlayUpdated); + } m_PCKeyboard.Process (bPlugAndPlayUpdated); diff --git a/src/minidexed.h b/src/minidexed.h index 779262d..5e82ebe 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -54,7 +54,7 @@ private: CUserInterface m_UI; CSysExFileLoader m_SysExFileLoader; - CMIDIKeyboard m_MIDIKeyboard; + CMIDIKeyboard *m_pMIDIKeyboard[CConfig::MaxUSBMIDIDevices]; CPCKeyboard m_PCKeyboard; CSerialMIDIDevice m_SerialMIDI; bool m_bUseSerial;