Support TG select in UI

* Active TG number is shown on LCD display
* Next TG is selected by double click
* MIDI receive and PC keyboard are still in omni mode
pull/50/head
Rene Stange 3 years ago
parent 8789dca1ec
commit ff69fdc395
  1. 47
      src/mididevice.cpp
  2. 106
      src/minidexed.cpp
  3. 20
      src/minidexed.h
  4. 11
      src/pckeyboard.cpp
  5. 70
      src/userinterface.cpp
  6. 13
      src/userinterface.h

@ -107,12 +107,18 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
{ {
if (ucVelocity <= 127) if (ucVelocity <= 127)
{ {
m_pSynthesizer->keydown (ucKeyNumber, ucVelocity); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->keydown (ucKeyNumber, ucVelocity, nTG);
}
} }
} }
else else
{ {
m_pSynthesizer->keyup (ucKeyNumber); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->keyup (ucKeyNumber, nTG);
}
} }
break; break;
@ -122,7 +128,10 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
break; break;
} }
m_pSynthesizer->keyup (ucKeyNumber); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->keyup (ucKeyNumber, nTG);
}
break; break;
case MIDI_CONTROL_CHANGE: case MIDI_CONTROL_CHANGE:
@ -134,26 +143,41 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
switch (pMessage[1]) switch (pMessage[1])
{ {
case MIDI_CC_MODULATION: case MIDI_CC_MODULATION:
m_pSynthesizer->setModWheel (pMessage[2]); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
m_pSynthesizer->ControllersRefresh (); {
m_pSynthesizer->setModWheel (pMessage[2], nTG);
m_pSynthesizer->ControllersRefresh (nTG);
}
break; break;
case MIDI_CC_VOLUME: case MIDI_CC_VOLUME:
m_pSynthesizer->SetVolume (pMessage[2]); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->SetVolume (pMessage[2], nTG);
}
break; break;
case MIDI_CC_BANK_SELECT_LSB: case MIDI_CC_BANK_SELECT_LSB:
m_pSynthesizer->BankSelectLSB (pMessage[2]); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->BankSelectLSB (pMessage[2], nTG);
}
break; break;
case MIDI_CC_BANK_SUSTAIN: case MIDI_CC_BANK_SUSTAIN:
m_pSynthesizer->setSustain (pMessage[2] >= 64); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->setSustain (pMessage[2] >= 64, nTG);
}
break; break;
} }
break; break;
case MIDI_PROGRAM_CHANGE: case MIDI_PROGRAM_CHANGE:
m_pSynthesizer->ProgramChange (pMessage[1]); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->ProgramChange (pMessage[1], nTG);
}
break; break;
case MIDI_PITCH_BEND: { case MIDI_PITCH_BEND: {
@ -166,7 +190,10 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
nValue |= (s16) pMessage[2] << 7; nValue |= (s16) pMessage[2] << 7;
nValue -= 0x2000; nValue -= 0x2000;
m_pSynthesizer->setPitchbend (nValue); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_pSynthesizer->setPitchbend (nValue, nTG);
}
} break; } break;
default: default:

