Support multiple USB MIDI inputs at once

* Maximum 2 inputs on Raspberry Pi 1-3
* Maximum 4 inputs on Raspberry Pi 4
pull/37/head
Rene Stange 3 years ago
parent e65b4f6654
commit 33825f3f9e
  1. 6
      src/config.h
  2. 58
      src/midikeyboard.cpp
  3. 18
      src/midikeyboard.h
  4. 12
      src/minidexed.cpp
  5. 2
      src/minidexed.h

@ -32,6 +32,12 @@ class CConfig // Configuration for MiniDexed
public: public:
static const unsigned MaxNotes = 16; // polyphony 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 LCDColumns = 16; // HD44780 LCD
static const unsigned LCDRows = 2; static const unsigned LCDRows = 2;

@ -24,18 +24,31 @@
#include <circle/devicenameservice.h> #include <circle/devicenameservice.h>
#include <assert.h> #include <assert.h>
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), : CMIDIDevice (pSynthesizer, pConfig),
m_nInstance (nInstance),
m_pMIDIDevice (0) 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) CMIDIKeyboard::~CMIDIKeyboard (void)
{ {
s_pThis = 0; assert (m_nInstance < MaxInstances);
s_pThis[m_nInstance] = 0;
} }
void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated) void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated)
@ -48,24 +61,45 @@ void CMIDIKeyboard::Process (boolean bPlugAndPlayUpdated)
if (m_pMIDIDevice == 0) if (m_pMIDIDevice == 0)
{ {
m_pMIDIDevice = m_pMIDIDevice =
(CUSBMIDIDevice *) CDeviceNameService::Get ()->GetDevice ("umidi1", FALSE); (CUSBMIDIDevice *) CDeviceNameService::Get ()->GetDevice (m_DeviceName, FALSE);
if (m_pMIDIDevice != 0) 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); assert (s_pThis[0] != 0);
s_pThis->MIDIMessageHandler (pPacket, nLength, nCable); 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) void CMIDIKeyboard::DeviceRemovedHandler (CDevice *pDevice, void *pContext)
{ {
assert (s_pThis != 0); CMIDIKeyboard *pThis = static_cast<CMIDIKeyboard *> (pContext);
s_pThis->m_pMIDIDevice = 0; assert (pThis != 0);
pThis->m_pMIDIDevice = 0;
} }

@ -27,6 +27,7 @@
#include "config.h" #include "config.h"
#include <circle/usb/usbmidi.h> #include <circle/usb/usbmidi.h>
#include <circle/device.h> #include <circle/device.h>
#include <circle/string.h>
#include <circle/types.h> #include <circle/types.h>
class CMiniDexed; class CMiniDexed;
@ -34,20 +35,31 @@ class CMiniDexed;
class CMIDIKeyboard : public CMIDIDevice class CMIDIKeyboard : public CMIDIDevice
{ {
public: public:
CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig); static const unsigned MaxInstances = 4;
public:
CMIDIKeyboard (CMiniDexed *pSynthesizer, CConfig *pConfig, unsigned nInstance = 0);
~CMIDIKeyboard (void); ~CMIDIKeyboard (void);
void Process (boolean bPlugAndPlayUpdated); void Process (boolean bPlugAndPlayUpdated);
private: 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); static void DeviceRemovedHandler (CDevice *pDevice, void *pContext);
private: private:
unsigned m_nInstance;
CString m_DeviceName;
CUSBMIDIDevice * volatile m_pMIDIDevice; CUSBMIDIDevice * volatile m_pMIDIDevice;
static CMIDIKeyboard *s_pThis; static CMIDIKeyboard *s_pThis[MaxInstances];
static TMIDIPacketHandler * const s_pMIDIPacketHandler[MaxInstances];
}; };
#endif #endif

@ -28,7 +28,6 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt)
: CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ()), : CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ()),
m_pConfig (pConfig), m_pConfig (pConfig),
m_UI (this, pConfig), m_UI (this, pConfig),
m_MIDIKeyboard (this, pConfig),
m_PCKeyboard (this), m_PCKeyboard (this),
m_SerialMIDI (this, pInterrupt, pConfig), m_SerialMIDI (this, pInterrupt, pConfig),
m_bUseSerial (false), m_bUseSerial (false),
@ -36,6 +35,11 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt)
1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()), 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()),
m_bProfileEnabled (m_pConfig->GetProfileEnabled ()) 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) bool CMiniDexed::Initialize (void)
@ -64,7 +68,11 @@ bool CMiniDexed::Initialize (void)
void CMiniDexed::Process (bool bPlugAndPlayUpdated) 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); m_PCKeyboard.Process (bPlugAndPlayUpdated);

@ -54,7 +54,7 @@ private:
CUserInterface m_UI; CUserInterface m_UI;
CSysExFileLoader m_SysExFileLoader; CSysExFileLoader m_SysExFileLoader;
CMIDIKeyboard m_MIDIKeyboard; CMIDIKeyboard *m_pMIDIKeyboard[CConfig::MaxUSBMIDIDevices];
CPCKeyboard m_PCKeyboard; CPCKeyboard m_PCKeyboard;
CSerialMIDIDevice m_SerialMIDI; CSerialMIDIDevice m_SerialMIDI;
bool m_bUseSerial; bool m_bUseSerial;

Loading…
Cancel
Save