Switchable performance files improvements + Poly/Mono + Fix to #298 and #83 issues (#267)

pull/311/head^2
arsamus 2 years ago committed by GitHub
parent 768d763f73
commit aa5a7c7450
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/config.cpp
  2. 4
      src/config.h
  3. 19
      src/mididevice.cpp
  4. 361
      src/minidexed.cpp
  5. 54
      src/minidexed.h
  6. 3
      src/minidexed.ini
  7. 81
      src/performance.ini
  8. 233
      src/performanceconfig.cpp
  9. 40
      src/performanceconfig.h
  10. 3
      src/serialmididevice.cpp
  11. 424
      src/uimenu.cpp
  12. 19
      src/uimenu.h
  13. 2
      src/userinterface.cpp

@ -110,6 +110,7 @@ void CConfig::Load (void)
m_bMIDIDumpEnabled = m_Properties.GetNumber ("MIDIDumpEnabled", 0) != 0;
m_bProfileEnabled = m_Properties.GetNumber ("ProfileEnabled", 0) != 0;
m_bPerformanceSelectToLoad = m_Properties.GetNumber ("PerformanceSelectToLoad", 1) != 0;
}
const char *CConfig::GetSoundDevice (void) const
@ -316,3 +317,8 @@ bool CConfig::GetProfileEnabled (void) const
{
return m_bProfileEnabled;
}
bool CConfig::GetPerformanceSelectToLoad (void) const
{
return m_bPerformanceSelectToLoad;
}

@ -127,6 +127,9 @@ public:
bool GetMIDIDumpEnabled (void) const;
bool GetProfileEnabled (void) const;
// Load performance mode. 0 for load just rotating encoder, 1 load just when Select is pushed
bool GetPerformanceSelectToLoad (void) const;
private:
CPropertiesFatFsFile m_Properties;
@ -180,6 +183,7 @@ private:
bool m_bMIDIDumpEnabled;
bool m_bProfileEnabled;
bool m_bPerformanceSelectToLoad;
};
#endif

