diff --git a/src/effect_audio/effect_3bandeq.h b/src/effect_audio/effect_3bandeq.h index 954b668..914cb20 100644 --- a/src/effect_audio/effect_3bandeq.h +++ b/src/effect_audio/effect_3bandeq.h @@ -58,8 +58,14 @@ public: a0HP = 1.0f - xHP; b1HP = -xHP; - out1LP = out2LP = out1HP = out2HP = 0.0f; - tmp1LP = tmp2LP = tmp1HP = tmp2HP = 0.0f; + out1LP = 0.0f; + out2LP = 0.0f; + out1HP = 0.0f; + out2HP = 0.0f; + tmp1LP = 0.0f; + tmp2LP = 0.0f; + tmp1HP = 0.0f; + tmp2HP = 0.0f; } virtual ~AudioEffect3BandEQ() @@ -155,18 +161,31 @@ protected: for (uint32_t i=0; i < len; ++i) { - tmp1LP = a0LP * in1[i] - b1LP * tmp1LP + kDC_ADD; - tmp2LP = a0LP * in2[i] - b1LP * tmp2LP + kDC_ADD; + float inValue1, inValue2; + if (std::isnan(in1[i])) { + inValue1 = 0.0f; + } else { + inValue1 = in1[i]; + } + if (std::isnan(in2[i])) { + inValue2 = 0.0f; + } else { + inValue2 = in2[i]; + } + + tmp1LP = a0LP * inValue1 - b1LP * tmp1LP + kDC_ADD; + tmp2LP = a0LP * inValue2 - b1LP * tmp2LP + kDC_ADD; + out1LP = tmp1LP - kDC_ADD; out2LP = tmp2LP - kDC_ADD; - tmp1HP = a0HP * in1[i] - b1HP * tmp1HP + kDC_ADD; - tmp2HP = a0HP * in2[i] - b1HP * tmp2HP + kDC_ADD; - out1HP = in1[i] - tmp1HP - kDC_ADD; - out2HP = in2[i] - tmp2HP - kDC_ADD; + tmp1HP = a0HP * inValue1 - b1HP * tmp1HP + kDC_ADD; + tmp2HP = a0HP * inValue2 - b1HP * tmp2HP + kDC_ADD; + out1HP = inValue1 - tmp1HP - kDC_ADD; + out2HP = inValue2 - tmp2HP - kDC_ADD; - out1[i] = (out1LP*lowVol + (in1[i] - out1LP - out1HP)*midVol + out1HP*highVol) * outVol; - out2[i] = (out2LP*lowVol + (in2[i] - out2LP - out2HP)*midVol + out2HP*highVol) * outVol; + out1[i] = (out1LP*lowVol + (inValue1 - out1LP - out1HP)*midVol + out1HP*highVol) * outVol; + out2[i] = (out2LP*lowVol + (inValue2 - out2LP - out2HP)*midVol + out2HP*highVol) * outVol; } } private: diff --git a/src/minidexed.cpp b/src/minidexed.cpp index c89d5f7..064720c 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -242,6 +242,8 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt, reverb_send_mixer = new AudioStereoMixer(pConfig->GetChunkSize()/2); // END setup reverb + SetParameter (ParameterMasterFXType, AudioEffect3BandEQ::ID); + SetParameter (ParameterCompressorEnable, 1); SetPerformanceSelectChannel(m_pConfig->GetPerformanceSelectChannel()); @@ -730,6 +732,11 @@ std::string CMiniDexed::getMidiFXName (unsigned nTG) void CMiniDexed::setSendFXType (unsigned nType) { + // If the effect type is already set just return + if (m_SendFX != NULL && m_SendFX->getId() == nType) { + return; + } + m_SendFXSpinLock.Acquire(); if (m_SendFX != NULL) { @@ -754,6 +761,30 @@ void CMiniDexed::setSendFXLevel (unsigned nValue) m_SendFXLevel = (float32_t) nValue / 100.0f; } +void CMiniDexed::setMasterFXType (unsigned nType) +{ + // If the effect type is already set just return + if (m_MasterFX != NULL && m_MasterFX->getId() == nType) { + return; + } + + m_MasterFXSpinLock.Acquire(); + if (m_MasterFX != NULL) + { + delete m_MasterFX; + } + m_MasterFX = newAudioEffect(nType, m_pConfig->GetSampleRate()); + m_MasterFX->setTempo(m_nTempo); + m_MasterFXSpinLock.Release(); + + m_UI.ParameterChanged (); +} + +std::string CMiniDexed::getMasterFXName () +{ + return m_MasterFX->getName(); +} + void CMiniDexed::SetReverbSend (unsigned nReverbSend, unsigned nTG) { nReverbSend=constrain((int)nReverbSend,0,99); @@ -868,6 +899,7 @@ void CMiniDexed::setTempo(unsigned nValue) // Set Tempo to FXs m_SendFX->setTempo(m_nTempo); + m_MasterFX->setTempo(m_nTempo); for (unsigned nTG = 0; nTG < CConfig::AllToneGenerators; nTG++) { m_InsertFX[nTG]->setTempo(m_nTempo); @@ -1090,6 +1122,10 @@ void CMiniDexed::SetParameter (TParameter Parameter, int nValue) setSendFXLevel(nValue); break; + case ParameterMasterFXType: + setMasterFXType(nValue); + break; + case ParameterPerformanceSelectChannel: // Nothing more to do break; @@ -1119,6 +1155,8 @@ int CMiniDexed::GetParameter (TParameter Parameter) return m_SendFX->getId(); case ParameterSendFXLevel: return roundf(m_SendFXLevel * 100); + case ParameterMasterFXType: + return m_MasterFX->getId(); case ParameterTempo: return this->getTempo(); default: @@ -1276,6 +1314,18 @@ int CMiniDexed::GetSendFXParameter (unsigned Parameter, unsigned nFXType) { return m_SendFX->getParameter(Parameter); } +void CMiniDexed::SetMasterFXParameter (unsigned Parameter, int nValue, unsigned nFXType) { + assert (m_MasterFX->getId() == nFXType); + + m_MasterFX->setParameter(Parameter, nValue); +} + +int CMiniDexed::GetMasterFXParameter (unsigned Parameter, unsigned nFXType) { + assert (m_MasterFX->getId() == nFXType); + + return m_MasterFX->getParameter(Parameter); +} + void CMiniDexed::SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG) { assert (nTG < CConfig::AllToneGenerators); @@ -1365,20 +1415,19 @@ void CMiniDexed::ProcessSound (void) m_GetChunkTimer.Start (); } + uint8_t indexL=0, indexR=1; float32_t SampleBuffer[2][nFrames]; m_MidiArpSpinLock[0]->Acquire(); m_MidiArp[0]->process(nFrames); m_MidiArpSpinLock[0]->Release(); - m_pTG[0]->getSamples (SampleBuffer[0], nFrames); + m_pTG[0]->getSamples (SampleBuffer[indexL], nFrames); m_InsertFXSpinLock[0]->Acquire(); - m_InsertFX[0]->process(SampleBuffer[0], SampleBuffer[0], SampleBuffer[0], SampleBuffer[1], nFrames); + m_InsertFX[0]->process(SampleBuffer[indexL], SampleBuffer[indexL], SampleBuffer[indexL], SampleBuffer[indexR], nFrames); m_InsertFXSpinLock[0]->Release(); - uint8_t indexL=0, indexR=1; - reverb_send_mixer->doAddMix(0, SampleBuffer[indexL], SampleBuffer[indexR]); float32_t ReverbBuffer[2][nFrames]; @@ -1403,6 +1452,10 @@ void CMiniDexed::ProcessSound (void) m_SendFXSpinLock.Release (); + m_MasterFXSpinLock.Acquire (); + m_MasterFX->process(SampleBuffer[indexL], SampleBuffer[indexR], SampleBuffer[indexL], SampleBuffer[indexR], nFrames); + m_MasterFXSpinLock.Release (); + // swap stereo channels if needed prior to writing back out if (m_bChannelsSwapped) { @@ -1541,8 +1594,8 @@ void CMiniDexed::ProcessSound (void) { for (uint8_t i = 0; i < m_nToneGenerators; i++) { - tg_mixer->doAddMix(i, m_OutputLevel[i][0], m_OutputLevel[i][1]); - reverb_send_mixer->doAddMix(i, m_OutputLevel[i][0], m_OutputLevel[i][1]); + 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]); } // END TG mixing @@ -1577,6 +1630,10 @@ void CMiniDexed::ProcessSound (void) m_SendFXSpinLock.Release (); // END adding reverb + m_MasterFXSpinLock.Acquire (); + m_MasterFX->process(SampleBuffer[indexL], SampleBuffer[indexR], SampleBuffer[indexL], SampleBuffer[indexR], nFrames); + m_MasterFXSpinLock.Release (); + // swap stereo channels if needed prior to writing back out if (m_bChannelsSwapped) { @@ -1724,6 +1781,12 @@ bool CMiniDexed::DoSavePerformance (void) pParams.shrink_to_fit(); m_PerformanceConfig.SetSendFXLevel (roundf(m_SendFXLevel * 100)); + m_PerformanceConfig.SetMasterFX (m_MasterFX->getId()); + std::vector pMasterParams = m_MasterFX->getParameters(); + m_PerformanceConfig.SetMasterFXParams (pMasterParams); + pMasterParams.clear(); + pMasterParams.shrink_to_fit(); + m_PerformanceConfig.SetTempo (m_nTempo); if(m_bSaveAsDeault) @@ -2219,6 +2282,12 @@ void CMiniDexed::LoadPerformanceParameters(void) pParams.shrink_to_fit(); SetParameter (ParameterSendFXLevel, m_PerformanceConfig.GetSendFXLevel ()); + setMasterFXType(m_PerformanceConfig.GetMasterFX ()); + std::vector pMasterParams = m_PerformanceConfig.GetMasterFXParams (); + m_MasterFX->setParameters(pMasterParams); + pMasterParams.clear(); + pMasterParams.shrink_to_fit(); + SetParameter (ParameterTempo, m_PerformanceConfig.GetTempo ()); } diff --git a/src/minidexed.h b/src/minidexed.h index 694c66f..3afabff 100644 --- a/src/minidexed.h +++ b/src/minidexed.h @@ -109,6 +109,8 @@ public: void setSendFXType (unsigned nType); std::string getSendFXName (); void setSendFXLevel (unsigned nValue); + void setMasterFXType (unsigned nType); + std::string getMasterFXName (); void SetReverbSend (unsigned nReverbSend, unsigned nTG); // 0 .. 127 @@ -166,6 +168,7 @@ public: ParameterCompressorEnable, ParameterSendFXType, ParameterSendFXLevel, + ParameterMasterFXType, ParameterPerformanceSelectChannel, ParameterPerformanceBank, ParameterTempo, @@ -239,6 +242,9 @@ public: void SetSendFXParameter (unsigned Parameter, int nValue, unsigned nFXType); int GetSendFXParameter (unsigned Parameter, unsigned nFXType); + void SetMasterFXParameter (unsigned Parameter, int nValue, unsigned nFXType); + int GetMasterFXParameter (unsigned Parameter, unsigned nFXType); + // access (global or OP-related) parameter of the active voice of a TG static const unsigned NoOP = 6; // for global parameters void SetVoiceParameter (uint8_t uchOffset, uint8_t uchValue, unsigned nOP, unsigned nTG); @@ -346,10 +352,12 @@ private: AudioStereoMixer* reverb_send_mixer; AudioEffect* m_SendFX = NULL; float32_t m_SendFXLevel = 1.0f; + AudioEffect* m_MasterFX = NULL; CSpinLock* m_MidiArpSpinLock[CConfig::AllToneGenerators]; CSpinLock* m_InsertFXSpinLock[CConfig::AllToneGenerators]; CSpinLock m_SendFXSpinLock; + CSpinLock m_MasterFXSpinLock; bool m_bSavePerformance; bool m_bSavePerformanceNewFile; diff --git a/src/performanceconfig.cpp b/src/performanceconfig.cpp index 192b40c..f5a8eec 100644 --- a/src/performanceconfig.cpp +++ b/src/performanceconfig.cpp @@ -223,7 +223,7 @@ bool CPerformanceConfig::Load (void) PropertyName.Format ("AftertouchTarget%u", nTG+1); m_nAftertouchTarget[nTG] = m_Properties.GetNumber (PropertyName, 0); - } + } m_bCompressorEnable = m_Properties.GetNumber ("CompressorEnable", 1) != 0; @@ -248,6 +248,10 @@ bool CPerformanceConfig::Load (void) + std::to_string(m_nReverbLowPass) + "," + std::to_string(m_nReverbDiffusion) + "," + std::to_string(100); } + + // Set 3 Band EQ as Default Master FX + m_nMasterFX = m_Properties.GetNumber ("MasterFX", 9); + m_sMasterFXParams = m_Properties.GetString ("MasterFXParams", ""); return bResult; } @@ -421,6 +425,9 @@ bool CPerformanceConfig::Save (void) tokens.shrink_to_fit(); } + m_Properties.SetNumber ("MasterFX", m_nMasterFX); + m_Properties.SetString ("MasterFXParams", m_sMasterFXParams.c_str()); + m_Properties.SetNumber ("Tempo", m_nTempo); return m_Properties.Save (); @@ -638,6 +645,15 @@ unsigned CPerformanceConfig::GetSendFXLevel (void) const return m_nSendFXLevel; } +unsigned CPerformanceConfig::GetMasterFX (void) const +{ + return m_nMasterFX; +} + +std::vector CPerformanceConfig::GetMasterFXParams (void) const +{ + return StringToVector(m_sMasterFXParams); +} bool CPerformanceConfig::GetReverbEnable (void) const { @@ -699,6 +715,16 @@ void CPerformanceConfig::SetSendFXLevel (unsigned nValue) m_nSendFXLevel = nValue; } +void CPerformanceConfig::SetMasterFX (unsigned nValue) +{ + m_nMasterFX = nValue; +} + +void CPerformanceConfig::SetMasterFXParams (std::vector pParams) +{ + m_sMasterFXParams = VectorToString(pParams); +} + void CPerformanceConfig::SetReverbEnable (bool bValue) { m_bReverbEnable = bValue; diff --git a/src/performanceconfig.h b/src/performanceconfig.h index 431b919..c1cbfb6 100644 --- a/src/performanceconfig.h +++ b/src/performanceconfig.h @@ -115,6 +115,8 @@ public: unsigned GetSendFX (void) const; std::vector GetSendFXParams (void) const; unsigned GetSendFXLevel (void) const; + unsigned GetMasterFX (void) const; + std::vector GetMasterFXParams (void) const; bool GetReverbEnable (void) const; unsigned GetReverbSize (void) const; // 0 .. 99 unsigned GetReverbHighDamp (void) const; // 0 .. 99 @@ -128,6 +130,8 @@ public: void SetSendFX (unsigned nValue); void SetSendFXParams (std::vector pParams); void SetSendFXLevel (unsigned nValue); + void SetMasterFX (unsigned nValue); + void SetMasterFXParams (std::vector pParams); void SetReverbEnable (bool bValue); void SetReverbSize (unsigned nValue); void SetReverbHighDamp (unsigned nValue); @@ -221,6 +225,8 @@ private: unsigned m_nSendFX; std::string m_sSendFXParams; unsigned m_nSendFXLevel; + unsigned m_nMasterFX; + std::string m_sMasterFXParams; bool m_bReverbEnable; unsigned m_nReverbSize; unsigned m_nReverbHighDamp; diff --git a/src/uimenu.cpp b/src/uimenu.cpp index e80165f..e60b1d8 100644 --- a/src/uimenu.cpp +++ b/src/uimenu.cpp @@ -94,10 +94,8 @@ const CUIMenu::TMenuItem CUIMenu::s_TGMenu[] = const CUIMenu::TMenuItem CUIMenu::s_EffectsMenu[] = { {"Compress", EditGlobalParameter, 0, CMiniDexed::ParameterCompressorEnable}, - {"Send FX", MenuHandlerSendFX}, -#ifdef ARM_ALLOW_MULTI_CORE - //{"Reverb", MenuHandler, s_ReverbMenu}, -#endif + {"Send FX", MenuHandlerSendFX}, + {"Master FX", MenuHandlerMasterFX}, {0} }; @@ -142,6 +140,13 @@ const CUIMenu::TMenuItem CUIMenu::s_SendFXMenu[] = {0} }; +const CUIMenu::TMenuItem CUIMenu::s_MasterFXMenu[] = +{ + {"Type:", EditGlobalParameter, 0, CMiniDexed::ParameterMasterFXType}, + {"Edit:", EditMasterFX}, + {0} +}; + const CUIMenu::TMenuItem CUIMenu::s_InsertFX[] = { {"Type:", EditTGParameter2, 0, CMiniDexed::TGParameterInsertFXType}, @@ -415,6 +420,7 @@ const CUIMenu::TParameter CUIMenu::s_GlobalParameter[CMiniDexed::ParameterUnknow {0, 1, 1, ToOnOff}, // ParameterCompressorEnable {0, AudioEffects::Types::UNKNOWN - 1, 1, ToFXType}, // ParameterSendFXType {0, 100, 1}, // ParameterSendFXLevel + {0, AudioEffects::Types::UNKNOWN - 1, 1, ToFXType}, // ParameterMasterFXType {0, CMIDIDevice::ChannelUnknown-1, 1, ToMIDIChannel}, // ParameterPerformanceSelectChannel {0, NUM_PERFORMANCE_BANKS, 1}, // ParameterPerformanceBank {30, 250, 1} // ParameterTempo @@ -1259,6 +1265,90 @@ void CUIMenu::MenuHandlerSendFX (CUIMenu *pUIMenu, TMenuEvent Event) } } +void CUIMenu::MenuHandlerMasterFX (CUIMenu *pUIMenu, TMenuEvent Event) +{ + // Setup menu when it's open + if (!pUIMenu->m_pCurrentMenu) + { + pUIMenu->m_pCurrentMenu = s_MasterFXMenu; + } + + 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->getMasterFXName(); + + // 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::EditGlobalParameter (CUIMenu *pUIMenu, TMenuEvent Event) { CMiniDexed::TParameter Param = (CMiniDexed::TParameter) pUIMenu->m_nCurrentParameter; @@ -1945,6 +2035,140 @@ void CUIMenu::EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) nValue > rParam.Minimum, nValue < rParam.Maximum); } +void CUIMenu::EditMasterFX (CUIMenu *pUIMenu, TMenuEvent Event) +{ + int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterMasterFXType); + pUIMenu->m_pCurrentMenu = getMasterFXMenuItem(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->getMasterFXName(); + + 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::EditMasterFXParameter (CUIMenu *pUIMenu, TMenuEvent Event) +{ + // Get FX type + int nFXType = pUIMenu->m_pMiniDexed->GetParameter(CMiniDexed::ParameterMasterFXType); + + // Get Param + unsigned nParam = pUIMenu->m_nCurrentParameter; + TParameter pParam = getFXParameter(nFXType, nParam); + const TParameter &rParam = pParam; + + int nValue = pUIMenu->m_pMiniDexed->GetMasterFXParameter (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->SetMasterFXParameter (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->SetMasterFXParameter (nParam, nValue, nFXType); + break; + + default: + return; + } + + // Get value again after change + nValue = pUIMenu->m_pMiniDexed->GetMasterFXParameter (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::EditVoiceParameter (CUIMenu *pUIMenu, TMenuEvent Event) { unsigned nTG = pUIMenu->m_nMenuStackParameter[pUIMenu->m_nCurrentMenuDepth-2]; @@ -3199,6 +3423,20 @@ CUIMenu::TMenuItem* CUIMenu::getSendFXMenuItem(unsigned type) return menu; } +CUIMenu::TMenuItem* CUIMenu::getMasterFXMenuItem(unsigned type) +{ + CUIMenu::TMenuItem* menu = getFXMenuItem(type); + + unsigned i = 0; + while(menu[i].Name != NULL) + { + menu[i].Handler = EditMasterFXParameter; + i++; + } + + return menu; +} + CUIMenu::TParameter CUIMenu::getFXParameter(unsigned type, unsigned nParam) { TParameter pParam; diff --git a/src/uimenu.h b/src/uimenu.h index 67212a4..eb79cfd 100644 --- a/src/uimenu.h +++ b/src/uimenu.h @@ -117,6 +117,11 @@ private: static void EditSendFXParameter (CUIMenu *pUIMenu, TMenuEvent Event); static CUIMenu::TMenuItem* getSendFXMenuItem(unsigned type); + static void MenuHandlerMasterFX (CUIMenu *pUIMenu, TMenuEvent Event); + static void EditMasterFX (CUIMenu *pUIMenu, TMenuEvent Event); + static void EditMasterFXParameter (CUIMenu *pUIMenu, TMenuEvent Event); + static CUIMenu::TMenuItem* getMasterFXMenuItem(unsigned type); + static std::string GetGlobalValueString (unsigned nParameter, int nValue); static std::string GetTGValueString (unsigned nTGParameter, int nValue); static std::string GetVoiceValueString (unsigned nVoiceParameter, int nValue); @@ -175,6 +180,7 @@ private: static const TMenuItem s_TGMenu[]; static const TMenuItem s_EffectsMenu[]; static const TMenuItem s_SendFXMenu[]; + static const TMenuItem s_MasterFXMenu[]; static const TMenuItem s_ReverbMenu[]; static const TMenuItem s_InsertFX[]; static const TMenuItem s_MidiFX[];