@ -115,13 +115,13 @@ bool CMiniDexed::Initialize (void)
m_bUseSerial = true; m_bUseSerial = true;
} }
SetVolume (100);
ProgramChange (0);
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) for (unsigned i = 0; i < CConfig::ToneGenerators; i++)
{ {
assert (m_pTG[i]); assert (m_pTG[i]);
SetVolume (100, i);
ProgramChange (0, i);
m_pTG[i]->setTranspose (24); m_pTG[i]->setTranspose (24);
m_pTG[i]->setPBController (12, 1); m_pTG[i]->setPBController (12, 1);
@ -245,114 +245,98 @@ CSysExFileLoader *CMiniDexed::GetSysExFileLoader (void)
return &m_SysExFileLoader; return &m_SysExFileLoader;
} }
void CMiniDexed::BankSelectLSB (unsigned nBankLSB) void CMiniDexed::BankSelectLSB (unsigned nBankLSB, unsigned nTG)
{ {
if (nBankLSB > 127) if (nBankLSB > 127)
{ {
return; return;
} }
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ m_nVoiceBankID[nTG] = nBankLSB;
m_nVoiceBankID[i] = nBankLSB;
}
m_UI.BankSelected (nBankLSB); m_UI.BankSelected (nBankLSB, nTG);
} }
void CMiniDexed::ProgramChange (unsigned nProgram) void CMiniDexed::ProgramChange (unsigned nProgram, unsigned nTG)
{ {
if (nProgram > 31) if (nProgram > 31)
{ {
return; return;
} }
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ uint8_t Buffer[156];
uint8_t Buffer[156]; m_SysExFileLoader.GetVoice (m_nVoiceBankID[nTG], nProgram, Buffer);
m_SysExFileLoader.GetVoice (m_nVoiceBankID[i], nProgram, Buffer);
assert (m_pTG[i]); assert (m_pTG[nTG]);
m_pTG[i]->loadVoiceParameters (Buffer); m_pTG[nTG]->loadVoiceParameters (Buffer);
}
m_UI.ProgramChanged (nProgram); m_UI.ProgramChanged (nProgram, nTG);
} }
void CMiniDexed::SetVolume (unsigned nVolume) void CMiniDexed::SetVolume (unsigned nVolume, unsigned nTG)
{ {
if (nVolume > 127) if (nVolume > 127)
{ {
return; return;
} }
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->setGain (nVolume / 127.0);
m_pTG[i]->setGain (nVolume / 127.0);
}
m_UI.VolumeChanged (nVolume); m_UI.VolumeChanged (nVolume, nTG);
} }
void CMiniDexed::keyup (int16_t pitch) void CMiniDexed::keyup (int16_t pitch, unsigned nTG)
{ {
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->keyup (pitch);
m_pTG[i]->keyup (pitch);
}
} }
void CMiniDexed::keydown (int16_t pitch, uint8_t velocity) void CMiniDexed::keydown (int16_t pitch, uint8_t velocity, unsigned nTG)
{ {
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->keydown (pitch, velocity);
m_pTG[i]->keydown (pitch, velocity);
}
} }
void CMiniDexed::setSustain(bool sustain) void CMiniDexed::setSustain(bool sustain, unsigned nTG)
{ {
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->setSustain (sustain);
m_pTG[i]->setSustain (sustain);
}
} }
void CMiniDexed::setModWheel (uint8_t value) void CMiniDexed::setModWheel (uint8_t value, unsigned nTG)
{ {
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->setModWheel (value);
m_pTG[i]->setModWheel (value);
}
} }
void CMiniDexed::setPitchbend (int16_t value) void CMiniDexed::setPitchbend (int16_t value, unsigned nTG)
{ {
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->setPitchbend (value);
m_pTG[i]->setPitchbend (value);
}
} }
void CMiniDexed::ControllersRefresh (void) void CMiniDexed::ControllersRefresh (unsigned nTG)
{ {
for (unsigned i = 0; i < CConfig::ToneGenerators; i++) assert (nTG < CConfig::ToneGenerators);
{ assert (m_pTG[nTG]);
assert (m_pTG[i]); m_pTG[nTG]->ControllersRefresh ();
m_pTG[i]->ControllersRefresh ();
}
} }
std::string CMiniDexed::GetVoiceName (unsigned nTG) std::string CMiniDexed::GetVoiceName (unsigned nTG)
{ {
char VoiceName[11]; char VoiceName[11];
memset (VoiceName, 0, sizeof VoiceName); memset (VoiceName, 0, sizeof VoiceName);
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]); assert (m_pTG[nTG]);
m_pTG[nTG]->setName (VoiceName); m_pTG[nTG]->setName (VoiceName);

@ -56,19 +56,19 @@ public:
CSysExFileLoader *GetSysExFileLoader (void); CSysExFileLoader *GetSysExFileLoader (void);
void BankSelectLSB (unsigned nBankLSB); void BankSelectLSB (unsigned nBankLSB, unsigned nTG);
void ProgramChange (unsigned nProgram); void ProgramChange (unsigned nProgram, unsigned nTG);
void SetVolume (unsigned nVolume); void SetVolume (unsigned nVolume, unsigned nTG);
void keyup (int16_t pitch); void keyup (int16_t pitch, unsigned nTG);
void keydown (int16_t pitch, uint8_t velocity); void keydown (int16_t pitch, uint8_t velocity, unsigned nTG);
void setSustain (bool sustain); void setSustain (bool sustain, unsigned nTG);
void setModWheel (uint8_t value); void setModWheel (uint8_t value, unsigned nTG);
void setPitchbend (int16_t value); void setPitchbend (int16_t value, unsigned nTG);
void ControllersRefresh (void); void ControllersRefresh (unsigned nTG);
std::string GetVoiceName (unsigned nTG = 0); std::string GetVoiceName (unsigned nTG);
private: private:
void ProcessSound (void); void ProcessSound (void);

