From 76c4f32f9ef26bd60c1d91a59b351bafbc2c55ea Mon Sep 17 00:00:00 2001 From: Kevin <68612569+diyelectromusic@users.noreply.github.com> Date: Thu, 27 Mar 2025 22:01:57 +0000 Subject: [PATCH] Simple implementation of MIDI CC 11 (Expression) as a live, MIDI only, multiplier for channel volume. --- src/mididevice.cpp | 11 ++++++++--- src/minidexed.cpp | 21 ++++++++++++++++++++- src/minidexed.h | 2 ++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 216b466..40a3a75 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -37,14 +37,15 @@ LOGMODULE ("mididevice"); #define MIDI_CHANNEL_AFTERTOUCH 0b1101 // right now Synth_Dexed just manage Channel Aftertouch not Polyphonic AT -> 0b1010 #define MIDI_CONTROL_CHANGE 0b1011 #define MIDI_CC_BANK_SELECT_MSB 0 - #define MIDI_CC_MODULATION 1 + #define MIDI_CC_MODULATION 1 #define MIDI_CC_BREATH_CONTROLLER 2 #define MIDI_CC_FOOT_PEDAL 4 - #define MIDI_CC_VOLUME 7 + #define MIDI_CC_VOLUME 7 #define MIDI_CC_PAN_POSITION 10 + #define MIDI_CC_EXPRESSION 11 #define MIDI_CC_BANK_SELECT_LSB 32 #define MIDI_CC_BANK_SUSTAIN 64 - #define MIDI_CC_RESONANCE 71 + #define MIDI_CC_RESONANCE 71 #define MIDI_CC_FREQUENCY_CUTOFF 74 #define MIDI_CC_REVERB_LEVEL 91 #define MIDI_CC_DETUNE_LEVEL 94 @@ -398,6 +399,10 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign m_pSynthesizer->SetPan (pMessage[2], nTG); break; + case MIDI_CC_EXPRESSION: + m_pSynthesizer->SetExpression (pMessage[2], nTG); + break; + case MIDI_CC_BANK_SELECT_MSB: m_pSynthesizer->BankSelectMSB (pMessage[2], nTG); break; diff --git a/src/minidexed.cpp b/src/minidexed.cpp index a485981..4d9a53c 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -72,6 +72,7 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, m_nVoiceBankIDMSB[i] = 0; m_nProgram[i] = 0; m_nVolume[i] = 100; + m_nExpression[i] = 127; m_nPan[i] = 64; m_nMasterTune[i] = 0; m_nCutoff[i] = 99; @@ -280,6 +281,7 @@ bool CMiniDexed::Initialize (void) assert (m_pTG[i]); SetVolume (100, i); + SetExpression (127, i); ProgramChange (0, i); m_pTG[i]->setTranspose (24); @@ -648,11 +650,28 @@ void CMiniDexed::SetVolume (unsigned nVolume, unsigned nTG) m_nVolume[nTG] = nVolume; assert (m_pTG[nTG]); - m_pTG[nTG]->setGain (nVolume / 127.0f); + m_pTG[nTG]->setGain ((m_nVolume[nTG] * m_nExpression[nTG]) / (127.0f * 127.0f)); m_UI.ParameterChanged (); } +void CMiniDexed::SetExpression (unsigned nExpression, unsigned nTG) +{ + nExpression=constrain((int)nExpression,0,127); + + assert (nTG < CConfig::AllToneGenerators); + if (nTG >= m_nToneGenerators) return; // Not an active TG + + m_nExpression[nTG] = nExpression; + + assert (m_pTG[nTG]); + m_pTG[nTG]->setGain ((m_nVolume[nTG] * m_nExpression[nTG]) / (127.0f * 127.0f)); + + // Expression is a "live performance" parameter only set + // via MIDI and not via the UI. + //m_UI.ParameterChanged (); +} + void CMiniDexed::SetPan (unsigned nPan, unsigned nTG) { nPan=constrain((int)nPan,0,127); diff --git a/src/minidexed.h b/src/minidexed.h index bb6290b..6a7ef81 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -74,6 +74,7 @@ public: void ProgramChange (unsigned nProgram, unsigned nTG); void ProgramChangePerformance (unsigned nProgram); void SetVolume (unsigned nVolume, unsigned nTG); + void SetExpression (unsigned nExpression, unsigned nTG); void SetPan (unsigned nPan, unsigned nTG); // 0 .. 127 void SetMasterTune (int nMasterTune, unsigned nTG); // -99 .. 99 void SetCutoff (int nCutoff, unsigned nTG); // 0 .. 99 @@ -261,6 +262,7 @@ private: unsigned m_nVoiceBankIDMSBPerformance; unsigned m_nProgram[CConfig::AllToneGenerators]; unsigned m_nVolume[CConfig::AllToneGenerators]; + unsigned m_nExpression[CConfig::AllToneGenerators]; unsigned m_nPan[CConfig::AllToneGenerators]; int m_nMasterTune[CConfig::AllToneGenerators]; int m_nCutoff[CConfig::AllToneGenerators];