@ -33,9 +33,12 @@ LOGMODULE ("mididevice");
#define MIDI_NOTE_OFF 0b1000
#define MIDI_NOTE_ON 0b1001
#define MIDI_AFTERTOUCH 0b1010 // TODO
#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 // TODO
#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_PAN_POSITION 10
#define MIDI_CC_BANK_SELECT_LSB 32
@ -226,6 +229,12 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
m_pSynthesizer->keyup (pMessage[1], nTG);
break;
case MIDI_CHANNEL_AFTERTOUCH:
m_pSynthesizer->setAftertouch (pMessage[1], nTG);
m_pSynthesizer->ControllersRefresh (nTG);
break;
case MIDI_CONTROL_CHANGE:
if (nLength < 3)
{
@ -239,6 +248,16 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
m_pSynthesizer->ControllersRefresh (nTG);
break;
case MIDI_CC_FOOT_PEDAL:
m_pSynthesizer->setFootController (pMessage[2], nTG);
m_pSynthesizer->ControllersRefresh (nTG);
break;
case MIDI_CC_BREATH_CONTROLLER:
m_pSynthesizer->setBreathController (pMessage[2], nTG);
m_pSynthesizer->ControllersRefresh (nTG);
break;
case MIDI_CC_VOLUME:
m_pSynthesizer->SetVolume (pMessage[2], nTG);
break;

@ -52,7 +52,9 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
m_bProfileEnabled (m_pConfig->GetProfileEnabled ()),
m_bSavePerformance (false),
m_bSavePerformanceNewFile (false),
m_bSetNewPerformance (false)
m_bSetNewPerformance (false),
m_bDeletePerformance (false),
m_bLoadPerformanceBusy(false)
{
assert (m_pConfig);
@ -71,11 +73,20 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
m_nPortamentoMode[i] = 0;
m_nPortamentoGlissando[i] = 0;
m_nPortamentoTime[i] = 0;
m_bMonoMode[i]=0;
m_nNoteLimitLow[i] = 0;
m_nNoteLimitHigh[i] = 127;
m_nNoteShift[i] = 0;
m_nModulationWheelRange[i]=99;
m_nModulationWheelTarget[i]=7;
m_nFootControlRange[i]=99;
m_nFootControlTarget[i]=0;
m_nBreathControlRange[i]=99;
m_nBreathControlTarget[i]=0;
m_nAftertouchRange[i]=99;
m_nAftertouchTarget[i]=0;
m_nReverbSend[i] = 0;
m_uchOPMask[i] = 0b111111; // All operators on
@ -177,7 +188,11 @@ bool CMiniDexed::Initialize (void)
m_pTG[i]->setTranspose (24);
m_pTG[i]->setPBController (2, 0);
m_pTG[i]->setMWController (99, 7, 0);
m_pTG[i]->setMWController (99, 1, 0);
m_pTG[i]->setFCController (99, 1, 0);
m_pTG[i]->setBCController (99, 1, 0);
m_pTG[i]->setATController (99, 1, 0);
tg_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f));
tg_mixer->gain(i,1.0f);
@ -263,10 +278,20 @@ void CMiniDexed::Process (bool bPlugAndPlayUpdated)
m_bSavePerformanceNewFile = false;
}
if (m_bSetNewPerformance)
if (m_bSetNewPerformance && !m_bLoadPerformanceBusy)
{
DoSetNewPerformance ();
m_bSetNewPerformance = false;
if (m_nSetNewPerformanceID == GetActualPerformanceID())
{
m_bSetNewPerformance = false;
}
}
if(m_bDeletePerformance)
{
DoDeletePerformance ();
m_bDeletePerformance = false;
}
if (m_bProfileEnabled)
@ -559,6 +584,28 @@ void CMiniDexed::setModWheel (uint8_t value, unsigned nTG)
m_pTG[nTG]->setModWheel (value);
}
void CMiniDexed::setFootController (uint8_t value, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setFootController (value);
}
void CMiniDexed::setBreathController (uint8_t value, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setBreathController (value);
}
void CMiniDexed::setAftertouch (uint8_t value, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setAftertouch (value);
}
void CMiniDexed::setPitchbend (int16_t value, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
@ -669,6 +716,27 @@ void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nT
case TGParameterPortamentoMode: setPortamentoMode (nValue, nTG); break;
case TGParameterPortamentoGlissando: setPortamentoGlissando (nValue, nTG); break;
case TGParameterPortamentoTime: setPortamentoTime (nValue, nTG); break;
case TGParameterMonoMode: setMonoMode (nValue , nTG); break;
case TGParameterMWRange: setModController(0, 0, nValue, nTG); break;
case TGParameterMWPitch: setModController(0, 1, nValue, nTG); break;
case TGParameterMWAmplitude: setModController(0, 2, nValue, nTG); break;
case TGParameterMWEGBias: setModController(0, 3, nValue, nTG); break;
case TGParameterFCRange: setModController(1, 0, nValue, nTG); break;
case TGParameterFCPitch: setModController(1, 1, nValue, nTG); break;
case TGParameterFCAmplitude: setModController(1, 2, nValue, nTG); break;
case TGParameterFCEGBias: setModController(1, 3, nValue, nTG); break;
case TGParameterBCRange: setModController(2, 0, nValue, nTG); break;
case TGParameterBCPitch: setModController(2, 1, nValue, nTG); break;
case TGParameterBCAmplitude: setModController(2, 2, nValue, nTG); break;
case TGParameterBCEGBias: setModController(2, 3, nValue, nTG); break;
case TGParameterATRange: setModController(3, 0, nValue, nTG); break;
case TGParameterATPitch: setModController(3, 1, nValue, nTG); break;
case TGParameterATAmplitude: setModController(3, 2, nValue, nTG); break;
case TGParameterATEGBias: setModController(3, 3, nValue, nTG); break;
case TGParameterMIDIChannel:
assert (0 <= nValue && nValue <= 255);
@ -703,6 +771,28 @@ int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG)
case TGParameterPortamentoMode: return m_nPortamentoMode[nTG];
case TGParameterPortamentoGlissando: return m_nPortamentoGlissando[nTG];
case TGParameterPortamentoTime: return m_nPortamentoTime[nTG];
case TGParameterMonoMode: return m_bMonoMode[nTG] ? 1 : 0;
case TGParameterMWRange: return getModController(0, 0, nTG);
case TGParameterMWPitch: return getModController(0, 1, nTG);
case TGParameterMWAmplitude: return getModController(0, 2, nTG);
case TGParameterMWEGBias: return getModController(0, 3, nTG);
case TGParameterFCRange: return getModController(1, 0, nTG);
case TGParameterFCPitch: return getModController(1, 1, nTG);
case TGParameterFCAmplitude: return getModController(1, 2, nTG);
case TGParameterFCEGBias: return getModController(1, 3, nTG);
case TGParameterBCRange: return getModController(2, 0, nTG);
case TGParameterBCPitch: return getModController(2, 1, nTG);
case TGParameterBCAmplitude: return getModController(2, 2, nTG);
case TGParameterBCEGBias: return getModController(2, 3, nTG);
case TGParameterATRange: return getModController(3, 0, nTG);
case TGParameterATPitch: return getModController(3, 1, nTG);
case TGParameterATAmplitude: return getModController(3, 2, nTG);
case TGParameterATEGBias: return getModController(3, 3, nTG);
default:
assert (0);
@ -946,9 +1036,10 @@ void CMiniDexed::ProcessSound (void)
#endif
bool CMiniDexed::SavePerformance (void)
bool CMiniDexed::SavePerformance (bool bSaveAsDeault)
{
m_bSavePerformance = true;
m_bSaveAsDeault=bSaveAsDeault;
return true;
}
@ -976,6 +1067,16 @@ bool CMiniDexed::DoSavePerformance (void)
m_PerformanceConfig.SetNoteShift (m_nNoteShift[nTG], nTG);
m_pTG[nTG]->getVoiceData(m_nRawVoiceData);
m_PerformanceConfig.SetVoiceDataToTxt (m_nRawVoiceData, nTG);
m_PerformanceConfig.SetMonoMode (m_bMonoMode[nTG], nTG);
m_PerformanceConfig.SetModulationWheelRange (m_nModulationWheelRange[nTG], nTG);
m_PerformanceConfig.SetModulationWheelTarget (m_nModulationWheelTarget[nTG], nTG);
m_PerformanceConfig.SetFootControlRange (m_nFootControlRange[nTG], nTG);
m_PerformanceConfig.SetFootControlTarget (m_nFootControlTarget[nTG], nTG);
m_PerformanceConfig.SetBreathControlRange (m_nBreathControlRange[nTG], nTG);
m_PerformanceConfig.SetBreathControlTarget (m_nBreathControlTarget[nTG], nTG);
m_PerformanceConfig.SetAftertouchRange (m_nAftertouchRange[nTG], nTG);
m_PerformanceConfig.SetAftertouchTarget (m_nAftertouchTarget[nTG], nTG);
m_PerformanceConfig.SetReverbSend (m_nReverbSend[nTG], nTG);
}
@ -989,6 +1090,11 @@ bool CMiniDexed::DoSavePerformance (void)
m_PerformanceConfig.SetReverbDiffusion (m_nParameter[ParameterReverbDiffusion]);
m_PerformanceConfig.SetReverbLevel (m_nParameter[ParameterReverbLevel]);
if(m_bSaveAsDeault)
{
m_PerformanceConfig.SetNewPerformance(0);
}
return m_PerformanceConfig.Save ();
}
@ -996,7 +1102,7 @@ void CMiniDexed::setMonoMode(uint8_t mono, uint8_t nTG)
{
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_bMonoMode[nTG]= mono != 0;
m_pTG[nTG]->setMonoMode(constrain(mono, 0, 1));
m_pTG[nTG]->doRefreshVoice();
m_UI.ParameterChanged ();
@ -1068,7 +1174,10 @@ void CMiniDexed::setModWheelRange(uint8_t range, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setModWheelRange(constrain(range, 0, 99));
m_nModulationWheelRange[nTG] = range;
m_pTG[nTG]->setMWController(range, m_pTG[nTG]->getModWheelTarget(), 0);
// m_pTG[nTG]->setModWheelRange(constrain(range, 0, 99)); replaces with the above due to wrong constrain on dexed_synth module.
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
}
@ -1078,6 +1187,8 @@ void CMiniDexed::setModWheelTarget(uint8_t target, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_nModulationWheelTarget[nTG] = target;
m_pTG[nTG]->setModWheelTarget(constrain(target, 0, 7));
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
@ -1088,7 +1199,10 @@ void CMiniDexed::setFootControllerRange(uint8_t range, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setFootControllerRange(constrain(range, 0, 99));
m_nFootControlRange[nTG]=range;
m_pTG[nTG]->setFCController(range, m_pTG[nTG]->getFootControllerTarget(), 0);
// m_pTG[nTG]->setFootControllerRange(constrain(range, 0, 99)); replaces with the above due to wrong constrain on dexed_synth module.
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
}
@ -1098,6 +1212,8 @@ void CMiniDexed::setFootControllerTarget(uint8_t target, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_nFootControlTarget[nTG] = target;
m_pTG[nTG]->setFootControllerTarget(constrain(target, 0, 7));
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
@ -1108,7 +1224,10 @@ void CMiniDexed::setBreathControllerRange(uint8_t range, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setBreathControllerRange(constrain(range, 0, 99));
m_nBreathControlRange[nTG]=range;
m_pTG[nTG]->setBCController(range, m_pTG[nTG]->getBreathControllerTarget(), 0);
//m_pTG[nTG]->setBreathControllerRange(constrain(range, 0, 99));
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
}
@ -1118,6 +1237,8 @@ void CMiniDexed::setBreathControllerTarget(uint8_t target, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_nBreathControlTarget[nTG]=target;
m_pTG[nTG]->setBreathControllerTarget(constrain(target, 0, 7));
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
@ -1128,7 +1249,10 @@ void CMiniDexed::setAftertouchRange(uint8_t range, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_pTG[nTG]->setAftertouchRange(constrain(range, 0, 99));
m_nAftertouchRange[nTG]=range;
m_pTG[nTG]->setATController(range, m_pTG[nTG]->getAftertouchTarget(), 0);
// m_pTG[nTG]->setAftertouchRange(constrain(range, 0, 99));
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
}
@ -1138,6 +1262,8 @@ void CMiniDexed::setAftertouchTarget(uint8_t target, uint8_t nTG)
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
m_nAftertouchTarget[nTG]=target;
m_pTG[nTG]->setAftertouchTarget(constrain(target, 0, 7));
m_pTG[nTG]->ControllersRefresh();
m_UI.ParameterChanged ();
@ -1244,17 +1370,6 @@ void CMiniDexed::SetActualPerformanceID(unsigned nID)
m_PerformanceConfig.SetActualPerformanceID(nID);
}
unsigned CMiniDexed::GetMenuSelectedPerformanceID()
{
return m_PerformanceConfig.GetMenuSelectedPerformanceID();
}
void CMiniDexed::SetMenuSelectedPerformanceID(unsigned nID)
{
m_PerformanceConfig.SetMenuSelectedPerformanceID(nID);
}
bool CMiniDexed::SetNewPerformance(unsigned nID)
{
m_bSetNewPerformance = true;
@ -1265,17 +1380,21 @@ bool CMiniDexed::SetNewPerformance(unsigned nID)
bool CMiniDexed::DoSetNewPerformance (void)
{
m_bLoadPerformanceBusy = true;
unsigned nID = m_nSetNewPerformanceID;
m_PerformanceConfig.SetNewPerformance(nID);
if (m_PerformanceConfig.Load ())
{
LoadPerformanceParameters();
m_bLoadPerformanceBusy = false;
return true;
}
else
{
SetMIDIChannel (CMIDIDevice::OmniMode, 0);
m_bLoadPerformanceBusy = false;
return false;
}
}
@ -1288,10 +1407,9 @@ bool CMiniDexed::SavePerformanceNewFile ()
bool CMiniDexed::DoSavePerformanceNewFile (void)
{
std::string nPerformanceName=""; // for future enhacements: capability to write performance name
if (m_PerformanceConfig.CreateNewPerformanceFile(nPerformanceName))
if (m_PerformanceConfig.CreateNewPerformanceFile())
{
if(SavePerformance())
if(SavePerformance(false))
{
return true;
}
@ -1336,9 +1454,19 @@ void CMiniDexed::LoadPerformanceParameters(void)
uint8_t* tVoiceData = m_PerformanceConfig.GetVoiceDataFromTxt(nTG);
m_pTG[nTG]->loadVoiceParameters(tVoiceData);
}
setMonoMode(m_PerformanceConfig.GetMonoMode(nTG) ? 1 : 0, nTG);
SetReverbSend (m_PerformanceConfig.GetReverbSend (nTG), nTG);
setModWheelRange (m_PerformanceConfig.GetModulationWheelRange (nTG), nTG);
setModWheelTarget (m_PerformanceConfig.GetModulationWheelTarget (nTG), nTG);
setFootControllerRange (m_PerformanceConfig.GetFootControlRange (nTG), nTG);
setFootControllerTarget (m_PerformanceConfig.GetFootControlTarget (nTG), nTG);
setBreathControllerRange (m_PerformanceConfig.GetBreathControlRange (nTG), nTG);
setBreathControllerTarget (m_PerformanceConfig.GetBreathControlTarget (nTG), nTG);
setAftertouchRange (m_PerformanceConfig.GetAftertouchRange (nTG), nTG);
setAftertouchTarget (m_PerformanceConfig.GetAftertouchTarget (nTG), nTG);
}
// Effects
@ -1352,3 +1480,184 @@ void CMiniDexed::LoadPerformanceParameters(void)
SetParameter (ParameterReverbLevel, m_PerformanceConfig.GetReverbLevel ());
}
std::string CMiniDexed::GetNewPerformanceDefaultName(void)
{
return m_PerformanceConfig.GetNewPerformanceDefaultName();
}
void CMiniDexed::SetNewPerformanceName(std::string nName)
{
m_PerformanceConfig.SetNewPerformanceName(nName);
}
void CMiniDexed::SetVoiceName (std::string VoiceName, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
assert (m_pTG[nTG]);
char Name[10];
strncpy(Name, VoiceName.c_str(),10);
m_pTG[nTG]->getName (Name);
}
bool CMiniDexed::DeletePerformance(unsigned nID)
{
m_bDeletePerformance = true;
m_nDeletePerformanceID = nID;
return true;
}
bool CMiniDexed::DoDeletePerformance(void)
{
unsigned nID = m_nDeletePerformanceID;
if(m_PerformanceConfig.DeletePerformance(nID))
{
if (m_PerformanceConfig.Load ())
{
LoadPerformanceParameters();
return true;
}
else
{
SetMIDIChannel (CMIDIDevice::OmniMode, 0);
}
}
return false;
}
bool CMiniDexed::GetPerformanceSelectToLoad(void)
{
return m_pConfig->GetPerformanceSelectToLoad();
}
void CMiniDexed::setModController (unsigned controller, unsigned parameter, uint8_t value, uint8_t nTG)
{
uint8_t nBits;
switch (controller)
{
case 0:
if (parameter == 0)
{
setModWheelRange(value, nTG);
}
else
{
value=constrain(value, 0, 1);
nBits=m_nModulationWheelTarget[nTG];
value == 1 ? nBits |= 1 << (parameter-1) : nBits &= ~(1 << (parameter-1));
setModWheelTarget(nBits , nTG);
}
break;
case 1:
if (parameter == 0)
{
setFootControllerRange(value, nTG);
}
else
{
value=constrain(value, 0, 1);
nBits=m_nFootControlTarget[nTG];
value == 1 ? nBits |= 1 << (parameter-1) : nBits &= ~(1 << (parameter-1));
setFootControllerTarget(nBits , nTG);
}
break;
case 2:
if (parameter == 0)
{
setBreathControllerRange(value, nTG);
}
else
{
value=constrain(value, 0, 1);
nBits=m_nBreathControlTarget[nTG];
value == 1 ? nBits |= 1 << (parameter-1) : nBits &= ~(1 << (parameter-1));
setBreathControllerTarget(nBits , nTG);
}
break;
case 3:
if (parameter == 0)
{
setAftertouchRange(value, nTG);
}
else
{
value=constrain(value, 0, 1);
nBits=m_nAftertouchTarget[nTG];
value == 1 ? nBits |= 1 << (parameter-1) : nBits &= ~(1 << (parameter-1));
setAftertouchTarget(nBits , nTG);
}
break;
default:
break;
}
}
unsigned CMiniDexed::getModController (unsigned controller, unsigned parameter, uint8_t nTG)
{
unsigned nBits;
switch (controller)
{
case 0:
if (parameter == 0)
{
return m_nModulationWheelRange[nTG];
}
else
{
nBits=m_nModulationWheelTarget[nTG];
nBits &= 1 << (parameter-1);
return (nBits != 0 ? 1 : 0) ;
}
break;
case 1:
if (parameter == 0)
{
return m_nFootControlRange[nTG];
}
else
{
nBits=m_nFootControlTarget[nTG];
nBits &= 1 << (parameter-1) ;
return (nBits != 0 ? 1 : 0) ;
}
break;
case 2:
if (parameter == 0)
{
return m_nBreathControlRange[nTG];
}
else
{
nBits=m_nBreathControlTarget[nTG];
nBits &= 1 << (parameter-1) ;
return (nBits != 0 ? 1 : 0) ;
}
break;
case 3:
if (parameter == 0)
{
return m_nAftertouchRange[nTG];
}
else
{
nBits=m_nAftertouchTarget[nTG];
nBits &= 1 << (parameter-1) ;
return (nBits != 0 ? 1 : 0) ;
}
break;
default:
return 0;
break;
}
}

@ -82,6 +82,10 @@ public:
void setPitchbend (int16_t value, unsigned nTG);
void ControllersRefresh (unsigned nTG);
void setFootController (uint8_t value, unsigned nTG);
void setBreathController (uint8_t value, unsigned nTG);
void setAftertouch (uint8_t value, unsigned nTG);
void SetReverbSend (unsigned nReverbSend, unsigned nTG); // 0 .. 127
void setMonoMode(uint8_t mono, uint8_t nTG);
@ -102,6 +106,9 @@ public:
void setVoiceDataElement(uint8_t data, uint8_t number, uint8_t nTG);
void getSysExVoiceDump(uint8_t* dest, uint8_t nTG);
void setModController (unsigned controller, unsigned parameter, uint8_t value, uint8_t nTG);
unsigned getModController (unsigned controller, unsigned parameter, uint8_t nTG);
int16_t checkSystemExclusive(const uint8_t* pMessage, const uint16_t nLength, uint8_t nTG);
std::string GetPerformanceFileName(unsigned nID);
@ -111,11 +118,11 @@ public:
void SetActualPerformanceID(unsigned nID);
bool SetNewPerformance(unsigned nID);
bool SavePerformanceNewFile ();
unsigned GetMenuSelectedPerformanceID();
void SetMenuSelectedPerformanceID(unsigned nID);
bool DoSavePerformanceNewFile (void);
bool DoSetNewPerformance (void);
bool GetPerformanceSelectToLoad(void);
bool SavePerformance (bool bSaveAsDeault);
enum TParameter
{
@ -133,6 +140,12 @@ public:
void SetParameter (TParameter Parameter, int nValue);
int GetParameter (TParameter Parameter);
std::string GetNewPerformanceDefaultName(void);
void SetNewPerformanceName(std::string nName);
void SetVoiceName (std::string VoiceName, unsigned nTG);
bool DeletePerformance(unsigned nID);
bool DoDeletePerformance(void);
enum TTGParameter
{
TGParameterVoiceBank,
@ -149,6 +162,28 @@ public:
TGParameterPortamentoMode,
TGParameterPortamentoGlissando,
TGParameterPortamentoTime,
TGParameterMonoMode,
TGParameterMWRange,
TGParameterMWPitch,
TGParameterMWAmplitude,
TGParameterMWEGBias,
TGParameterFCRange,
TGParameterFCPitch,
TGParameterFCAmplitude,
TGParameterFCEGBias,
TGParameterBCRange,
TGParameterBCPitch,
TGParameterBCAmplitude,
TGParameterBCEGBias,
TGParameterATRange,
TGParameterATPitch,
TGParameterATAmplitude,
TGParameterATEGBias,
TGParameterUnknown
};
@ -204,6 +239,16 @@ private:
unsigned m_nPortamentoMode[CConfig::ToneGenerators];
unsigned m_nPortamentoGlissando[CConfig::ToneGenerators];
unsigned m_nPortamentoTime[CConfig::ToneGenerators];
bool m_bMonoMode[CConfig::ToneGenerators];
unsigned m_nModulationWheelRange[CConfig::ToneGenerators];
unsigned m_nModulationWheelTarget[CConfig::ToneGenerators];
unsigned m_nFootControlRange[CConfig::ToneGenerators];
unsigned m_nFootControlTarget[CConfig::ToneGenerators];
unsigned m_nBreathControlRange[CConfig::ToneGenerators];
unsigned m_nBreathControlTarget[CConfig::ToneGenerators];
unsigned m_nAftertouchRange[CConfig::ToneGenerators];
unsigned m_nAftertouchTarget[CConfig::ToneGenerators];
unsigned m_nNoteLimitLow[CConfig::ToneGenerators];
unsigned m_nNoteLimitHigh[CConfig::ToneGenerators];
@ -220,7 +265,8 @@ private:
float32_t nMasterVolume;
bool m_bDeletePerformance;
unsigned m_nDeletePerformanceID;
CUserInterface m_UI;
CSysExFileLoader m_SysExFileLoader;
@ -252,6 +298,8 @@ private:
CSpinLock m_ReverbSpinLock;
bool m_bSavePerformance;
bool m_bLoadPerformanceBusy;
bool m_bSaveAsDeault;
};
#endif

@ -65,3 +65,6 @@ EncoderPinData=9
# Debug
MIDIDumpEnabled=0
ProfileEnabled=0
# Performance
PerformanceSelectToLoad=1

@ -21,6 +21,15 @@
#PortamentoGlissando#=0 # 0 .. 1
#PortamentoTime#=0 # 0 .. 99
#VoiceData#= # space separated hex numbers of 156 voice parameters. Example: 5F 1D 14 32 63 [....] 20 55
#MonoMode#=0 # 0-off .. 1-On
#ModulationWheelRange#=99 # 0..99
#ModulationWheelTarget#=1 # 0..7
#FootControlRange#=99 # 0..99
#FootControlTarget#=0 # 0..7
#BreathControlRange#=99 # 0..99
#BreathControlTarget#=0 # 0..7
#AftertouchRange#=99 # 0..99
#AftertouchTarget#=0 # 0..7
# TG1
BankNumber1=0
@ -41,6 +50,15 @@ PortamentoMode1=0
PortamentoGlissando1=0
PortamentoTime1=0
VoiceData1=
MonoMode1=0
ModulationWheelRange1=99
ModulationWheelTarget1=1
FootControlRange1=99
FootControlTarget1=0
BreathControlRange1=99
BreathControlTarget1=0
AftertouchRange1=99
AftertouchTarget1=0
# TG2
BankNumber2=0
@ -61,6 +79,15 @@ PortamentoMode2=0
PortamentoGlissando2=0
PortamentoTime2=0
VoiceData2=
MonoMode2=0
ModulationWheelRange2=99
ModulationWheelTarget2=1
FootControlRange2=99
FootControlTarget2=0
BreathControlRange2=99
BreathControlTarget2=0
AftertouchRange2=99
AftertouchTarget2=0
# TG3
BankNumber3=0
@ -81,6 +108,15 @@ PortamentoMode3=0
PortamentoGlissando3=0
PortamentoTime3=0
VoiceData3=
MonoMode3=0
ModulationWheelRange3=99
ModulationWheelTarget3=1
FootControlRange3=99
FootControlTarget3=0
BreathControlRange3=99
BreathControlTarget3=0
AftertouchRange3=99
AftertouchTarget3=0
# TG4
BankNumber4=0
@ -101,6 +137,15 @@ PortamentoMode4=0
PortamentoGlissando4=0
PortamentoTime4=0
VoiceData4=
MonoMode4=0
ModulationWheelRange4=99
ModulationWheelTarget4=1
FootControlRange4=99
FootControlTarget4=0
BreathControlRange4=99
BreathControlTarget4=0
AftertouchRange4=99
AftertouchTarget4=0
# TG5
BankNumber5=0
@ -121,6 +166,15 @@ PortamentoMode5=0
PortamentoGlissando5=0
PortamentoTime5=0
VoiceData5=
MonoMode5=0
ModulationWheelRange5=99
ModulationWheelTarget5=1
FootControlRange5=99
FootControlTarget5=0
BreathControlRange5=99
BreathControlTarget5=0
AftertouchRange5=99
AftertouchTarget5=0
# TG6
BankNumber6=0
@ -141,6 +195,15 @@ PortamentoMode6=0
PortamentoGlissando6=0
PortamentoTime6=0
VoiceData6=
MonoMode6=0
ModulationWheelRange6=99
ModulationWheelTarget6=1
FootControlRange6=99
FootControlTarget6=0
BreathControlRange6=99
BreathControlTarget6=0
AftertouchRange6=99
AftertouchTarget6=0
# TG7
BankNumber7=0
@ -161,6 +224,15 @@ PortamentoMode7=0
PortamentoGlissando7=0
PortamentoTime7=0
VoiceData7=
MonoMode7=0
ModulationWheelRange7=99
ModulationWheelTarget7=1
FootControlRange7=99
FootControlTarget7=0
BreathControlRange7=99
BreathControlTarget7=0
AftertouchRange7=99
AftertouchTarget7=0
# TG8
BankNumber8=0
@ -181,6 +253,15 @@ PortamentoMode8=0
PortamentoGlissando8=0
PortamentoTime8=0
VoiceData8=
MonoMode8=0
ModulationWheelRange8=99
ModulationWheelTarget8=1
FootControlRange8=99
FootControlTarget8=0
BreathControlRange8=99
BreathControlTarget8=0
AftertouchRange8=99
AftertouchTarget8=0
# Effects
#CompressorEnable=1 # 0: off, 1: on

@ -119,6 +119,34 @@ bool CPerformanceConfig::Load (void)
PropertyName.Format ("VoiceData%u", nTG+1);
m_nVoiceDataTxt[nTG] = m_Properties.GetString (PropertyName, "");
PropertyName.Format ("MonoMode%u", nTG+1);
m_bMonoMode[nTG] = m_Properties.GetNumber (PropertyName, 0) != 0;
PropertyName.Format ("ModulationWheelRange%u", nTG+1);
m_nModulationWheelRange[nTG] = m_Properties.GetNumber (PropertyName, 99);
PropertyName.Format ("ModulationWheelTarget%u", nTG+1);
m_nModulationWheelTarget[nTG] = m_Properties.GetNumber (PropertyName, 1);
PropertyName.Format ("FootControlRange%u", nTG+1);
m_nFootControlRange[nTG] = m_Properties.GetNumber (PropertyName, 99);
PropertyName.Format ("FootControlTarget%u", nTG+1);
m_nFootControlTarget[nTG] = m_Properties.GetNumber (PropertyName, 0);
PropertyName.Format ("BreathControlRange%u", nTG+1);
m_nBreathControlRange[nTG] = m_Properties.GetNumber (PropertyName, 99);
PropertyName.Format ("BreathControlTarget%u", nTG+1);
m_nBreathControlTarget[nTG] = m_Properties.GetNumber (PropertyName, 0);
PropertyName.Format ("AftertouchRange%u", nTG+1);
m_nAftertouchRange[nTG] = m_Properties.GetNumber (PropertyName, 99);
PropertyName.Format ("AftertouchTarget%u", nTG+1);
m_nAftertouchTarget[nTG] = m_Properties.GetNumber (PropertyName, 0);
}
m_bCompressorEnable = m_Properties.GetNumber ("CompressorEnable", 1) != 0;
@ -209,6 +237,34 @@ bool CPerformanceConfig::Save (void)
PropertyName.Format ("VoiceData%u", nTG+1);
char *cstr = &m_nVoiceDataTxt[nTG][0];
m_Properties.SetString (PropertyName, cstr);
PropertyName.Format ("MonoMode%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_bMonoMode[nTG] ? 1 : 0);
PropertyName.Format ("ModulationWheelRange%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nModulationWheelRange[nTG]);
PropertyName.Format ("ModulationWheelTarget%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nModulationWheelTarget[nTG]);
PropertyName.Format ("FootControlRange%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nFootControlRange[nTG]);
PropertyName.Format ("FootControlTarget%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nFootControlTarget[nTG]);
PropertyName.Format ("BreathControlRange%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nBreathControlRange[nTG]);
PropertyName.Format ("BreathControlTarget%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nBreathControlTarget[nTG]);
PropertyName.Format ("AftertouchRange%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nAftertouchRange[nTG]);
PropertyName.Format ("AftertouchTarget%u", nTG+1);
m_Properties.SetNumber (PropertyName, m_nAftertouchTarget[nTG]);
}
m_Properties.SetNumber ("CompressorEnable", m_bCompressorEnable ? 1 : 0);
@ -512,6 +568,113 @@ unsigned CPerformanceConfig::GetPortamentoTime (unsigned nTG) const
return m_nPortamentoTime[nTG];
}
void CPerformanceConfig::SetMonoMode (bool bValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_bMonoMode[nTG] = bValue;
}
bool CPerformanceConfig::GetMonoMode (unsigned nTG) const
{
return m_bMonoMode[nTG];
}
void CPerformanceConfig::SetModulationWheelRange (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nModulationWheelRange[nTG] = nValue;
}
unsigned CPerformanceConfig::GetModulationWheelRange (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nModulationWheelRange[nTG];
}
void CPerformanceConfig::SetModulationWheelTarget (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nModulationWheelTarget[nTG] = nValue;
}
unsigned CPerformanceConfig::GetModulationWheelTarget (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nModulationWheelTarget[nTG];
}
void CPerformanceConfig::SetFootControlRange (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nFootControlRange[nTG] = nValue;
}
unsigned CPerformanceConfig::GetFootControlRange (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nFootControlRange[nTG];
}
void CPerformanceConfig::SetFootControlTarget (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nFootControlTarget[nTG] = nValue;
}
unsigned CPerformanceConfig::GetFootControlTarget (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nFootControlTarget[nTG];
}
void CPerformanceConfig::SetBreathControlRange (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nBreathControlRange[nTG] = nValue;
}
unsigned CPerformanceConfig::GetBreathControlRange (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nBreathControlRange[nTG];
}
void CPerformanceConfig::SetBreathControlTarget (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nBreathControlTarget[nTG] = nValue;
}
unsigned CPerformanceConfig::GetBreathControlTarget (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nBreathControlTarget[nTG];
}
void CPerformanceConfig::SetAftertouchRange (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nAftertouchRange[nTG] = nValue;
}
unsigned CPerformanceConfig::GetAftertouchRange (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nAftertouchRange[nTG];
}
void CPerformanceConfig::SetAftertouchTarget (unsigned nValue, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
m_nAftertouchTarget[nTG] = nValue;
}
unsigned CPerformanceConfig::GetAftertouchTarget (unsigned nTG) const
{
assert (nTG < CConfig::ToneGenerators);
return m_nAftertouchTarget[nTG];
}
void CPerformanceConfig::SetVoiceDataToTxt (const uint8_t *pData, unsigned nTG)
{
assert (nTG < CConfig::ToneGenerators);
@ -579,25 +742,15 @@ void CPerformanceConfig::SetActualPerformanceID(unsigned nID)
nActualPerformance = nID;
}
unsigned CPerformanceConfig::GetMenuSelectedPerformanceID()
{
return nMenuSelectedPerformance;
}
void CPerformanceConfig::SetMenuSelectedPerformanceID(unsigned nID)
{
nMenuSelectedPerformance = nID;
}
bool CPerformanceConfig::GetInternalFolderOk()
{
return nInternalFolderOk;
}
bool CPerformanceConfig::CreateNewPerformanceFile(std::string sPerformanceName)
bool CPerformanceConfig::CreateNewPerformanceFile(void)
{
// sPerformanceName for future improvements when user can enter a name via UI
std::string sPerformanceName = NewPerformanceName;
NewPerformanceName="";
nActualPerformance=nLastPerformance;
std::string nFileName;
std::string nPath;
@ -697,7 +850,7 @@ bool CPerformanceConfig::ListPerformances()
// sort by performance number-name
if (nLastPerformance > 2)
{
sort (m_nPerformanceFileName+1, m_nPerformanceFileName + nLastPerformance - 1); // default is always on first place.
sort (m_nPerformanceFileName+1, m_nPerformanceFileName + nLastPerformance); // default is always on first place. %%%%%%%%%%%%%%%%
}
}
@ -718,3 +871,55 @@ void CPerformanceConfig::SetNewPerformance (unsigned nID)
new (&m_Properties) CPropertiesFatFsFile(FileN.c_str(), m_pFileSystem);
}
std::string CPerformanceConfig::GetNewPerformanceDefaultName(void)
{
std::string nIndex = "000000";
nIndex += std::to_string(nLastFileIndex+1);
nIndex = nIndex.substr(nIndex.length()-6,6);
return "Perf" + nIndex;
}
void CPerformanceConfig::SetNewPerformanceName(std::string nName)
{
int i = nName.length();
do
{
--i;
}
while (i>=0 && nName[i] == 32);
nName=nName.substr(0,i+1) ;
NewPerformanceName = nName;
}
bool CPerformanceConfig::DeletePerformance(unsigned nID)
{
bool bOK = false;
if(nID == 0){return bOK;} // default (performance.ini at root directory) can't be deleted
DIR Directory;
FILINFO FileInfo;
std::string FileN = "SD:/";
FileN += PERFORMANCE_DIR;
FRESULT Result = f_findfirst (&Directory, &FileInfo, FileN.c_str(), m_nPerformanceFileName[nID].c_str());
if (Result == FR_OK && FileInfo.fname[0])
{
FileN += "/";
FileN += m_nPerformanceFileName[nID];
Result=f_unlink (FileN.c_str());
if (Result == FR_OK)
{
SetNewPerformance(0);
nActualPerformance =0;
//nMenuSelectedPerformance=0;
m_nPerformanceFileName[nID]="ZZZZZZ";
sort (m_nPerformanceFileName+1, m_nPerformanceFileName + nLastPerformance); // test si va con -1 o no
--nLastPerformance;
m_nPerformanceFileName[nLastPerformance]=nullptr;
bOK=true;
}
}
return bOK;
}

@ -57,6 +57,16 @@ public:
unsigned GetPortamentoMode (unsigned nTG) const; // 0 .. 1
unsigned GetPortamentoGlissando (unsigned nTG) const; // 0 .. 1
unsigned GetPortamentoTime (unsigned nTG) const; // 0 .. 99
bool GetMonoMode (unsigned nTG) const; // 0 .. 1
unsigned GetModulationWheelRange (unsigned nTG) const; // 0 .. 99
unsigned GetModulationWheelTarget (unsigned nTG) const; // 0 .. 7
unsigned GetFootControlRange (unsigned nTG) const; // 0 .. 99
unsigned GetFootControlTarget (unsigned nTG) const; // 0 .. 7
unsigned GetBreathControlRange (unsigned nTG) const; // 0 .. 99
unsigned GetBreathControlTarget (unsigned nTG) const; // 0 .. 7
unsigned GetAftertouchRange (unsigned nTG) const; // 0 .. 99
unsigned GetAftertouchTarget (unsigned nTG) const; // 0 .. 7
void SetBankNumber (unsigned nValue, unsigned nTG);
void SetVoiceNumber (unsigned nValue, unsigned nTG);
@ -77,6 +87,16 @@ public:
void SetPortamentoTime (unsigned nValue, unsigned nTG);
void SetVoiceDataToTxt (const uint8_t *pData, unsigned nTG);
uint8_t *GetVoiceDataFromTxt (unsigned nTG);
void SetMonoMode (bool bOKValue, unsigned nTG);
void SetModulationWheelRange (unsigned nValue, unsigned nTG);
void SetModulationWheelTarget (unsigned nValue, unsigned nTG);
void SetFootControlRange (unsigned nValue, unsigned nTG);
void SetFootControlTarget (unsigned nValue, unsigned nTG);
void SetBreathControlRange (unsigned nValue, unsigned nTG);
void SetBreathControlTarget (unsigned nValue, unsigned nTG);
void SetAftertouchRange (unsigned nValue, unsigned nTG);
void SetAftertouchTarget (unsigned nValue, unsigned nTG);
// Effects
bool GetCompressorEnable (void) const;
@ -106,10 +126,11 @@ public:
unsigned GetLastPerformance();
void SetActualPerformanceID(unsigned nID);
unsigned GetActualPerformanceID();
void SetMenuSelectedPerformanceID(unsigned nID);
unsigned GetMenuSelectedPerformanceID();
bool CreateNewPerformanceFile(std::string sPerformanceName);
bool CreateNewPerformanceFile(void);
bool GetInternalFolderOk();
std::string GetNewPerformanceDefaultName(void);
void SetNewPerformanceName(std::string nName);
bool DeletePerformance(unsigned nID);
private:
CPropertiesFatFsFile m_Properties;
@ -132,16 +153,27 @@ private:
unsigned m_nPortamentoGlissando[CConfig::ToneGenerators];
unsigned m_nPortamentoTime[CConfig::ToneGenerators];
std::string m_nVoiceDataTxt[CConfig::ToneGenerators];
bool m_bMonoMode[CConfig::ToneGenerators];
unsigned m_nModulationWheelRange[CConfig::ToneGenerators];
unsigned m_nModulationWheelTarget[CConfig::ToneGenerators];
unsigned m_nFootControlRange[CConfig::ToneGenerators];
unsigned m_nFootControlTarget[CConfig::ToneGenerators];
unsigned m_nBreathControlRange[CConfig::ToneGenerators];
unsigned m_nBreathControlTarget[CConfig::ToneGenerators];
unsigned m_nAftertouchRange[CConfig::ToneGenerators];
unsigned m_nAftertouchTarget[CConfig::ToneGenerators];
unsigned nLastPerformance;
unsigned nLastFileIndex;
unsigned nActualPerformance = 0;
unsigned nMenuSelectedPerformance = 0;
//unsigned nMenuSelectedPerformance = 0;
std::string m_nPerformanceFileName[40];
FATFS *m_pFileSystem;
bool nInternalFolderOk=false;
bool nExternalFolderOk=false; // for future USB implementation
std::string NewPerformanceName="";
bool m_bCompressorEnable;
bool m_bReverbEnable;

@ -130,7 +130,8 @@ void CSerialMIDIDevice::Process (void)
m_SerialMessage[m_nSerialState++] = uchData;
if ( (m_SerialMessage[0] & 0xE0) == 0xC0
|| m_nSerialState == 3) // message is complete
|| m_nSerialState == 3 // message is complete
|| (m_SerialMessage[0] & 0xF0) == 0xD0) // channel aftertouch
{
MIDIMessageHandler (m_SerialMessage, m_nSerialState);

@ -52,8 +52,7 @@ const CUIMenu::TMenuItem CUIMenu::s_MainMenu[] =
{"TG8", MenuHandler, s_TGMenu, 7},
#endif
{"Effects", MenuHandler, s_EffectsMenu},
{"Performance", PerformanceMenu},
{"Save", MenuHandler, s_SaveMenu},
{"Performance", MenuHandler, s_PerformanceMenu},
{0}
};
@ -71,6 +70,8 @@ const CUIMenu::TMenuItem CUIMenu::s_TGMenu[] =
{"Resonance", EditTGParameter, 0, CMiniDexed::TGParameterResonance},
{"Pitch Bend", MenuHandler, s_EditPitchBendMenu},
{"Portamento", MenuHandler, s_EditPortamentoMenu},
{"Poly/Mono", EditTGParameter, 0, CMiniDexed::TGParameterMonoMode},
{"Modulation", MenuHandler, s_ModulationMenu},
{"Channel", EditTGParameter, 0, CMiniDexed::TGParameterMIDIChannel},
{"Edit Voice", MenuHandler, s_EditVoiceMenu},
{0}
@ -100,6 +101,24 @@ const CUIMenu::TMenuItem CUIMenu::s_EditPortamentoMenu[] =
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_ModulationMenu[] =
{
{"Mod. Wheel", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterMWRange},
{"Foot Control", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterFCRange},
{"Breath Control", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterBCRange},
{"Aftertouch", MenuHandler, s_ModulationMenuParameters, CMiniDexed::TGParameterATRange},
{0}
};
const CUIMenu::TMenuItem CUIMenu::s_ModulationMenuParameters[] =
{
{"Range", EditTGParameterModulation, 0, 0},
{"Pitch", EditTGParameterModulation, 0, 1},
{"Amplitude", EditTGParameterModulation, 0, 2},
{"EG Bias", EditTGParameterModulation, 0, 3},
{0}
};
#ifdef ARM_ALLOW_MULTI_CORE
const CUIMenu::TMenuItem CUIMenu::s_ReverbMenu[] =
@ -144,6 +163,7 @@ const CUIMenu::TMenuItem CUIMenu::s_EditVoiceMenu[] =
{"LFO Wave", EditVoiceParameter, 0, DEXED_LFO_WAVE},
{"P Mod Sens.", EditVoiceParameter, 0, DEXED_LFO_PITCH_MOD_SENS},
{"Transpose", EditVoiceParameter, 0, DEXED_TRANSPOSE},
{"Name", InputTxt,0 , 3},
{0}
};
@ -176,8 +196,9 @@ const CUIMenu::TMenuItem CUIMenu::s_OperatorMenu[] =
const CUIMenu::TMenuItem CUIMenu::s_SaveMenu[] =
{
{"Overwrite", SavePerformance},
{"New", SavePerformanceNewFile},
{"Overwrite", SavePerformance, 0, 0},
{"New", InputTxt,0 , 1},
{"Save as default", SavePerformance, 0, 1},
{0}
};
@ -208,9 +229,27 @@ const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown]
{0, 99, 1}, // TGParameterReverbSend
{0, 12, 1}, // TGParameterPitchBendRange
{0, 12, 1}, // TGParameterPitchBendStep
{0, 1, 1, ToPortaMode}, // TGParameterPortamentoMode
{0, 1, 1, ToPortaGlissando}, // TGParameterPortamentoGlissando
{0, 99, 1} // TGParameterPortamentoTime
{0, 1, 1, ToPortaMode}, // TGParameterPortamentoMode
{0, 1, 1, ToPortaGlissando}, // TGParameterPortamentoGlissando
{0, 99, 1}, // TGParameterPortamentoTime
{0, 1, 1, ToPolyMono}, // TGParameterMonoMode
{0, 99, 1}, //MW Range
{0, 1, 1, ToOnOff}, //MW Pitch
{0, 1, 1, ToOnOff}, //MW Amp
{0, 1, 1, ToOnOff}, //MW EGBias
{0, 99, 1}, //FC Range
{0, 1, 1, ToOnOff}, //FC Pitch
{0, 1, 1, ToOnOff}, //FC Amp
{0, 1, 1, ToOnOff}, //FC EGBias
{0, 99, 1}, //BC Range
{0, 1, 1, ToOnOff}, //BC Pitch
{0, 1, 1, ToOnOff}, //BC Amp
{0, 1, 1, ToOnOff}, //BC EGBias
{0, 99, 1}, //AT Range
{0, 1, 1, ToOnOff}, //AT Pitch
{0, 1, 1, ToOnOff}, //AT Amp
{0, 1, 1, ToOnOff} //AT EGBias
};
// must match DexedVoiceParameters in Synth_Dexed
@ -234,7 +273,8 @@ const CUIMenu::TParameter CUIMenu::s_VoiceParameter[] =
{0, 1, 1, ToOnOff}, // DEXED_LFO_SYNC
{0, 5, 1, ToLFOWaveform}, // DEXED_LFO_WAVE
{0, 7, 1}, // DEXED_LFO_PITCH_MOD_SENS
{0, 48, 1, ToTransposeNote} // DEXED_TRANSPOSE
{0, 48, 1, ToTransposeNote}, // DEXED_TRANSPOSE
{0, 1, 1} // Voice Name - Dummy parameters for in case new item would be added in future
};
// must match DexedVoiceOPParameters in Synth_Dexed
@ -278,6 +318,15 @@ const char CUIMenu::s_NoteName[100][4] =
};
static const unsigned NoteC3 = 27;
const CUIMenu::TMenuItem CUIMenu::s_PerformanceMenu[] =
{
{"Load", PerformanceMenu, 0, 0},
{"Save", MenuHandler, s_SaveMenu},
{"Delete", PerformanceMenu, 0, 1},
{0}
};
CUIMenu::CUIMenu (CUserInterface *pUI, CMiniDexed *pMiniDexed)
: m_pUI (pUI),
m_pMiniDexed (pMiniDexed),
@ -799,7 +848,7 @@ void CUIMenu::SavePerformance (CUIMenu *pUIMenu, TMenuEvent Event)
return;
}
bool bOK = pUIMenu->m_pMiniDexed->SavePerformance ();
bool bOK = pUIMenu->m_pMiniDexed->SavePerformance (pUIMenu->m_nCurrentParameter == 1);
const char *pMenuName =
pUIMenu->m_MenuStackParent[pUIMenu->m_nCurrentMenuDepth-1]
@ -1020,6 +1069,16 @@ string CUIMenu::ToPortaGlissando (int nValue)
}
};
string CUIMenu::ToPolyMono (int nValue)
{
switch (nValue)
{
case 0: return "Poly";
case 1: return "Mono";
default: return to_string (nValue);
}
}
void CUIMenu::TGShortcutHandler (TMenuEvent Event)
{
assert (m_nCurrentMenuDepth >= 2);
@ -1088,79 +1147,364 @@ void CUIMenu::TimerHandler (TKernelTimerHandle hTimer, void *pParam, void *pCont
pThis->EventHandler (MenuEventBack);
}
void CUIMenu::TimerHandlerNoBack (TKernelTimerHandle hTimer, void *pParam, void *pContext)
{
CUIMenu *pThis = static_cast<CUIMenu *> (pContext);
assert (pThis);
pThis->m_bSplashShow = false;
pThis->EventHandler (MenuEventUpdate);
}
void CUIMenu::PerformanceMenu (CUIMenu *pUIMenu, TMenuEvent Event)
{
bool bPerformanceSelectToLoad = pUIMenu->m_pMiniDexed->GetPerformanceSelectToLoad();
unsigned nValue = pUIMenu->m_nSelectedPerformanceID;
std::string Value;
if (Event == MenuEventUpdate)
{
pUIMenu->m_bPerformanceDeleteMode=false;
}
if (pUIMenu->m_bSplashShow)
{
return;
}
if(!pUIMenu->m_bPerformanceDeleteMode)
{
switch (Event)
{
case MenuEventUpdate:
break;
case MenuEventStepDown:
if (nValue > 0)
{
--nValue;
}
pUIMenu->m_nSelectedPerformanceID = nValue;
if (!bPerformanceSelectToLoad && pUIMenu->m_nCurrentParameter==0)
{
pUIMenu->m_pMiniDexed->SetNewPerformance(nValue);
}
break;
case MenuEventStepUp:
if (++nValue > (unsigned) pUIMenu->m_pMiniDexed->GetLastPerformance()-1)
{
nValue = pUIMenu->m_pMiniDexed->GetLastPerformance()-1;
}
pUIMenu->m_nSelectedPerformanceID = nValue;
if (!bPerformanceSelectToLoad && pUIMenu->m_nCurrentParameter==0)
{
pUIMenu->m_pMiniDexed->SetNewPerformance(nValue);
}
break;
case MenuEventSelect:
switch (pUIMenu->m_nCurrentParameter)
{
case 0:
if (bPerformanceSelectToLoad)
{
pUIMenu->m_pMiniDexed->SetNewPerformance(nValue);
}
break;
case 1:
if (pUIMenu->m_nSelectedPerformanceID != 0)
{
pUIMenu->m_bPerformanceDeleteMode=true;
pUIMenu->m_bConfirmDeletePerformance=false;
}
break;
default:
break;
}
break;
default:
return;
}
}
else
{
switch (Event)
{
case MenuEventUpdate:
break;
case MenuEventStepDown:
pUIMenu->m_bConfirmDeletePerformance=false;
break;
case MenuEventStepUp:
pUIMenu->m_bConfirmDeletePerformance=true;
break;
case MenuEventSelect:
pUIMenu->m_bPerformanceDeleteMode=false;
if (pUIMenu->m_bConfirmDeletePerformance)
{
pUIMenu->m_nSelectedPerformanceID = 0;
pUIMenu->m_bConfirmDeletePerformance=false;
pUIMenu->m_pUI->DisplayWrite ("", "Delete", pUIMenu->m_pMiniDexed->DeletePerformance(nValue) ? "Completed" : "Error", false, false);
pUIMenu->m_bSplashShow=true;
CTimer::Get ()->StartKernelTimer (MSEC2HZ (1500), TimerHandlerNoBack, 0, pUIMenu);
return;
}
else
{
break;
}
default:
return;
}
}
if(!pUIMenu->m_bPerformanceDeleteMode)
{
Value = pUIMenu->m_pMiniDexed->GetPerformanceName(nValue);
std::string nPSelected = "";
if(nValue == pUIMenu->m_pMiniDexed->GetActualPerformanceID())
{
nPSelected= "[L]";
}
pUIMenu->m_pUI->DisplayWrite (pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name, nPSelected.c_str(),
Value.c_str (),
(int) nValue > 0, (int) nValue < (int) pUIMenu->m_pMiniDexed->GetLastPerformance()-1);
}
else
{
pUIMenu->m_pUI->DisplayWrite ("", "Delete?", pUIMenu->m_bConfirmDeletePerformance ? "Yes" : "No", false, false);
}
}
void CUIMenu::InputTxt (CUIMenu *pUIMenu, TMenuEvent Event)
{
unsigned nTG=0;
string TG ("TG");
std::string MsgOk;
std::string NoValidChars;
unsigned MaxChars;
std::string MenuTitleR;
std::string MenuTitleL;
std::string OkTitleL;
std::string OkTitleR;
switch(pUIMenu->m_nCurrentParameter)
{
case 1: // save new performance
NoValidChars = {92, 47, 58, 42, 63, 34, 60,62, 124};
MaxChars=14;
MenuTitleL="Performance Name";
MenuTitleR="";
OkTitleL="New Performance"; // \E[?25l
OkTitleR="";
break;
case 2: // Rename performance - NOT Implemented yet
NoValidChars = {92, 47, 58, 42, 63, 34, 60,62, 124};
MaxChars=14;
MenuTitleL="Performance Name";
MenuTitleR="";
OkTitleL="Rename Perf."; // \E[?25l
OkTitleR="";
break;
case 3: // Voice name
nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-2];
NoValidChars = {127};
MaxChars=10;
MenuTitleL="Name";
TG += to_string (nTG+1);
MenuTitleR=TG;
OkTitleL="";
OkTitleR="";
break;
default:
return;
}
bool bOK;
unsigned nPosition = pUIMenu->m_InputTextPosition;
unsigned nChar = pUIMenu->m_InputText[nPosition];
unsigned nValue = pUIMenu->m_pMiniDexed->GetMenuSelectedPerformanceID();
switch (Event)
{
case MenuEventUpdate:
if(pUIMenu->m_nCurrentParameter == 1 || pUIMenu->m_nCurrentParameter == 2)
{
pUIMenu->m_InputText = pUIMenu->m_pMiniDexed->GetNewPerformanceDefaultName();
pUIMenu->m_InputText += " ";
pUIMenu->m_InputText = pUIMenu->m_InputText.substr(0,14);
pUIMenu->m_InputTextPosition=0;
nPosition=pUIMenu->m_InputTextPosition;
nChar = pUIMenu->m_InputText[nPosition];
}
else
{
pUIMenu->m_InputText = pUIMenu->m_pMiniDexed->GetVoiceName(nTG);
pUIMenu->m_InputText += " ";
pUIMenu->m_InputText = pUIMenu->m_InputText.substr(0,10);
pUIMenu->m_InputTextPosition=0;
nPosition=pUIMenu->m_InputTextPosition;
nChar = pUIMenu->m_InputText[nPosition];
}
break;
case MenuEventStepDown:
if (nValue > 0)
if (nChar > 32)
{
--nValue;
do {
--nChar;
}
while (NoValidChars.find(nChar) != std::string::npos);
}
pUIMenu->m_pMiniDexed->SetMenuSelectedPerformanceID (nValue);
pUIMenu->m_InputTextChar = nChar;
break;
case MenuEventStepUp:
if (++nValue > (unsigned) pUIMenu->m_pMiniDexed->GetLastPerformance()-1)
if (nChar < 126)
{
nValue = pUIMenu->m_pMiniDexed->GetLastPerformance()-1;
do {
++nChar;
}
while (NoValidChars.find(nChar) != std::string::npos);
}
pUIMenu->m_pMiniDexed->SetMenuSelectedPerformanceID (nValue);
pUIMenu->m_InputTextChar = nChar;
break;
case MenuEventSelect:
pUIMenu->m_pMiniDexed->SetNewPerformance(nValue);
break;
case MenuEventSelect:
if(pUIMenu->m_nCurrentParameter == 1)
{
pUIMenu->m_pMiniDexed->SetNewPerformanceName(pUIMenu->m_InputText);
bOK = pUIMenu->m_pMiniDexed->SavePerformanceNewFile ();
MsgOk=bOK ? "Completed" : "Error";
pUIMenu->m_pUI->DisplayWrite (OkTitleR.c_str(), OkTitleL.c_str(), MsgOk.c_str(), false, false);
CTimer::Get ()->StartKernelTimer (MSEC2HZ (1500), TimerHandler, 0, pUIMenu);
return;
}
else
{
break; // Voice Name Edit
}
case MenuEventPressAndStepDown:
if (nPosition > 0)
{
--nPosition;
}
pUIMenu->m_InputTextPosition = nPosition;
nChar = pUIMenu->m_InputText[nPosition];
break;
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
if (nPosition < MaxChars-1)
{
++nPosition;
}
pUIMenu->m_InputTextPosition = nPosition;
nChar = pUIMenu->m_InputText[nPosition];
break;
default:
return;
}
string Value = pUIMenu->m_pMiniDexed->GetPerformanceName(nValue);
// \E[2;%dH Cursor move to row %1 and column %2 (starting at 1)
// \E[?25h Normal cursor visible
// \E[?25l Cursor invisible
std::string nPSelected = "";
if(nValue == pUIMenu->m_pMiniDexed->GetActualPerformanceID())
{
nPSelected="[Ld]";
}
std::string escCursor="\E[?25h\E[2;"; // this is to locate cursor
escCursor += to_string(nPosition + 2);
escCursor += "H";
std::string Value = pUIMenu->m_InputText;
Value[nPosition]=nChar;
pUIMenu->m_InputText = Value;
if(pUIMenu->m_nCurrentParameter == 3)
{
pUIMenu->m_pMiniDexed->SetVoiceName(pUIMenu->m_InputText, nTG);
}
Value = Value + " " + escCursor ;
pUIMenu->m_pUI->DisplayWrite (MenuTitleR.c_str(),MenuTitleL.c_str(), Value.c_str(), false, false);
pUIMenu->m_pUI->DisplayWrite (pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name, nPSelected.c_str(),
Value.c_str (),
(int) nValue > 0, (int) nValue < (int) pUIMenu->m_pMiniDexed->GetLastPerformance()-1);
}
void CUIMenu::SavePerformanceNewFile (CUIMenu *pUIMenu, TMenuEvent Event)
void CUIMenu::EditTGParameterModulation (CUIMenu *pUIMenu, TMenuEvent Event)
{
if (Event != MenuEventUpdate)
unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-3];
unsigned nController = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-1];
unsigned nParameter = pUIMenu->m_nCurrentParameter + nController;
CMiniDexed::TTGParameter Param = (CMiniDexed::TTGParameter) nParameter;
const TParameter &rParam = s_TGParameter[Param];
int nValue = pUIMenu->m_pMiniDexed->GetTGParameter (Param, nTG);
switch (Event)
{
case MenuEventUpdate:
break;
case MenuEventStepDown:
nValue -= rParam.Increment;
if (nValue < rParam.Minimum)
{
nValue = rParam.Minimum;
}
pUIMenu->m_pMiniDexed->SetTGParameter (Param, nValue, nTG);
break;
case MenuEventStepUp:
nValue += rParam.Increment;
if (nValue > rParam.Maximum)
{
nValue = rParam.Maximum;
}
pUIMenu->m_pMiniDexed->SetTGParameter (Param, nValue, nTG);
break;
case MenuEventPressAndStepDown:
case MenuEventPressAndStepUp:
pUIMenu->TGShortcutHandler (Event);
return;
default:
return;
}
bool bOK = pUIMenu->m_pMiniDexed->SavePerformanceNewFile ();
string TG ("TG");
TG += to_string (nTG+1);
const char *pMenuName =
pUIMenu->m_MenuStackParent[pUIMenu->m_nCurrentMenuDepth-1]
[pUIMenu->m_nMenuStackItem[pUIMenu->m_nCurrentMenuDepth-1]].Name;
string Value = GetTGValueString (Param, pUIMenu->m_pMiniDexed->GetTGParameter (Param, nTG));
pUIMenu->m_pUI->DisplayWrite (pMenuName,
pUIMenu->m_pUI->DisplayWrite (TG.c_str (),
pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name,
bOK ? "Completed" : "Error",
false, false);
Value.c_str (),
nValue > rParam.Minimum, nValue < rParam.Maximum);
CTimer::Get ()->StartKernelTimer (MSEC2HZ (1500), TimerHandler, 0, pUIMenu);
}