@ -19,6 +19,7 @@
// //
#include "pckeyboard.h" #include "pckeyboard.h"
#include "minidexed.h" #include "minidexed.h"
#include "config.h"
#include <circle/devicenameservice.h> #include <circle/devicenameservice.h>
#include <circle/util.h> #include <circle/util.h>
#include <assert.h> #include <assert.h>
@ -112,7 +113,10 @@ void CPCKeyboard::KeyStatusHandlerRaw (unsigned char ucModifiers, const unsigned
u8 ucKeyNumber = GetKeyNumber (ucKeyCode); u8 ucKeyNumber = GetKeyNumber (ucKeyCode);
if (ucKeyNumber != 0) if (ucKeyNumber != 0)
{ {
s_pThis->m_pSynthesizer->keyup (ucKeyNumber); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
s_pThis->m_pSynthesizer->keyup (ucKeyNumber, nTG);
}
} }
} }
} }
@ -127,7 +131,10 @@ void CPCKeyboard::KeyStatusHandlerRaw (unsigned char ucModifiers, const unsigned
u8 ucKeyNumber = GetKeyNumber (ucKeyCode); u8 ucKeyNumber = GetKeyNumber (ucKeyCode);
if (ucKeyNumber != 0) if (ucKeyNumber != 0)
{ {
s_pThis->m_pSynthesizer->keydown (ucKeyNumber, 100); for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
s_pThis->m_pSynthesizer->keydown (ucKeyNumber, 100, nTG);
}
} }
} }
} }

