MIDI CC 11 (Expression) (#830)

* Simple implementation of MIDI CC 11 (Expression) as a live, MIDI only, multiplier for channel volume.

* Add config option for global MIDI CC Expression channel
main continuous
Kevin 2 days ago committed by GitHub
parent f546448371
commit 29bbce3472
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      src/config.cpp
  2. 2
      src/config.h
  3. 34
      src/mididevice.cpp
  4. 1
      src/mididevice.h
  5. 21
      src/minidexed.cpp
  6. 2
      src/minidexed.h

@ -112,6 +112,7 @@ void CConfig::Load (void)
m_nMIDISystemCCVol = m_Properties.GetNumber ("MIDISystemCCVol", 0);
m_nMIDISystemCCPan = m_Properties.GetNumber ("MIDISystemCCPan", 0);
m_nMIDISystemCCDetune = m_Properties.GetNumber ("MIDISystemCCDetune", 0);
m_nMIDIGlobalExpression = m_Properties.GetNumber ("MIDIGlobalExpression", 0);
m_bLCDEnabled = m_Properties.GetNumber ("LCDEnabled", 0) != 0;
m_nLCDPinEnable = m_Properties.GetNumber ("LCDPinEnable", 4);
@ -353,6 +354,11 @@ unsigned CConfig::GetMIDISystemCCDetune (void) const
return m_nMIDISystemCCDetune;
}
unsigned CConfig::GetMIDIGlobalExpression (void) const
{
return m_nMIDIGlobalExpression;
}
bool CConfig::GetLCDEnabled (void) const
{
return m_bLCDEnabled;

@ -131,6 +131,7 @@ public:
unsigned GetMIDISystemCCVol (void) const;
unsigned GetMIDISystemCCPan (void) const;
unsigned GetMIDISystemCCDetune (void) const;
unsigned GetMIDIGlobalExpression (void) const;
// HD44780 LCD
// GPIO pin numbers are chip numbers, not header positions
@ -267,6 +268,7 @@ private:
unsigned m_nMIDISystemCCVol;
unsigned m_nMIDISystemCCPan;
unsigned m_nMIDISystemCCDetune;
unsigned m_nMIDIGlobalExpression;
bool m_bLCDEnabled;
unsigned m_nLCDPinEnable;

@ -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
@ -94,6 +95,15 @@ CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInter
m_MIDISystemCCBitmap[2] = 0;
m_MIDISystemCCBitmap[3] = 0;
m_nMIDIGlobalExpression = m_pConfig->GetMIDIGlobalExpression();
// convert from config channels 1..16 to internal channels
if ((m_nMIDIGlobalExpression >= 1) && (m_nMIDIGlobalExpression <= 16)) {
m_nMIDIGlobalExpression = m_nMIDIGlobalExpression - 1;
} else {
// Either disabled or OMNI means disabled
m_nMIDIGlobalExpression = Disabled;
}
for (int tg=0; tg<8; tg++)
{
if (m_nMIDISystemCCVol != 0) {
@ -279,6 +289,17 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
}
}
}
if (m_nMIDIGlobalExpression != Disabled)
{
// Expression is global so check for expression MIDI channel
// NB: OMNI not supported
if (ucChannel == m_nMIDIGlobalExpression) {
// Send to all TGs regardless of their own channel
for (unsigned nTG = 0; nTG < m_pConfig->GetToneGenerators(); nTG++) {
m_pSynthesizer->SetExpression (pMessage[2], nTG);
}
}
}
if (nLength == 3)
{
m_pUI->UIMIDICmdHandler (ucChannel, ucStatus & 0xF0, pMessage[1], pMessage[2]);
@ -398,6 +419,13 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
m_pSynthesizer->SetPan (pMessage[2], nTG);
break;
case MIDI_CC_EXPRESSION:
if (m_nMIDIGlobalExpression == Disabled) {
// Expression is per channel only
m_pSynthesizer->SetExpression (pMessage[2], nTG);
}
break;
case MIDI_CC_BANK_SELECT_MSB:
m_pSynthesizer->BankSelectMSB (pMessage[2], nTG);
break;

@ -75,6 +75,7 @@ private:
unsigned m_nMIDISystemCCPan;
unsigned m_nMIDISystemCCDetune;
u32 m_MIDISystemCCBitmap[4]; // to allow for 128 bit entries
unsigned m_nMIDIGlobalExpression;
std::string m_DeviceName;

@ -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);

@ -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];

Loading…
Cancel
Save