@ -84,7 +84,7 @@ private:
static void EditOPParameter (CUIMenu *pUIMenu, TMenuEvent Event);
static void SavePerformance (CUIMenu *pUIMenu, TMenuEvent Event);
static void EditTGParameter2 (CUIMenu *pUIMenu, TMenuEvent Event);
static void EditTGParameterModulation (CUIMenu *pUIMenu, TMenuEvent Event);
static void PerformanceMenu (CUIMenu *pUIMenu, TMenuEvent Event);
static void SavePerformanceNewFile (CUIMenu *pUIMenu, TMenuEvent Event);
@ -107,12 +107,16 @@ private:
static std::string ToOscillatorDetune (int nValue);
static std::string ToPortaMode (int nValue);
static std::string ToPortaGlissando (int nValue);
static std::string ToPolyMono (int nValue);
void TGShortcutHandler (TMenuEvent Event);
void OPShortcutHandler (TMenuEvent Event);
static void TimerHandler (TKernelTimerHandle hTimer, void *pParam, void *pContext);
static void InputTxt (CUIMenu *pUIMenu, TMenuEvent Event);
static void TimerHandlerNoBack (TKernelTimerHandle hTimer, void *pParam, void *pContext);
private:
CUserInterface *m_pUI;
CMiniDexed *m_pMiniDexed;
@ -140,6 +144,10 @@ private:
static const TMenuItem s_SaveMenu[];
static const TMenuItem s_EditPitchBendMenu[];
static const TMenuItem s_EditPortamentoMenu[];
static const TMenuItem s_PerformanceMenu[];
static const TMenuItem s_ModulationMenu[];
static const TMenuItem s_ModulationMenuParameters[];
static const TParameter s_GlobalParameter[];
static const TParameter s_TGParameter[];
@ -147,6 +155,15 @@ private:
static const TParameter s_OPParameter[];
static const char s_NoteName[100][4];
std::string m_InputText="1234567890ABCD";
unsigned m_InputTextPosition=0;
unsigned m_InputTextChar=32;
bool m_bPerformanceDeleteMode=false;
bool m_bConfirmDeletePerformance=false;
unsigned m_nSelectedPerformanceID =0;
bool m_bSplashShow=false;
};
#endif

@ -173,7 +173,7 @@ void CUserInterface::DisplayWrite (const char *pMenu, const char *pParam, const
assert (pParam);
assert (pValue);
CString Msg ("\x1B[H"); // cursor home
CString Msg ("\x1B[H\E[?25l"); // cursor home and off
// first line
Msg.Append (pParam);

Loading…
Cancel
Save