diff --git a/src/config.h b/src/config.h index da97326..4e615bf 100644 --- a/src/config.h +++ b/src/config.h @@ -64,6 +64,7 @@ public: static const unsigned DefToneGenerators = AllToneGenerators; #endif #endif + static const unsigned SendFX2MixerChannels = AllToneGenerators + 1; // Set maximum polyphony, depending on PI version. This can be changed via config settings #if RASPPI == 1 diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 064720c..8d78175 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -108,7 +108,8 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, m_InsertFXSpinLock[i] = new CSpinLock(); m_InsertFX[i] = new AudioEffect(pConfig->GetSampleRate ()); - m_nReverbSend[i] = 0; + m_nSendFX1[i] = 0; + m_nSendFX2[i] = 0; // Active the required number of active TGs if (i(pConfig->GetChunkSize()/2); // END setup tgmixer - // BEGIN setup reverb - SetParameter (ParameterSendFXType, AudioEffectPlateReverb::ID); - reverb_send_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2); - // END setup reverb + // BEGIN setup send fx + SetParameter (ParameterSendFX1Type, AudioEffectDelay::ID); + //SetParameter (ParameterSendFX1SendFXLevel, 0); + SetParameter (ParameterSendFX2Type, AudioEffectPlateReverb::ID); + send_fx1_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2); + send_fx2_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2); + // END setup send fx SetParameter (ParameterMasterFXType, AudioEffect3BandEQ::ID); @@ -302,9 +306,13 @@ bool CMiniDexed::Initialize (void) tg_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f)); tg_mixer->gain(i,1.0f); - reverb_send_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f)); - reverb_send_mixer->gain(i,mapfloat(m_nReverbSend[i],0,99,0.0f,1.0f)); + send_fx1_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f)); + send_fx1_mixer->gain(i,mapfloat(m_nSendFX1[i],0,99,0.0f,1.0f)); + send_fx2_mixer->pan(i,mapfloat(m_nPan[i],0,127,0.0f,1.0f)); + send_fx2_mixer->gain(i,mapfloat(m_nSendFX2[i],0,99,0.0f,1.0f)); } + send_fx2_mixer->pan(CConfig::SendFX2MixerChannels - 1, 0.5f); + send_fx2_mixer->gain(CConfig::SendFX2MixerChannels - 1, 0.0f); m_PerformanceConfig.Init(m_nToneGenerators); if (m_PerformanceConfig.Load ()) @@ -677,7 +685,8 @@ void CMiniDexed::SetPan (unsigned nPan, unsigned nTG) m_nPan[nTG] = nPan; tg_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f)); - reverb_send_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f)); + send_fx1_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f)); + send_fx2_mixer->pan(nTG,mapfloat(nPan,0,127,0.0f,1.0f)); m_UI.ParameterChanged (); } @@ -730,35 +739,73 @@ std::string CMiniDexed::getMidiFXName (unsigned nTG) return m_MidiArp[nTG]->getName(); } -void CMiniDexed::setSendFXType (unsigned nType) +void CMiniDexed::setSendFX1Type (unsigned nType) { // If the effect type is already set just return - if (m_SendFX != NULL && m_SendFX->getId() == nType) { + if (m_SendFX1 != NULL && m_SendFX1->getId() == nType) { return; } - m_SendFXSpinLock.Acquire(); - if (m_SendFX != NULL) + m_SendFX1SpinLock.Acquire(); + if (m_SendFX1 != NULL) { - delete m_SendFX; + delete m_SendFX1; } - m_SendFX = newAudioEffect(nType, m_pConfig->GetSampleRate()); - m_SendFX->setTempo(m_nTempo); - m_SendFX->initializeSendFX(); - m_SendFXSpinLock.Release(); + m_SendFX1 = newAudioEffect(nType, m_pConfig->GetSampleRate()); + m_SendFX1->setTempo(m_nTempo); + m_SendFX1->initializeSendFX(); + m_SendFX1SpinLock.Release(); m_UI.ParameterChanged (); } -std::string CMiniDexed::getSendFXName () +void CMiniDexed::setSendFX2Type (unsigned nType) { - return m_SendFX->getName(); + // If the effect type is already set just return + if (m_SendFX2 != NULL && m_SendFX2->getId() == nType) { + return; + } + + m_SendFX2SpinLock.Acquire(); + if (m_SendFX2 != NULL) + { + delete m_SendFX2; + } + m_SendFX2 = newAudioEffect(nType, m_pConfig->GetSampleRate()); + m_SendFX2->setTempo(m_nTempo); + m_SendFX2->initializeSendFX(); + m_SendFX2SpinLock.Release(); + + m_UI.ParameterChanged (); +} + +std::string CMiniDexed::getSendFX1Name () +{ + return m_SendFX1->getName(); +} + +std::string CMiniDexed::getSendFX2Name () +{ + return m_SendFX2->getName(); } -void CMiniDexed::setSendFXLevel (unsigned nValue) +void CMiniDexed::setSendFX1SendFXLevel (unsigned nValue) +{ + nValue = constrain((int) nValue, 0, 99); + m_SendFX1SendFXLevel = (float32_t) nValue / 100.0f; + send_fx2_mixer->gain(CConfig::SendFX2MixerChannels - 1, mapfloat(nValue,0,99,0.0f,1.0f)); +} + +void CMiniDexed::setSendFX1Level (unsigned nValue) +{ + nValue = constrain((int)nValue, 0, 100); + m_SendFX1Level = (float32_t) nValue / 100.0f; +} + +void CMiniDexed::setSendFX2Level (unsigned nValue) { nValue = constrain((int)nValue, 0, 100); - m_SendFXLevel = (float32_t) nValue / 100.0f; + m_SendFX2Level = (float32_t) nValue / 100.0f; } void CMiniDexed::setMasterFXType (unsigned nType) @@ -785,6 +832,20 @@ std::string CMiniDexed::getMasterFXName () return m_MasterFX->getName(); } +void CMiniDexed::SetSendFX1 (unsigned nSend, unsigned nTG) +{ + nSend=constrain((int)nSend,0,99); + + assert (nTG < CConfig::AllToneGenerators); + if (nTG >= m_nToneGenerators) return; // Not an active TG + + m_nSendFX1[nTG] = nSend; + + send_fx1_mixer->gain(nTG,mapfloat(nSend,0,99,0.0f,1.0f)); + + m_UI.ParameterChanged (); +} + void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG) { nReverbSend=constrain((int)nReverbSend,0,99); @@ -792,9 +853,9 @@ void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG) assert (nTG < CConfig::AllToneGenerators); if (nTG >= m_nToneGenerators) return; // Not an active TG - m_nReverbSend[nTG] = nReverbSend; + m_nSendFX2[nTG] = nReverbSend; - reverb_send_mixer->gain(nTG,mapfloat(nReverbSend,0,99,0.0f,1.0f)); + send_fx2_mixer->gain(nTG,mapfloat(nReverbSend,0,99,0.0f,1.0f)); m_UI.ParameterChanged (); } @@ -898,7 +959,8 @@ void CMiniDexed::setTempo(unsigned nValue) m_nTempo = nValue; // Set Tempo to FXs - m_SendFX->setTempo(m_nTempo); + m_SendFX1->setTempo(m_nTempo); + m_SendFX2->setTempo(m_nTempo); m_MasterFX->setTempo(m_nTempo); for (unsigned nTG = 0; nTG < CConfig::AllToneGenerators; nTG++) { @@ -1114,12 +1176,24 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue) } break; - case ParameterSendFXType: - setSendFXType(nValue); + case ParameterSendFX1Type: + setSendFX1Type(nValue); + break; + + case ParameterSendFX1SendFXLevel: + setSendFX1SendFXLevel(nValue); + break; + + case ParameterSendFX1Level: + setSendFX1Level(nValue); + break; + + case ParameterSendFX2Type: + setSendFX2Type(nValue); break; - case ParameterSendFXLevel: - setSendFXLevel(nValue); + case ParameterSendFX2Level: + setSendFX2Level(nValue); break; case ParameterMasterFXType: @@ -1151,10 +1225,16 @@ int CMiniDexed::GetParameter (TParameter Parameter) switch (Parameter) { - case ParameterSendFXType: - return m_SendFX->getId(); - case ParameterSendFXLevel: - return roundf(m_SendFXLevel * 100); + case ParameterSendFX1Type: + return m_SendFX1->getId(); + case ParameterSendFX2Type: + return m_SendFX2->getId(); + case ParameterSendFX1SendFXLevel: + return roundf(m_SendFX1SendFXLevel * 100); + case ParameterSendFX1Level: + return roundf(m_SendFX1Level * 100); + case ParameterSendFX2Level: + return roundf(m_SendFX2Level * 100); case ParameterMasterFXType: return m_MasterFX->getId(); case ParameterTempo: @@ -1212,6 +1292,7 @@ void CMiniDexed::SetTGParameter (TTGParameter Parameter, int nValue, unsigned nT SetMIDIChannel ((uint8_t) nValue, nTG); break; + case TGParameterSendFX1: SetSendFX1 (nValue, nTG); break; case TGParameterReverbSend: SetReverbSend (nValue, nTG); break; case TGParameterInsertFXType: setInsertFXType(nValue, nTG); break; case TGParameterMidiFXType: setMidiFXType(nValue, nTG); break; @@ -1238,7 +1319,8 @@ int CMiniDexed::GetTGParameter (TTGParameter Parameter, unsigned nTG) case TGParameterCutoff: return m_nCutoff[nTG]; case TGParameterResonance: return m_nResonance[nTG]; case TGParameterMIDIChannel: return m_nMIDIChannel[nTG]; - case TGParameterReverbSend: return m_nReverbSend[nTG]; + case TGParameterSendFX1: return m_nSendFX1[nTG]; + case TGParameterReverbSend: return m_nSendFX2[nTG]; case TGParameterInsertFXType: return m_InsertFX[nTG]->getId(); case TGParameterMidiFXType: return m_MidiArp[nTG]->getId(); case TGParameterPitchBendRange: return m_nPitchBendRange[nTG]; @@ -1302,16 +1384,28 @@ int CMiniDexed::GetTGFXParameter (unsigned Parameter, unsigned nTG, unsigned nFX return m_InsertFX[nTG]->getParameter(Parameter); } -void CMiniDexed::SetSendFXParameter (unsigned Parameter, int nValue, unsigned nFXType) { - assert (m_SendFX->getId() == nFXType); +void CMiniDexed::SetSendFX1Parameter (unsigned Parameter, int nValue, unsigned nFXType) { + assert (m_SendFX1->getId() == nFXType); - m_SendFX->setParameter(Parameter, nValue); + m_SendFX1->setParameter(Parameter, nValue); } -int CMiniDexed::GetSendFXParameter (unsigned Parameter, unsigned nFXType) { - assert (m_SendFX->getId() == nFXType); +void CMiniDexed::SetSendFX2Parameter (unsigned Parameter, int nValue, unsigned nFXType) { + assert (m_SendFX2->getId() == nFXType); - return m_SendFX->getParameter(Parameter); + m_SendFX2->setParameter(Parameter, nValue); +} + +int CMiniDexed::GetSendFX1Parameter (unsigned Parameter, unsigned nFXType) { + assert (m_SendFX1->getId() == nFXType); + + return m_SendFX1->getParameter(Parameter); +} + +int CMiniDexed::GetSendFX2Parameter (unsigned Parameter, unsigned nFXType) { + assert (m_SendFX2->getId() == nFXType); + + return m_SendFX2->getParameter(Parameter); } void CMiniDexed::SetMasterFXParameter (unsigned Parameter, int nValue, unsigned nFXType) { @@ -1428,29 +1522,49 @@ void CMiniDexed::ProcessSound (void) m_InsertFX[0]->process(SampleBuffer[indexL], SampleBuffer[indexL], SampleBuffer[indexL], SampleBuffer[indexR], nFrames); m_InsertFXSpinLock[0]->Release(); - reverb_send_mixer->doAddMix(0, SampleBuffer[indexL], SampleBuffer[indexR]); + send_fx1_mixer->doAddMix(0, SampleBuffer[indexL], SampleBuffer[indexR]); + send_fx2_mixer->doAddMix(0, SampleBuffer[indexL], SampleBuffer[indexR]); + + // BEGIN adding send fx 1 + float32_t SendFXOutputBuffer[2][nFrames]; + float32_t SendFXMixBuffer[2][nFrames]; + arm_fill_f32(0.0f, SendFXOutputBuffer[indexL], nFrames); + arm_fill_f32(0.0f, SendFXOutputBuffer[indexR], nFrames); + arm_fill_f32(0.0f, SendFXMixBuffer[indexR], nFrames); + arm_fill_f32(0.0f, SendFXMixBuffer[indexL], nFrames); + + m_SendFX1SpinLock.Acquire (); + send_fx1_mixer->getMix(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR]); + m_SendFX1->process(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR], SendFXOutputBuffer[indexL], SendFXOutputBuffer[indexR], nFrames); + m_SendFX1SpinLock.Release (); - float32_t ReverbBuffer[2][nFrames]; - float32_t ReverbSendBuffer[2][nFrames]; + // send to FX 2 + arm_scale_f32(SendFXOutputBuffer[indexL], m_SendFX1SendFXLevel, SendFXMixBuffer[indexL], nFrames); + arm_scale_f32(SendFXOutputBuffer[indexR], m_SendFX1SendFXLevel, SendFXMixBuffer[indexR], nFrames); + send_fx2_mixer->doAddMix(CConfig::SendFX2MixerChannels - 1, SendFXMixBuffer[indexL], SendFXMixBuffer[indexR]); - arm_fill_f32(0.0f, ReverbBuffer[indexL], nFrames); - arm_fill_f32(0.0f, ReverbBuffer[indexR], nFrames); - arm_fill_f32(0.0f, ReverbSendBuffer[indexR], nFrames); - arm_fill_f32(0.0f, ReverbSendBuffer[indexL], nFrames); + // scale down and add left reverb buffer by reverb level + arm_scale_f32(SendFXOutputBuffer[indexL], m_SendFX1Level, SendFXOutputBuffer[indexL], nFrames); + arm_add_f32(SampleBuffer[indexL], SendFXOutputBuffer[indexL], SampleBuffer[indexL], nFrames); + // scale down and add right reverb buffer by reverb level + arm_scale_f32(SendFXOutputBuffer[indexR], m_SendFX1Level, SendFXOutputBuffer[indexR], nFrames); + arm_add_f32(SampleBuffer[indexR], SendFXOutputBuffer[indexR], SampleBuffer[indexR], nFrames); + // END adding send fx 1 - m_SendFXSpinLock.Acquire (); - reverb_send_mixer->getMix(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR]); - m_SendFX->process(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR], ReverbBuffer[indexL], ReverbBuffer[indexR], nFrames); + // BEGIN adding send fx 2 + m_SendFX2SpinLock.Acquire (); + send_fx2_mixer->getMix(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR]); + m_SendFX2->process(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR], SendFXOutputBuffer[indexL], SendFXOutputBuffer[indexR], nFrames); + m_SendFX2SpinLock.Release (); // scale down and add left reverb buffer by reverb level - arm_scale_f32(ReverbBuffer[indexL], m_SendFXLevel, ReverbBuffer[indexL], nFrames); - arm_add_f32(SampleBuffer[indexL], ReverbBuffer[indexL], SampleBuffer[indexL], nFrames); + arm_scale_f32(SendFXOutputBuffer[indexL], m_SendFX2Level, SendFXOutputBuffer[indexL], nFrames); + arm_add_f32(SampleBuffer[indexL], SendFXOutputBuffer[indexL], SampleBuffer[indexL], nFrames); // scale down and add right reverb buffer by reverb level - arm_scale_f32(ReverbBuffer[indexR], m_SendFXLevel, ReverbBuffer[indexR], nFrames); - arm_add_f32(SampleBuffer[indexR], ReverbBuffer[indexR], SampleBuffer[indexR], nFrames); - - m_SendFXSpinLock.Release (); + arm_scale_f32(SendFXOutputBuffer[indexR], m_SendFX2Level, SendFXOutputBuffer[indexR], nFrames); + arm_add_f32(SampleBuffer[indexR], SendFXOutputBuffer[indexR], SampleBuffer[indexR], nFrames); + // END adding send fx 2 m_MasterFXSpinLock.Acquire (); m_MasterFX->process(SampleBuffer[indexL], SampleBuffer[indexR], SampleBuffer[indexL], SampleBuffer[indexR], nFrames); @@ -1595,7 +1709,8 @@ void CMiniDexed::ProcessSound (void) for (uint8_t i = 0; i < m_nToneGenerators; i++) { tg_mixer->doAddMix(i, m_OutputLevel[i][indexL], m_OutputLevel[i][indexR]); - reverb_send_mixer->doAddMix(i, m_OutputLevel[i][indexL], m_OutputLevel[i][indexR]); + send_fx1_mixer->doAddMix(i, m_OutputLevel[i][indexL], m_OutputLevel[i][indexR]); + send_fx2_mixer->doAddMix(i, m_OutputLevel[i][indexL], m_OutputLevel[i][indexR]); } // END TG mixing @@ -1606,29 +1721,45 @@ void CMiniDexed::ProcessSound (void) // get the mix of all TGs tg_mixer->getMix(SampleBuffer[indexL], SampleBuffer[indexR]); - // BEGIN adding reverb - float32_t ReverbBuffer[2][nFrames]; - float32_t ReverbSendBuffer[2][nFrames]; - - arm_fill_f32(0.0f, ReverbBuffer[indexL], nFrames); - arm_fill_f32(0.0f, ReverbBuffer[indexR], nFrames); - arm_fill_f32(0.0f, ReverbSendBuffer[indexR], nFrames); - arm_fill_f32(0.0f, ReverbSendBuffer[indexL], nFrames); + // BEGIN adding send fx 1 + float32_t SendFXOutputBuffer[2][nFrames]; + float32_t SendFXMixBuffer[2][nFrames]; + arm_fill_f32(0.0f, SendFXOutputBuffer[indexL], nFrames); + arm_fill_f32(0.0f, SendFXOutputBuffer[indexR], nFrames); + arm_fill_f32(0.0f, SendFXMixBuffer[indexR], nFrames); + arm_fill_f32(0.0f, SendFXMixBuffer[indexL], nFrames); + + m_SendFX1SpinLock.Acquire (); + send_fx1_mixer->getMix(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR]); + m_SendFX1->process(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR], SendFXOutputBuffer[indexL], SendFXOutputBuffer[indexR], nFrames); + m_SendFX1SpinLock.Release (); + + // send to FX 2 + arm_scale_f32(SendFXOutputBuffer[indexL], m_SendFX1SendFXLevel, SendFXMixBuffer[indexL], nFrames); + arm_scale_f32(SendFXOutputBuffer[indexR], m_SendFX1SendFXLevel, SendFXMixBuffer[indexR], nFrames); + send_fx2_mixer->doAddMix(CConfig::SendFX2MixerChannels - 1, SendFXMixBuffer[indexL], SendFXMixBuffer[indexR]); - m_SendFXSpinLock.Acquire (); + // scale down and add left reverb buffer by reverb level + arm_scale_f32(SendFXOutputBuffer[indexL], m_SendFX1Level, SendFXOutputBuffer[indexL], nFrames); + arm_add_f32(SampleBuffer[indexL], SendFXOutputBuffer[indexL], SampleBuffer[indexL], nFrames); + // scale down and add right reverb buffer by reverb level + arm_scale_f32(SendFXOutputBuffer[indexR], m_SendFX1Level, SendFXOutputBuffer[indexR], nFrames); + arm_add_f32(SampleBuffer[indexR], SendFXOutputBuffer[indexR], SampleBuffer[indexR], nFrames); + // END adding send fx 1 - reverb_send_mixer->getMix(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR]); - m_SendFX->process(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR], ReverbBuffer[indexL], ReverbBuffer[indexR], nFrames); + // BEGIN adding send fx 2 + m_SendFX2SpinLock.Acquire (); + send_fx2_mixer->getMix(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR]); + m_SendFX2->process(SendFXMixBuffer[indexL], SendFXMixBuffer[indexR], SendFXOutputBuffer[indexL], SendFXOutputBuffer[indexR], nFrames); + m_SendFX2SpinLock.Release (); // scale down and add left reverb buffer by reverb level - arm_scale_f32(ReverbBuffer[indexL], m_SendFXLevel, ReverbBuffer[indexL], nFrames); - arm_add_f32(SampleBuffer[indexL], ReverbBuffer[indexL], SampleBuffer[indexL], nFrames); + arm_scale_f32(SendFXOutputBuffer[indexL], m_SendFX2Level, SendFXOutputBuffer[indexL], nFrames); + arm_add_f32(SampleBuffer[indexL], SendFXOutputBuffer[indexL], SampleBuffer[indexL], nFrames); // scale down and add right reverb buffer by reverb level - arm_scale_f32(ReverbBuffer[indexR], m_SendFXLevel, ReverbBuffer[indexR], nFrames); - arm_add_f32(SampleBuffer[indexR], ReverbBuffer[indexR], SampleBuffer[indexR], nFrames); - - m_SendFXSpinLock.Release (); - // END adding reverb + arm_scale_f32(SendFXOutputBuffer[indexR], m_SendFX2Level, SendFXOutputBuffer[indexR], nFrames); + arm_add_f32(SampleBuffer[indexR], SendFXOutputBuffer[indexR], SampleBuffer[indexR], nFrames); + // END adding send fx 2 m_MasterFXSpinLock.Acquire (); m_MasterFX->process(SampleBuffer[indexL], SampleBuffer[indexR], SampleBuffer[indexL], SampleBuffer[indexR], nFrames); @@ -1769,17 +1900,17 @@ bool CMiniDexed::DoSavePerformance (void) m_PerformanceConfig.SetAftertouchRange (m_nAftertouchRange[nTG], nTG); m_PerformanceConfig.SetAftertouchTarget (m_nAftertouchTarget[nTG], nTG); - m_PerformanceConfig.SetReverbSend (m_nReverbSend[nTG], nTG); + m_PerformanceConfig.SetReverbSend (m_nSendFX2[nTG], nTG); } m_PerformanceConfig.SetCompressorEnable (!!m_nParameter[ParameterCompressorEnable]); - m_PerformanceConfig.SetSendFX (m_SendFX->getId()); - std::vector pParams = m_SendFX->getParameters(); - m_PerformanceConfig.SetSendFXParams (pParams); + m_PerformanceConfig.SetSendFX2 (m_SendFX2->getId()); + std::vector pParams = m_SendFX2->getParameters(); + m_PerformanceConfig.SetSendFX2Params (pParams); pParams.clear(); pParams.shrink_to_fit(); - m_PerformanceConfig.SetSendFXLevel (roundf(m_SendFXLevel * 100)); + m_PerformanceConfig.SetSendFX2Level (roundf(m_SendFX2Level * 100)); m_PerformanceConfig.SetMasterFX (m_MasterFX->getId()); std::vector pMasterParams = m_MasterFX->getParameters(); @@ -2275,12 +2406,12 @@ void CMiniDexed::LoadPerformanceParameters(void) // Effects SetParameter (ParameterCompressorEnable, m_PerformanceConfig.GetCompressorEnable () ? 1 : 0); - setSendFXType(m_PerformanceConfig.GetSendFX ()); - std::vector pParams = m_PerformanceConfig.GetSendFXParams (); - m_SendFX->setParameters(pParams); + setSendFX2Type(m_PerformanceConfig.GetSendFX2 ()); + std::vector pParams = m_PerformanceConfig.GetSendFX2Params (); + m_SendFX2->setParameters(pParams); pParams.clear(); pParams.shrink_to_fit(); - SetParameter (ParameterSendFXLevel, m_PerformanceConfig.GetSendFXLevel ()); + SetParameter (ParameterSendFX2Level, m_PerformanceConfig.GetSendFX2Level ()); setMasterFXType(m_PerformanceConfig.GetMasterFX ()); std::vector pMasterParams = m_PerformanceConfig.GetMasterFXParams (); diff --git a/src/minidexed.h b/src/minidexed.h index 3afabff..21c4545 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -106,12 +106,17 @@ public: std::string getInsertFXName (unsigned nTG); void setMidiFXType (unsigned nType, unsigned nTG); std::string getMidiFXName (unsigned nTG); - void setSendFXType (unsigned nType); - std::string getSendFXName (); - void setSendFXLevel (unsigned nValue); + void setSendFX1Type (unsigned nType); + std::string getSendFX1Name (); + void setSendFX1SendFXLevel (unsigned nValue); + void setSendFX1Level (unsigned nValue); + void setSendFX2Type (unsigned nType); + std::string getSendFX2Name (); + void setSendFX2Level (unsigned nValue); void setMasterFXType (unsigned nType); std::string getMasterFXName (); - + + void SetSendFX1 (unsigned nSend, unsigned nTG); void SetReverbSend (unsigned nReverbSend, unsigned nTG); // 0 .. 127 void setMonoMode(uint8_t mono, uint8_t nTG); @@ -166,8 +171,11 @@ public: enum TParameter { ParameterCompressorEnable, - ParameterSendFXType, - ParameterSendFXLevel, + ParameterSendFX1Type, + ParameterSendFX1SendFXLevel, + ParameterSendFX1Level, + ParameterSendFX2Type, + ParameterSendFX2Level, ParameterMasterFXType, ParameterPerformanceSelectChannel, ParameterPerformanceBank, @@ -199,6 +207,7 @@ public: TGParameterCutoff, TGParameterResonance, TGParameterMIDIChannel, + TGParameterSendFX1, TGParameterReverbSend, TGParameterPitchBendRange, TGParameterPitchBendStep, @@ -239,8 +248,11 @@ public: void SetTGFXParameter (unsigned Parameter, int nValue, unsigned nTG, unsigned nFXType); int GetTGFXParameter (unsigned Parameter, unsigned nTG, unsigned nFXType); - void SetSendFXParameter (unsigned Parameter, int nValue, unsigned nFXType); - int GetSendFXParameter (unsigned Parameter, unsigned nFXType); + void SetSendFX1Parameter (unsigned Parameter, int nValue, unsigned nFXType); + int GetSendFX1Parameter (unsigned Parameter, unsigned nFXType); + + void SetSendFX2Parameter (unsigned Parameter, int nValue, unsigned nFXType); + int GetSendFX2Parameter (unsigned Parameter, unsigned nFXType); void SetMasterFXParameter (unsigned Parameter, int nValue, unsigned nFXType); int GetMasterFXParameter (unsigned Parameter, unsigned nFXType); @@ -307,7 +319,7 @@ private: unsigned m_nFootControlRange[CConfig::AllToneGenerators]; unsigned m_nFootControlTarget[CConfig::AllToneGenerators]; unsigned m_nBreathControlRange[CConfig::AllToneGenerators]; - unsigned m_nBreathControlTarget[CConfig::AllToneGenerators]; + unsigned m_nBreathControlTarget[CConfig::AllToneGenerators]; unsigned m_nAftertouchRange[CConfig::AllToneGenerators]; unsigned m_nAftertouchTarget[CConfig::AllToneGenerators]; @@ -317,7 +329,8 @@ private: MidiEffect* m_MidiArp[CConfig::AllToneGenerators]; AudioEffect* m_InsertFX[CConfig::AllToneGenerators]; - unsigned m_nReverbSend[CConfig::AllToneGenerators]; + unsigned m_nSendFX1[CConfig::AllToneGenerators]; + unsigned m_nSendFX2[CConfig::AllToneGenerators]; uint8_t m_nRawVoiceData[156]; @@ -349,14 +362,19 @@ private: bool m_bProfileEnabled; AudioStereoMixer* tg_mixer; - AudioStereoMixer* reverb_send_mixer; - AudioEffect* m_SendFX = NULL; - float32_t m_SendFXLevel = 1.0f; + AudioStereoMixer* send_fx1_mixer; + AudioStereoMixer* send_fx2_mixer; + AudioEffect* m_SendFX1 = NULL; + AudioEffect* m_SendFX2 = NULL; + float32_t m_SendFX1SendFXLevel = 0.0f; + float32_t m_SendFX1Level = 1.0f; + float32_t m_SendFX2Level = 1.0f; AudioEffect* m_MasterFX = NULL; CSpinLock* m_MidiArpSpinLock[CConfig::AllToneGenerators]; CSpinLock* m_InsertFXSpinLock[CConfig::AllToneGenerators]; - CSpinLock m_SendFXSpinLock; + CSpinLock m_SendFX1SpinLock; + CSpinLock m_SendFX2SpinLock; CSpinLock m_MasterFXSpinLock; bool m_bSavePerformance; diff --git a/src/performanceconfig.cpp b/src/performanceconfig.cpp index f5a8eec..4f1abda 100644 --- a/src/performanceconfig.cpp +++ b/src/performanceconfig.cpp @@ -237,13 +237,23 @@ bool CPerformanceConfig::Load (void) m_nTempo = m_Properties.GetNumber ("Tempo", 120); + m_nSendFX1 = m_Properties.GetNumber ("SendFX1", 7); + m_sSendFX1Params = m_Properties.GetString ("SendFX1Params", ""); + m_nSendFX1SendLevel = m_Properties.GetNumber ("SendFX1SendLevel", 0); + m_nSendFX1Level = m_Properties.GetNumber ("SendFX1Level", 100); + // Set EFFECT_REVERB as Default for backward compatibility // EFFECT_REVERB 7 - m_nSendFX = m_Properties.GetNumber ("SendFX", 7); - m_sSendFXParams = m_Properties.GetString ("SendFXParams", ""); - m_nSendFXLevel = m_Properties.GetNumber ("SendFXLevel", m_nReverbLevel); - if (m_nSendFX == 7 && m_sSendFXParams.empty()) { - m_sSendFXParams = std::to_string(m_bReverbEnable == 1 ? 0 : 1) + "," + std::to_string(m_nReverbSize) + "," + // Support for first FX version with only one send effect for backward compatibility + m_nSendFX2 = m_Properties.GetNumber ("SendFX", 7); + m_sSendFX2Params = m_Properties.GetString ("SendFXParams", ""); + m_nSendFX2Level = m_Properties.GetNumber ("SendFXLevel", m_nReverbLevel); + // Now read the new values, but use previous values as default + m_nSendFX2 = m_Properties.GetNumber ("SendFX2", m_nSendFX2); + m_sSendFX2Params = m_Properties.GetString ("SendFX2Params", m_sSendFX2Params.c_str()); + m_nSendFX2Level = m_Properties.GetNumber ("SendFX2Level", m_nSendFX2Level); + if (m_nSendFX2 == 7 && m_sSendFX2Params.empty()) { + m_sSendFX2Params = std::to_string(m_bReverbEnable == 1 ? 0 : 1) + "," + std::to_string(m_nReverbSize) + "," + std::to_string(m_nReverbHighDamp) + "," + std::to_string(m_nReverbLowDamp) + "," + std::to_string(m_nReverbLowPass) + "," + std::to_string(m_nReverbDiffusion) + "," + std::to_string(100); @@ -375,16 +385,21 @@ bool CPerformanceConfig::Save (void) m_Properties.SetNumber ("CompressorEnable", m_bCompressorEnable ? 1 : 0); - m_Properties.SetNumber ("SendFX", m_nSendFX); - m_Properties.SetString ("SendFXParams", m_sSendFXParams.c_str()); - m_Properties.SetNumber ("SendFXLevel", m_nSendFXLevel); + m_Properties.SetNumber ("SendFX1", m_nSendFX1); + m_Properties.SetString ("SendFX1Params", m_sSendFX1Params.c_str()); + m_Properties.SetNumber ("SendFX1SendLevel", m_nSendFX1SendLevel); + m_Properties.SetNumber ("SendFX1Level", m_nSendFX1Level); + + m_Properties.SetNumber ("SendFX2", m_nSendFX2); + m_Properties.SetString ("SendFX2Params", m_sSendFX2Params.c_str()); + m_Properties.SetNumber ("SendFX2Level", m_nSendFX2Level); // For backward compatibility // EFFECT_REVERB 7 - if (m_nSendFX == 7) + if (m_nSendFX2 == 7) { std::vector tokens; - std::string params = m_sSendFXParams; + std::string params = m_sSendFX2Params; char delimiter = ','; std::stringstream ss(params); std::string temp; @@ -419,7 +434,7 @@ bool CPerformanceConfig::Save (void) break; } } - m_Properties.SetNumber ("ReverbLevel", m_nSendFXLevel); + m_Properties.SetNumber ("ReverbLevel", m_nSendFX2Level); tokens.clear(); tokens.shrink_to_fit(); @@ -630,19 +645,39 @@ bool CPerformanceConfig::GetCompressorEnable (void) const return m_bCompressorEnable; } -unsigned CPerformanceConfig::GetSendFX (void) const +unsigned CPerformanceConfig::GetSendFX1 (void) const +{ + return m_nSendFX1; +} + +unsigned CPerformanceConfig::GetSendFX2 (void) const +{ + return m_nSendFX2; +} + +std::vector CPerformanceConfig::GetSendFX1Params (void) const +{ + return StringToVector(m_sSendFX1Params); +} + +std::vector CPerformanceConfig::GetSendFX2Params (void) const +{ + return StringToVector(m_sSendFX2Params); +} + +unsigned CPerformanceConfig::GetSendFX1SendLevel (void) const { - return m_nSendFX; + return m_nSendFX1SendLevel; } -std::vector CPerformanceConfig::GetSendFXParams (void) const +unsigned CPerformanceConfig::GetSendFX1Level (void) const { - return StringToVector(m_sSendFXParams); + return m_nSendFX1Level; } -unsigned CPerformanceConfig::GetSendFXLevel (void) const +unsigned CPerformanceConfig::GetSendFX2Level (void) const { - return m_nSendFXLevel; + return m_nSendFX2Level; } unsigned CPerformanceConfig::GetMasterFX (void) const @@ -700,19 +735,39 @@ void CPerformanceConfig::SetCompressorEnable (bool bValue) m_bCompressorEnable = bValue; } -void CPerformanceConfig::SetSendFX (unsigned nValue) +void CPerformanceConfig::SetSendFX1 (unsigned nValue) +{ + m_nSendFX1 = nValue; +} + +void CPerformanceConfig::SetSendFX2 (unsigned nValue) +{ + m_nSendFX1 = nValue; +} + +void CPerformanceConfig::SetSendFX1Params (std::vector pParams) +{ + m_sSendFX1Params = VectorToString(pParams); +} + +void CPerformanceConfig::SetSendFX2Params (std::vector pParams) +{ + m_sSendFX2Params = VectorToString(pParams); +} + +void CPerformanceConfig::SetSendFX1SendLevel (unsigned nValue) { - m_nSendFX = nValue; + m_nSendFX1SendLevel = nValue; } -void CPerformanceConfig::SetSendFXParams (std::vector pParams) +void CPerformanceConfig::SetSendFX1Level (unsigned nValue) { - m_sSendFXParams = VectorToString(pParams); + m_nSendFX1Level = nValue; } -void CPerformanceConfig::SetSendFXLevel (unsigned nValue) +void CPerformanceConfig::SetSendFX2Level (unsigned nValue) { - m_nSendFXLevel = nValue; + m_nSendFX2Level = nValue; } void CPerformanceConfig::SetMasterFX (unsigned nValue) diff --git a/src/performanceconfig.h b/src/performanceconfig.h index c1cbfb6..df81f4c 100644 --- a/src/performanceconfig.h +++ b/src/performanceconfig.h @@ -112,9 +112,13 @@ public: // Effects bool GetCompressorEnable (void) const; - unsigned GetSendFX (void) const; - std::vector GetSendFXParams (void) const; - unsigned GetSendFXLevel (void) const; + unsigned GetSendFX1 (void) const; + std::vector GetSendFX1Params (void) const; + unsigned GetSendFX1SendLevel (void) const; + unsigned GetSendFX1Level (void) const; + unsigned GetSendFX2 (void) const; + std::vector GetSendFX2Params (void) const; + unsigned GetSendFX2Level (void) const; unsigned GetMasterFX (void) const; std::vector GetMasterFXParams (void) const; bool GetReverbEnable (void) const; @@ -127,9 +131,13 @@ public: unsigned GetTempo (void) const; void SetCompressorEnable (bool bValue); - void SetSendFX (unsigned nValue); - void SetSendFXParams (std::vector pParams); - void SetSendFXLevel (unsigned nValue); + void SetSendFX1 (unsigned nValue); + void SetSendFX1Params (std::vector pParams); + void SetSendFX1SendLevel (unsigned nValue); + void SetSendFX1Level (unsigned nValue); + void SetSendFX2 (unsigned nValue); + void SetSendFX2Params (std::vector pParams); + void SetSendFX2Level (unsigned nValue); void SetMasterFX (unsigned nValue); void SetMasterFXParams (std::vector pParams); void SetReverbEnable (bool bValue); @@ -222,9 +230,13 @@ private: std::string NewPerformanceName=""; bool m_bCompressorEnable; - unsigned m_nSendFX; - std::string m_sSendFXParams; - unsigned m_nSendFXLevel; + unsigned m_nSendFX1; + std::string m_sSendFX1Params; + unsigned m_nSendFX1SendLevel; + unsigned m_nSendFX1Level; + unsigned m_nSendFX2; + std::string m_sSendFX2Params; + unsigned m_nSendFX2Level; unsigned m_nMasterFX; std::string m_sMasterFXParams; bool m_bReverbEnable; diff --git a/src/uimenu.cpp b/src/uimenu.cpp index e60b1d8..21273a5 100644 --- a/src/uimenu.cpp +++ b/src/uimenu.cpp @@ -77,7 +77,8 @@ const CUIMenu::TMenuItem CUIMenu::s_TGMenu[] = {"Pan", EditTGParameter, 0, CMiniDexed::TGParameterPan}, #endif {"Insert FX", MenuHandlerInsertFX}, - {"Send FX", EditTGParameter, 0, CMiniDexed::TGParameterReverbSend}, + {"Send FX 1", EditTGParameter, 0, CMiniDexed::TGParameterSendFX1}, + {"Send FX 2", EditTGParameter, 0, CMiniDexed::TGParameterReverbSend}, {"Detune", EditTGParameter, 0, CMiniDexed::TGParameterMasterTune}, {"Cutoff", EditTGParameter, 0, CMiniDexed::TGParameterCutoff}, {"Resonance", EditTGParameter, 0, CMiniDexed::TGParameterResonance}, @@ -94,7 +95,8 @@ const CUIMenu::TMenuItem CUIMenu::s_TGMenu[] = const CUIMenu::TMenuItem CUIMenu::s_EffectsMenu[] = { {"Compress", EditGlobalParameter, 0, CMiniDexed::ParameterCompressorEnable}, - {"Send FX", MenuHandlerSendFX}, + {"Send FX 1", MenuHandlerSendFX1}, + {"Send FX 2", MenuHandlerSendFX2}, {"Master FX", MenuHandlerMasterFX}, {0} }; @@ -132,11 +134,20 @@ const CUIMenu::TMenuItem CUIMenu::s_ModulationMenuParameters[] = {0} }; -const CUIMenu::TMenuItem CUIMenu::s_SendFXMenu[] = +const CUIMenu::TMenuItem CUIMenu::s_SendFX1Menu[] = { - {"Type:", EditGlobalParameter, 0, CMiniDexed::ParameterSendFXType}, - {"Edit:", EditSendFX}, - {"Level", EditGlobalParameter, 0, CMiniDexed::ParameterSendFXLevel}, + {"Type:", EditGlobalParameter, 0, CMiniDexed::ParameterSendFX1Type}, + {"Edit:", EditSendFX1}, + {"To FX 2", EditGlobalParameter, 0, CMiniDexed::ParameterSendFX1SendFXLevel}, + {"Level", EditGlobalParameter, 0, CMiniDexed::ParameterSendFX1Level}, + {0} +}; + +const CUIMenu::TMenuItem CUIMenu::s_SendFX2Menu[] = +{ + {"Type:", EditGlobalParameter, 0, CMiniDexed::ParameterSendFX2Type}, + {"Edit:", EditSendFX2}, + {"Level", EditGlobalParameter, 0, CMiniDexed::ParameterSendFX2Level}, {0} }; @@ -418,8 +429,11 @@ const CUIMenu::TMenuItem CUIMenu::s_SaveMenu[] = const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknown] = { {0, 1, 1, ToOnOff}, // ParameterCompressorEnable - {0, AudioEffects::Types::UNKNOWN - 1, 1, ToFXType}, // ParameterSendFXType - {0, 100, 1}, // ParameterSendFXLevel + {0, AudioEffects::Types::UNKNOWN - 1, 1, ToFXType}, // ParameterSendFX1Type + {0, 99, 1}, // ParameterSendFX1SendFXLevel + {0, 100, 1}, // ParameterSendFX2Level + {0, AudioEffects::Types::UNKNOWN - 1, 1, ToFXType}, // ParameterSendFX2Type + {0, 100, 1}, // ParameterSendFX2Level {0, AudioEffects::Types::UNKNOWN - 1, 1, ToFXType}, // ParameterMasterFXType {0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // ParameterPerformanceSelectChannel {0, NUM_PERFORMANCE_BANKS, 1}, // ParameterPerformanceBank @@ -441,6 +455,7 @@ const CUIMenu::TParameter CUIMenu::s_TGParameter[CMiniDexed::TGParameterUnknown] {0, 99, 1}, // TGParameterCutoff {0, 99, 1}, // TGParameterResonance {0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // TGParameterMIDIChannel + {0, 100, 1}, // TGParameterSendFX1 {0, 100, 1}, // TGParameterReverbSend {0, 12, 1}, // TGParameterPitchBendRange {0, 12, 1}, // TGParameterPitchBendStep @@ -1181,12 +1196,12 @@ void CUIMenu::MenuHandlerInsertFX (CUIMenu *pUIMenu, TMenuEvent Event) } } -void CUIMenu::MenuHandlerSendFX (CUIMenu *pUIMenu, TMenuEvent Event) +void CUIMenu::MenuHandlerSendFX1 (CUIMenu *pUIMenu, TMenuEvent Event) { // Setup menu when it's open if (!pUIMenu->m_pCurrentMenu) { - pUIMenu->m_pCurrentMenu = s_SendFXMenu; + pUIMenu->m_pCurrentMenu = s_SendFX1Menu; } switch (Event) @@ -1242,7 +1257,91 @@ void CUIMenu::MenuHandlerSendFX (CUIMenu *pUIMenu, TMenuEvent Event) if (pUIMenu->m_pCurrentMenu) // if this is another menu? { // Get current FX Name - std::string fxName = pUIMenu->m_pMiniDexed->getSendFXName(); + std::string fxName = pUIMenu->m_pMiniDexed->getSendFX1Name(); + + // Create Paramter with type label + std::string value; + value.append(pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Name); + if (pUIMenu->m_nCurrentSelection < 2) + { + value.append(fxName); + } + + pUIMenu->m_pUI->DisplayWrite ( + pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name, + "", + value.c_str(), + pUIMenu->m_nCurrentSelection > 0, + !!pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection+1].Name); + } + else + { + pUIMenu->EventHandler (MenuEventUpdate); // no, update parameter display + } +} + +void CUIMenu::MenuHandlerSendFX2 (CUIMenu *pUIMenu, TMenuEvent Event) +{ + // Setup menu when it's open + if (!pUIMenu->m_pCurrentMenu) + { + pUIMenu->m_pCurrentMenu = s_SendFX2Menu; + } + + switch (Event) + { + case MenuEventUpdate: + break; + + case MenuEventSelect: // push menu + assert (pUIMenu->m_nCurrentMenuDepth < MaxMenuDepth); + pUIMenu->m_MenuStackParent[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pParentMenu; + pUIMenu->m_MenuStackMenu[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pCurrentMenu; + pUIMenu->m_nMenuStackItem[pUIMenu->m_nCurrentMenuDepth] + = pUIMenu->m_nCurrentMenuItem; + pUIMenu->m_nMenuStackSelection[pUIMenu->m_nCurrentMenuDepth] + = pUIMenu->m_nCurrentSelection; + pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth] + = pUIMenu->m_nCurrentParameter; + pUIMenu->m_nCurrentMenuDepth++; + + pUIMenu->m_pParentMenu = pUIMenu->m_pCurrentMenu; + pUIMenu->m_nCurrentParameter = + pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Parameter; + pUIMenu->m_pCurrentMenu = + pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].MenuItem; + pUIMenu->m_nCurrentMenuItem = pUIMenu->m_nCurrentSelection; + pUIMenu->m_nCurrentSelection = 0; + break; + + case MenuEventStepDown: + if (pUIMenu->m_nCurrentSelection > 0) + { + pUIMenu->m_nCurrentSelection--; + } + break; + + case MenuEventStepUp: + ++pUIMenu->m_nCurrentSelection; + if (!pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Name) // more entries? + { + pUIMenu->m_nCurrentSelection--; + } + break; + + case MenuEventPressAndStepDown: + case MenuEventPressAndStepUp: + pUIMenu->TGShortcutHandler (Event); + return; + + default: + return; + } + + if (pUIMenu->m_pCurrentMenu) // if this is another menu? + { + // Get current FX Name + std::string fxName = pUIMenu->m_pMiniDexed->getSendFX2Name(); // Create Paramter with type label std::string value; @@ -1901,10 +2000,10 @@ void CUIMenu::EditTGFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) nValue > rParam.Minimum, nValue < rParam.Maximum); } -void CUIMenu::EditSendFX (CUIMenu *pUIMenu, TMenuEvent Event) +void CUIMenu::EditSendFX1 (CUIMenu *pUIMenu, TMenuEvent Event) { - int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterSendFXType); - pUIMenu->m_pCurrentMenu = getSendFXMenuItem(nFXType); + int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterSendFX1Type); + pUIMenu->m_pCurrentMenu = getSendFX1MenuItem(nFXType); switch (Event) { @@ -1957,7 +2056,7 @@ void CUIMenu::EditSendFX (CUIMenu *pUIMenu, TMenuEvent Event) if (pUIMenu->m_pCurrentMenu) // if this is another menu? { - string fxName = pUIMenu->m_pMiniDexed->getSendFXName(); + string fxName = pUIMenu->m_pMiniDexed->getSendFX1Name(); pUIMenu->m_pUI->DisplayWrite ( fxName.c_str(), @@ -1972,17 +2071,151 @@ void CUIMenu::EditSendFX (CUIMenu *pUIMenu, TMenuEvent Event) } } -void CUIMenu::EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) +void CUIMenu::EditSendFX2 (CUIMenu *pUIMenu, TMenuEvent Event) +{ + int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterSendFX2Type); + pUIMenu->m_pCurrentMenu = getSendFX2MenuItem(nFXType); + + switch (Event) + { + case MenuEventUpdate: + break; + + case MenuEventSelect: // push menu + if (nFXType == 0) + { + break; + } + assert (pUIMenu->m_nCurrentMenuDepth < MaxMenuDepth); + pUIMenu->m_MenuStackParent[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pParentMenu; + pUIMenu->m_MenuStackMenu[pUIMenu->m_nCurrentMenuDepth] = pUIMenu->m_pCurrentMenu; + pUIMenu->m_nMenuStackItem[pUIMenu->m_nCurrentMenuDepth] + = pUIMenu->m_nCurrentMenuItem; + pUIMenu->m_nMenuStackSelection[pUIMenu->m_nCurrentMenuDepth] + = pUIMenu->m_nCurrentSelection; + pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth] + = pUIMenu->m_nCurrentParameter; + pUIMenu->m_nCurrentMenuDepth++; + + pUIMenu->m_pParentMenu = pUIMenu->m_pCurrentMenu; + pUIMenu->m_nCurrentParameter = + pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Parameter; + pUIMenu->m_pCurrentMenu = + pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].MenuItem; + pUIMenu->m_nCurrentMenuItem = pUIMenu->m_nCurrentSelection; + pUIMenu->m_nCurrentSelection = 0; + break; + + case MenuEventStepDown: + if (pUIMenu->m_nCurrentSelection > 0) + { + pUIMenu->m_nCurrentSelection--; + } + break; + + case MenuEventStepUp: + ++pUIMenu->m_nCurrentSelection; + if (!pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Name) // more entries? + { + pUIMenu->m_nCurrentSelection--; + } + break; + + default: + return; + } + + if (pUIMenu->m_pCurrentMenu) // if this is another menu? + { + string fxName = pUIMenu->m_pMiniDexed->getSendFX2Name(); + + pUIMenu->m_pUI->DisplayWrite ( + fxName.c_str(), + "", + pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection].Name, + pUIMenu->m_nCurrentSelection > 0, + !!pUIMenu->m_pCurrentMenu[pUIMenu->m_nCurrentSelection+1].Name); + } + else + { + pUIMenu->EventHandler (MenuEventUpdate); // no, update parameter display + } +} + +void CUIMenu::EditSendFX1Parameter (CUIMenu *pUIMenu, TMenuEvent Event) +{ + // Get FX type + int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterSendFX1Type); + + // Get Param + unsigned nParam = pUIMenu->m_nCurrentParameter; + TParameter pParam = getFXParameter(nFXType, nParam); + const TParameter &rParam = pParam; + + int nValue = pUIMenu->m_pMiniDexed->GetSendFX1Parameter (nParam, nFXType); + + switch (Event) + { + case MenuEventUpdate: + break; + + case MenuEventPressAndStepDown: + nValue -= rParam.Increment * 9; + case MenuEventStepDown: + nValue -= rParam.Increment * pUIMenu->m_nStepCount; + if (nValue < rParam.Minimum) + { + nValue = rParam.Minimum; + } + pUIMenu->m_pMiniDexed->SetSendFX1Parameter (nParam, nValue, nFXType); + break; + + case MenuEventPressAndStepUp: + nValue += rParam.Increment * 9; + case MenuEventStepUp: + nValue += rParam.Increment * pUIMenu->m_nStepCount; + if (nValue > rParam.Maximum) + { + nValue = rParam.Maximum; + } + pUIMenu->m_pMiniDexed->SetSendFX1Parameter (nParam, nValue, nFXType); + break; + + default: + return; + } + + // Get value again after change + nValue = pUIMenu->m_pMiniDexed->GetSendFX1Parameter (nParam, nFXType); + CUIMenu::TToString *pToString = rParam.ToString; + string Value; + if (pToString) + { + Value = (*pToString) (nValue); + } + else + { + Value = to_string (nValue); + } + + pUIMenu->m_pUI->DisplayWrite ( + pUIMenu->m_pParentMenu[pUIMenu->m_nCurrentMenuItem].Name, + "", + Value.c_str (), + nValue > rParam.Minimum, nValue < rParam.Maximum); +} + +void CUIMenu::EditSendFX2Parameter (CUIMenu *pUIMenu, TMenuEvent Event) { // Get FX type - int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterSendFXType); + int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterSendFX2Type); // Get Param unsigned nParam = pUIMenu->m_nCurrentParameter; TParameter pParam = getFXParameter(nFXType, nParam); const TParameter &rParam = pParam; - int nValue = pUIMenu->m_pMiniDexed->GetSendFXParameter (nParam, nFXType); + int nValue = pUIMenu->m_pMiniDexed->GetSendFX2Parameter (nParam, nFXType); switch (Event) { @@ -1997,7 +2230,7 @@ void CUIMenu::EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) { nValue = rParam.Minimum; } - pUIMenu->m_pMiniDexed->SetSendFXParameter (nParam, nValue, nFXType); + pUIMenu->m_pMiniDexed->SetSendFX2Parameter (nParam, nValue, nFXType); break; case MenuEventPressAndStepUp: @@ -2008,7 +2241,7 @@ void CUIMenu::EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) { nValue = rParam.Maximum; } - pUIMenu->m_pMiniDexed->SetSendFXParameter (nParam, nValue, nFXType); + pUIMenu->m_pMiniDexed->SetSendFX2Parameter (nParam, nValue, nFXType); break; default: @@ -2016,7 +2249,7 @@ void CUIMenu::EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) } // Get value again after change - nValue = pUIMenu->m_pMiniDexed->GetSendFXParameter (nParam, nFXType); + nValue = pUIMenu->m_pMiniDexed->GetSendFX2Parameter (nParam, nFXType); CUIMenu::TToString *pToString = rParam.ToString; string Value; if (pToString) @@ -3409,14 +3642,28 @@ CUIMenu::TMenuItem* CUIMenu::getInsertFXMenuItem(unsigned type) return menu; } -CUIMenu::TMenuItem* CUIMenu::getSendFXMenuItem(unsigned type) +CUIMenu::TMenuItem* CUIMenu::getSendFX1MenuItem(unsigned type) +{ + CUIMenu::TMenuItem* menu = getFXMenuItem(type); + + unsigned i = 0; + while(menu[i].Name != NULL) + { + menu[i].Handler = EditSendFX1Parameter; + i++; + } + + return menu; +} + +CUIMenu::TMenuItem* CUIMenu::getSendFX2MenuItem(unsigned type) { CUIMenu::TMenuItem* menu = getFXMenuItem(type); unsigned i = 0; while(menu[i].Name != NULL) { - menu[i].Handler = EditSendFXParameter; + menu[i].Handler = EditSendFX2Parameter; i++; } diff --git a/src/uimenu.h b/src/uimenu.h index eb79cfd..f921b0c 100644 --- a/src/uimenu.h +++ b/src/uimenu.h @@ -112,10 +112,14 @@ private: static void EditTGFXParameter (CUIMenu *pUIMenu, TMenuEvent Event); static CUIMenu::TMenuItem* getInsertFXMenuItem(unsigned type); - static void MenuHandlerSendFX (CUIMenu *pUIMenu, TMenuEvent Event); - static void EditSendFX (CUIMenu *pUIMenu, TMenuEvent Event); - static void EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event); - static CUIMenu::TMenuItem* getSendFXMenuItem(unsigned type); + static void MenuHandlerSendFX1 (CUIMenu *pUIMenu, TMenuEvent Event); + static void MenuHandlerSendFX2 (CUIMenu *pUIMenu, TMenuEvent Event); + static void EditSendFX1 (CUIMenu *pUIMenu, TMenuEvent Event); + static void EditSendFX2 (CUIMenu *pUIMenu, TMenuEvent Event); + static void EditSendFX1Parameter (CUIMenu *pUIMenu, TMenuEvent Event); + static void EditSendFX2Parameter (CUIMenu *pUIMenu, TMenuEvent Event); + static CUIMenu::TMenuItem* getSendFX1MenuItem(unsigned type); + static CUIMenu::TMenuItem* getSendFX2MenuItem(unsigned type); static void MenuHandlerMasterFX (CUIMenu *pUIMenu, TMenuEvent Event); static void EditMasterFX (CUIMenu *pUIMenu, TMenuEvent Event); @@ -179,7 +183,8 @@ private: static const TMenuItem s_MainMenu[]; static const TMenuItem s_TGMenu[]; static const TMenuItem s_EffectsMenu[]; - static const TMenuItem s_SendFXMenu[]; + static const TMenuItem s_SendFX1Menu[]; + static const TMenuItem s_SendFX2Menu[]; static const TMenuItem s_MasterFXMenu[]; static const TMenuItem s_ReverbMenu[]; static const TMenuItem s_InsertFX[];