From 52ebc436713bd9320953d38dbc4aa6b30dbe8b5a Mon Sep 17 00:00:00 2001 From: Rene Stange Date: Fri, 18 Mar 2022 16:40:45 +0100 Subject: [PATCH] Initial support for multiple Dexed instances * Currently 2 similar instances, which work with the same parameters * Only 1 instance with max. 8 notes polyphony on RPi 1 * Chunk size needs to be increased on RPi 1 --- src/config.h | 6 ++ src/minidexed.cpp | 132 +++++++++++++++++++++++++++++++++++++++--- src/minidexed.h | 17 +++++- src/userinterface.cpp | 9 +-- 4 files changed, 147 insertions(+), 17 deletions(-) diff --git a/src/config.h b/src/config.h index 1846743..70ff2d6 100644 --- a/src/config.h +++ b/src/config.h @@ -30,7 +30,13 @@ class CConfig // Configuration for MiniDexed { public: +#if RASPPI == 1 + static const unsigned ToneGenerators = 1; + static const unsigned MaxNotes = 8; // polyphony +#else + static const unsigned ToneGenerators = 2; static const unsigned MaxNotes = 16; // polyphony +#endif #if RASPPI <= 3 static const unsigned MaxUSBMIDIDevices = 2; diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 4e4d8cf..98b649f 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -31,7 +31,7 @@ LOGMODULE ("minidexed"); CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, CGPIOManager *pGPIOManager, CI2CMaster *pI2CMaster) -: CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ()), +: #ifdef ARM_ALLOW_MULTI_CORE CMultiCoreSupport (CMemorySystem::Get ()), #endif @@ -45,6 +45,16 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, 1000000U * pConfig->GetChunkSize ()/2 / pConfig->GetSampleRate ()), m_bProfileEnabled (m_pConfig->GetProfileEnabled ()) { + assert (m_pConfig); + + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + m_pTG[i] = new CDexedAdapter (CConfig::MaxNotes, pConfig->GetSampleRate ()); + assert (m_pTG[i]); + + m_pTG[i]->activate (); + } + for (unsigned i = 0; i < CConfig::MaxUSBMIDIDevices; i++) { m_pMIDIKeyboard[i] = new CMIDIKeyboard (this, pConfig, i); @@ -96,14 +106,18 @@ bool CMiniDexed::Initialize (void) m_bUseSerial = true; } - activate (); - SetVolume (100); ProgramChange (0); - setTranspose (24); - setPBController (12, 1); - setMWController (99, 7, 0); + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + + m_pTG[i]->setTranspose (24); + + m_pTG[i]->setPBController (12, 1); + m_pTG[i]->setMWController (99, 7, 0); + } // setup and start the sound device if (!m_pSoundDevice->AllocateQueueFrames (m_pConfig->GetChunkSize ())) @@ -198,7 +212,11 @@ void CMiniDexed::ProgramChange (unsigned nProgram) uint8_t Buffer[156]; m_SysExFileLoader.GetVoice (nProgram, Buffer); - loadVoiceParameters (Buffer); + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->loadVoiceParameters (Buffer); + } m_UI.ProgramChanged (nProgram); } @@ -210,11 +228,81 @@ void CMiniDexed::SetVolume (unsigned nVolume) return; } - setGain (nVolume / 127.0); + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->setGain (nVolume / 127.0); + } m_UI.VolumeChanged (nVolume); } +void CMiniDexed::keyup (int16_t pitch) +{ + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->keyup (pitch); + } +} + +void CMiniDexed::keydown (int16_t pitch, uint8_t velocity) +{ + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->keydown (pitch, velocity); + } +} + +void CMiniDexed::setSustain(bool sustain) +{ + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->setSustain (sustain); + } +} + +void CMiniDexed::setModWheel (uint8_t value) +{ + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->setModWheel (value); + } +} + +void CMiniDexed::setPitchbend (int16_t value) +{ + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->setPitchbend (value); + } +} + +void CMiniDexed::ControllersRefresh (void) +{ + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + assert (m_pTG[i]); + m_pTG[i]->ControllersRefresh (); + } +} + +std::string CMiniDexed::GetVoiceName (unsigned nTG) +{ + char VoiceName[11]; + memset (VoiceName, 0, sizeof VoiceName); + assert (m_pTG[nTG]); + m_pTG[nTG]->setName (VoiceName); + + std::string Result (VoiceName); + + return Result; +} + void CMiniDexed::ProcessSound (void) { assert (m_pSoundDevice); @@ -228,7 +316,33 @@ void CMiniDexed::ProcessSound (void) } int16_t SampleBuffer[nFrames]; - getSamples (nFrames, SampleBuffer); + +#if RASPPI > 1 + for (unsigned i = 0; i < CConfig::ToneGenerators; i++) + { + int16_t TempBuffer[nFrames]; + + assert (m_pTG[i]); + m_pTG[i]->getSamples (nFrames, TempBuffer); + + if (i == 0) + { + for (unsigned j = 0; j < nFrames; j++) + { + SampleBuffer[j] = TempBuffer[j] / CConfig::ToneGenerators; + } + } + else + { + for (unsigned j = 0; j < nFrames; j++) + { + SampleBuffer[j] += TempBuffer[j] / CConfig::ToneGenerators; + } + } + } +#else + m_pTG[0]->getSamples (nFrames, SampleBuffer); +#endif if ( m_pSoundDevice->Write (SampleBuffer, sizeof SampleBuffer) != (int) sizeof SampleBuffer) diff --git a/src/minidexed.h b/src/minidexed.h index 17ca610..508f6ab 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -29,6 +29,7 @@ #include "serialmididevice.h" #include "perftimer.h" #include +#include #include #include #include @@ -36,9 +37,9 @@ #include #include -class CMiniDexed : public CDexedAdapter +class CMiniDexed #ifdef ARM_ALLOW_MULTI_CORE - , public CMultiCoreSupport +: public CMultiCoreSupport #endif { public: @@ -59,12 +60,24 @@ public: void ProgramChange (unsigned nProgram); void SetVolume (unsigned nVolume); + void keyup (int16_t pitch); + void keydown (int16_t pitch, uint8_t velocity); + + void setSustain (bool sustain); + void setModWheel (uint8_t value); + void setPitchbend (int16_t value); + void ControllersRefresh (void); + + std::string GetVoiceName (unsigned nTG = 0); + private: void ProcessSound (void); private: CConfig *m_pConfig; + CDexedAdapter *m_pTG[CConfig::ToneGenerators]; + CUserInterface m_UI; CSysExFileLoader m_SysExFileLoader; diff --git a/src/userinterface.cpp b/src/userinterface.cpp index 6f573e2..f3b79f4 100644 --- a/src/userinterface.cpp +++ b/src/userinterface.cpp @@ -135,20 +135,17 @@ void CUserInterface::ProgramChanged (unsigned nProgram) nProgram++; // MIDI numbering starts with 0, user interface with 1 - // fetch program name from Dexed instance - char ProgramName[11]; - memset (ProgramName, 0, sizeof ProgramName); assert (m_pMiniDexed); - m_pMiniDexed->setName (ProgramName); + std::string VoiceName = m_pMiniDexed->GetVoiceName (); - printf ("Loading voice %u: \"%s\"\n", nProgram, ProgramName); + printf ("Loading voice %u: \"%s\"\n", nProgram, VoiceName.c_str ()); if (m_UIMode == UIModeVoiceSelect) { CString String; String.Format ("%u", nProgram); - DisplayWrite (String, "VOICE", ProgramName); + DisplayWrite (String, "VOICE", VoiceName.c_str ()); } }