@ -37,10 +37,14 @@ CUserInterface::CUserInterface (CMiniDexed *pMiniDexed, CGPIOManager *pGPIOManag
m_pLCDBuffered (0), m_pLCDBuffered (0),
m_pRotaryEncoder (0), m_pRotaryEncoder (0),
m_UIMode (UIModeVoiceSelect), m_UIMode (UIModeVoiceSelect),
m_nBank (0), m_nTG (0)
m_nProgram (0),
m_nVolume (0)
{ {
for (unsigned nTG = 0; nTG < CConfig::ToneGenerators; nTG++)
{
m_nBank[nTG] = 0;
m_nProgram[nTG] = 0;
m_nVolume[nTG] = 0;
}
} }
CUserInterface::~CUserInterface (void) CUserInterface::~CUserInterface (void)
@ -108,10 +112,11 @@ void CUserInterface::Process (void)
} }
} }
void CUserInterface::BankSelected (unsigned nBankLSB) void CUserInterface::BankSelected (unsigned nBankLSB, unsigned nTG)
{ {
assert (nBankLSB < 128); assert (nBankLSB < 128);
m_nBank = nBankLSB; assert (nTG < CConfig::ToneGenerators);
m_nBank[nTG] = nBankLSB;
assert (m_pMiniDexed); assert (m_pMiniDexed);
std::string BankName = m_pMiniDexed->GetSysExFileLoader ()->GetBankName (nBankLSB); std::string BankName = m_pMiniDexed->GetSysExFileLoader ()->GetBankName (nBankLSB);
@ -119,48 +124,62 @@ void CUserInterface::BankSelected (unsigned nBankLSB)
// MIDI numbering starts with 0, user interface with 1 // MIDI numbering starts with 0, user interface with 1
printf ("Select voice bank %u: \"%s\"\n", nBankLSB+1, BankName.c_str ()); printf ("Select voice bank %u: \"%s\"\n", nBankLSB+1, BankName.c_str ());
if (m_UIMode == UIModeBankSelect) if ( m_UIMode == UIModeBankSelect
&& m_nTG == nTG)
{ {
CString TG;
TG.Format ("TG%u", nTG+1);
CString String; CString String;
String.Format ("%u", nBankLSB+1); String.Format ("%u", nBankLSB+1);
DisplayWrite (String, "BANK", BankName.c_str ()); DisplayWrite (TG, "BANK", String, BankName.c_str ());
} }
} }
void CUserInterface::ProgramChanged (unsigned nProgram) void CUserInterface::ProgramChanged (unsigned nProgram, unsigned nTG)
{ {
assert (nProgram < 128); assert (nProgram < 128);
m_nProgram = nProgram; assert (nTG < CConfig::ToneGenerators);
m_nProgram[nTG] = nProgram;
nProgram++; // MIDI numbering starts with 0, user interface with 1 nProgram++; // MIDI numbering starts with 0, user interface with 1
assert (m_pMiniDexed); assert (m_pMiniDexed);
std::string VoiceName = m_pMiniDexed->GetVoiceName (); std::string VoiceName = m_pMiniDexed->GetVoiceName (nTG);
printf ("Loading voice %u: \"%s\"\n", nProgram, VoiceName.c_str ()); printf ("Loading voice %u: \"%s\"\n", nProgram, VoiceName.c_str ());
if (m_UIMode == UIModeVoiceSelect) if ( m_UIMode == UIModeVoiceSelect
&& m_nTG == nTG)
{ {
CString TG;
TG.Format ("TG%u", nTG+1);
CString String; CString String;
String.Format ("%u", nProgram); String.Format ("%u", nProgram);
DisplayWrite (String, "VOICE", VoiceName.c_str ()); DisplayWrite (TG, "VOICE", String, VoiceName.c_str ());
} }
} }
void CUserInterface::VolumeChanged (unsigned nVolume) void CUserInterface::VolumeChanged (unsigned nVolume, unsigned nTG)
{ {
assert (nVolume < 128); assert (nVolume < 128);
m_nVolume = nVolume; assert (nTG < CConfig::ToneGenerators);
m_nVolume[nTG] = nVolume;
if (m_UIMode == UIModeVolume) if ( m_UIMode == UIModeVolume
&& m_nTG == nTG)
{ {
CString TG;
TG.Format ("TG%u", nTG+1);
char VolumeBar[CConfig::LCDColumns+1]; char VolumeBar[CConfig::LCDColumns+1];
memset (VolumeBar, 0xFF, sizeof VolumeBar); // 0xFF is the block character memset (VolumeBar, 0xFF, sizeof VolumeBar); // 0xFF is the block character
VolumeBar[nVolume * CConfig::LCDColumns / 127] = '\0'; VolumeBar[nVolume * CConfig::LCDColumns / 127] = '\0';
DisplayWrite ("", "VOLUME", VolumeBar); DisplayWrite (TG, "VOLUME", VolumeBar);
} }
} }
@ -235,6 +254,13 @@ void CUserInterface::EncoderEventHandler (CKY040::TEvent Event)
} }
break; break;
case CKY040::EventSwitchDoubleClick:
if (++m_nTG == CConfig::ToneGenerators)
{
m_nTG = 0;
}
break;
case CKY040::EventSwitchHold: case CKY040::EventSwitchHold:
if (m_pRotaryEncoder->GetHoldSeconds () >= 3) if (m_pRotaryEncoder->GetHoldSeconds () >= 3)
{ {
@ -251,23 +277,23 @@ void CUserInterface::EncoderEventHandler (CKY040::TEvent Event)
switch (m_UIMode) switch (m_UIMode)
{ {
case UIModeBankSelect: case UIModeBankSelect:
if (m_nBank + nStep < 128) if (m_nBank[m_nTG] + nStep < 128)
{ {
m_pMiniDexed->BankSelectLSB (m_nBank + nStep); m_pMiniDexed->BankSelectLSB (m_nBank[m_nTG] + nStep, m_nTG);
} }
break; break;
case UIModeVoiceSelect: case UIModeVoiceSelect:
if (m_nProgram + nStep < 32) if (m_nProgram[m_nTG] + nStep < 32)
{ {
m_pMiniDexed->ProgramChange (m_nProgram + nStep); m_pMiniDexed->ProgramChange (m_nProgram[m_nTG] + nStep, m_nTG);
} }
break; break;
case UIModeVolume: { case UIModeVolume: {
const int Increment = 128 / CConfig::LCDColumns; const int Increment = 128 / CConfig::LCDColumns;
int nVolume = m_nVolume + nStep*Increment; int nVolume = m_nVolume[m_nTG] + nStep*Increment;
if (nVolume < 0) if (nVolume < 0)
{ {
nVolume = 0; nVolume = 0;
@ -277,7 +303,7 @@ void CUserInterface::EncoderEventHandler (CKY040::TEvent Event)
nVolume = 127; nVolume = 127;
} }
m_pMiniDexed->SetVolume (nVolume); m_pMiniDexed->SetVolume (nVolume, m_nTG);
} break; } break;
default: default:

@ -38,9 +38,9 @@ public:
void Process (void); void Process (void);
void BankSelected (unsigned nBankLSB); // 0 .. 127 void BankSelected (unsigned nBankLSB, unsigned nTG); // 0 .. 127
void ProgramChanged (unsigned nProgram); // 0 .. 127 void ProgramChanged (unsigned nProgram, unsigned nTG); // 0 .. 127
void VolumeChanged (unsigned nVolume); // 0 .. 127 void VolumeChanged (unsigned nVolume, unsigned nTG); // 0 .. 127
private: private:
// Print to display in this format: // Print to display in this format:
@ -78,9 +78,10 @@ private:
TUIMode m_UIMode; TUIMode m_UIMode;
unsigned m_nBank; unsigned m_nTG;
unsigned m_nProgram; unsigned m_nBank[CConfig::ToneGenerators];
unsigned m_nVolume; unsigned m_nProgram[CConfig::ToneGenerators];
unsigned m_nVolume[CConfig::ToneGenerators];
}; };
#endif #endif

Loading…
Cancel
Save