diff --git a/include/audacity/EffectAutomationParameters.h b/include/audacity/EffectAutomationParameters.h index 56a813581..0f6b519a8 100644 --- a/include/audacity/EffectAutomationParameters.h +++ b/include/audacity/EffectAutomationParameters.h @@ -44,6 +44,7 @@ #include #include +#include class EffectAutomationParameters : public wxFileConfig { @@ -82,6 +83,22 @@ public: return wxFileConfig::DoReadLong(NormalizeName(key), pl); } + virtual bool DoReadDouble(const wxString & key, double *pd) const + { + wxString str; + if (Read(key, &str)) + { + wxString dec = wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER); + + str.Replace(wxT(","), dec); + str.Replace(wxT("."), dec); + + return str.ToDouble(pd); + } + + return false; + } + virtual bool DoWriteString(const wxString & key, const wxString & szValue) { return wxFileConfig::DoWriteString(NormalizeName(key), szValue); @@ -94,7 +111,7 @@ public: virtual bool DoWriteDouble(const wxString & key, double value) { - return DoWriteString(key, wxString::Format(wxT("%.12g"), value)); + return DoWriteString(key, wxString::Format(wxT("%.12f"), value)); } bool ReadFloat(const wxString & key, float *pf) const @@ -209,19 +226,6 @@ public: return (*val != wxNOT_FOUND); } - wxString NormalizeName(const wxString & name) const - { - wxString cleaned = name; - - cleaned.Trim(true).Trim(false); - cleaned.Replace(wxT(" "), wxT("_")); - cleaned.Replace(wxT("/"), wxT("_")); - cleaned.Replace(wxT("\\"), wxT("_")); - cleaned.Replace(wxT(":"), wxT("_")); - - return cleaned; - } - bool GetParameters(wxString & parms) { wxFileConfig::SetPath(wxT("/")); @@ -270,6 +274,19 @@ public: return true; } + wxString NormalizeName(const wxString & name) const + { + wxString cleaned = name; + + cleaned.Trim(true).Trim(false); + cleaned.Replace(wxT(" "), wxT("_")); + cleaned.Replace(wxT("/"), wxT("_")); + cleaned.Replace(wxT("\\"), wxT("_")); + cleaned.Replace(wxT(":"), wxT("_")); + + return cleaned; + } + wxString Escape(wxString val) { val.Replace(wxT("\\"), wxT("\\\\"), true); diff --git a/src/effects/VST/VSTEffect.cpp b/src/effects/VST/VSTEffect.cpp index c51f8e3c4..4cd7e7531 100644 --- a/src/effects/VST/VSTEffect.cpp +++ b/src/effects/VST/VSTEffect.cpp @@ -2090,6 +2090,8 @@ bool VSTEffect::GetAutomationParameters(EffectAutomationParameters & parms) bool VSTEffect::SetAutomationParameters(EffectAutomationParameters & parms) { + size_t slaveCnt = mSlaves.GetCount(); + callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0); for (int i = 0; i < mAEffect->numParams; i++) { @@ -2105,7 +2107,14 @@ bool VSTEffect::SetAutomationParameters(EffectAutomationParameters & parms) return false; } - callSetParameter(i, d); + if (d >= -1.0 && d <= 1.0) + { + callSetParameter(i, d); + for (size_t i = 0; i < slaveCnt; i++) + { + mSlaves[i]->callSetParameter(i, d); + } + } } callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0); @@ -2797,38 +2806,19 @@ bool VSTEffect::LoadParameters(const wxString & group) return true; } - if (!mHost->GetPrivateConfig(group, wxT("Value"), value, wxEmptyString)) + wxString parms; + if (!mHost->GetPrivateConfig(group, wxT("Parameters"), parms, wxEmptyString)) { return false; } - if (callDispatcher(effBeginLoadProgram, 0, 0, &info, 0.0) == -1) + EffectAutomationParameters eap; + if (!eap.SetParameters(parms)) { return false; } - callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0); - size_t cnt = mSlaves.GetCount(); - - wxStringTokenizer st(value, wxT(',')); - for (int i = 0; st.HasMoreTokens(); i++) - { - double val = 0.0; - st.GetNextToken().ToDouble(&val); - - if (val >= -1.0 && val <= 1.0) - { - callSetParameter(i, val); - for (size_t i = 0; i < cnt; i++) - { - mSlaves[i]->callSetParameter(i, val); - } - } - } - - callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0); - - return true; + return SetAutomationParameters(eap); } bool VSTEffect::SaveParameters(const wxString & group) @@ -2850,13 +2840,19 @@ bool VSTEffect::SaveParameters(const wxString & group) return true; } - wxString parms; - for (int i = 0; i < mAEffect->numParams; i++) + EffectAutomationParameters eap; + if (!GetAutomationParameters(eap)) { - parms += wxString::Format(wxT(",%f"), callGetParameter(i)); + return false; } - return mHost->SetPrivateConfig(group, wxT("Value"), parms.Mid(1)); + wxString parms; + if (!eap.GetParameters(parms)) + { + return false; + } + + return mHost->SetPrivateConfig(group, wxT("Parameters"), parms); } void VSTEffect::OnTimer() diff --git a/src/effects/audiounits/AudioUnitEffect.cpp b/src/effects/audiounits/AudioUnitEffect.cpp index 322fd470c..71380be96 100644 --- a/src/effects/audiounits/AudioUnitEffect.cpp +++ b/src/effects/audiounits/AudioUnitEffect.cpp @@ -1738,6 +1738,13 @@ bool AudioUnitEffect::SetAutomationParameters(EffectAutomationParameters & parms delete [] array; + AudioUnitParameter aup; + aup.mAudioUnit = mUnit; + aup.mParameterID = kAUParameterListener_AnyParameter; + aup.mScope = kAudioUnitScope_Global; + aup.mElement = 0; + AUParameterListenerNotify(NULL, NULL, &aup); + return true; } @@ -2163,135 +2170,36 @@ void AudioUnitEffect::RemoveHandler() bool AudioUnitEffect::LoadParameters(const wxString & group) { - OSStatus result; - UInt32 dataSize; - Boolean isWritable; - - wxString value; - if (!mHost->GetPrivateConfig(group, wxT("Value"), value, wxEmptyString)) - { - return false; - } - wxStringTokenizer tokens(value, wxT(',')); - - result = AudioUnitGetPropertyInfo(mUnit, - kAudioUnitProperty_ParameterList, - kAudioUnitScope_Global, - 0, - &dataSize, - &isWritable); - if (result != noErr) + wxString parms; + if (!mHost->GetPrivateConfig(group, wxT("Parameters"), parms, wxEmptyString)) { return false; } - UInt32 cnt = dataSize / sizeof(AudioUnitParameterID); - - if (cnt != tokens.CountTokens()) + EffectAutomationParameters eap; + if (!eap.SetParameters(parms)) { return false; } - AudioUnitParameterID *array = new AudioUnitParameterID[cnt]; - - result = AudioUnitGetProperty(mUnit, - kAudioUnitProperty_ParameterList, - kAudioUnitScope_Global, - 0, - array, - &dataSize); - if (result != noErr) - { - delete [] array; - return false; - } - - for (int i = 0; i < cnt; i++) - { - double d = 0.0; - tokens.GetNextToken().ToDouble(&d); - - AudioUnitParameterValue value = d; - result = AudioUnitSetParameter(mUnit, - array[i], - kAudioUnitScope_Global, - 0, - value, - 0); - if (result != noErr) - { - delete [] array; - return false; - } - } - - AudioUnitParameter aup; - aup.mAudioUnit = mUnit; - aup.mParameterID = kAUParameterListener_AnyParameter; - aup.mScope = kAudioUnitScope_Global; - aup.mElement = 0; - AUParameterListenerNotify(NULL, NULL, &aup); - - delete [] array; - - return true; + return SetAutomationParameters(eap); } bool AudioUnitEffect::SaveParameters(const wxString & group) { - OSStatus result; - UInt32 dataSize; - Boolean isWritable; + EffectAutomationParameters eap; + if (!GetAutomationParameters(eap)) + { + return false; + } + wxString parms; - - result = AudioUnitGetPropertyInfo(mUnit, - kAudioUnitProperty_ParameterList, - kAudioUnitScope_Global, - 0, - &dataSize, - &isWritable); - if (result != noErr) + if (!eap.GetParameters(parms)) { return false; } - UInt32 cnt = dataSize / sizeof(AudioUnitParameterID); - AudioUnitParameterID *array = new AudioUnitParameterID[cnt]; - - result = AudioUnitGetProperty(mUnit, - kAudioUnitProperty_ParameterList, - kAudioUnitScope_Global, - 0, - array, - &dataSize); - if (result != noErr) - { - delete [] array; - return false; - } - - for (int i = 0; i < cnt; i++) - { - AudioUnitParameterValue value; - result = AudioUnitGetParameter(mUnit, - array[i], - kAudioUnitScope_Global, - 0, - &value); - if (result != noErr) - { - delete [] array; - return false; - } - - parms += wxString::Format(wxT(",%f"), value); - } - - mHost->SetPrivateConfig(group, wxT("Value"), parms.Mid(1)); - - delete [] array; - - return true; + return mHost->SetPrivateConfig(group, wxT("Parameters"), parms); } bool AudioUnitEffect::SetRateAndChannels() diff --git a/src/effects/ladspa/LadspaEffect.cpp b/src/effects/ladspa/LadspaEffect.cpp index cb5a83ab5..403275a15 100644 --- a/src/effects/ladspa/LadspaEffect.cpp +++ b/src/effects/ladspa/LadspaEffect.cpp @@ -1539,38 +1539,36 @@ void LadspaEffect::Unload() bool LadspaEffect::LoadParameters(const wxString & group) { - wxString value; - - if (!mHost->GetPrivateConfig(group, wxT("Value"), value, wxEmptyString)) + wxString parms; + if (!mHost->GetPrivateConfig(group, wxT("Parameters"), parms, wxEmptyString)) { return false; } - wxStringTokenizer st(value, wxT(',')); - if (st.CountTokens() != mData->PortCount) + EffectAutomationParameters eap; + if (!eap.SetParameters(parms)) { return false; } - for (unsigned long p = 0; st.HasMoreTokens(); p++) - { - double val = 0.0; - st.GetNextToken().ToDouble(&val); - mInputControls[p] = val; - } - - return true; + return SetAutomationParameters(eap); } bool LadspaEffect::SaveParameters(const wxString & group) { - wxString parms; - for (unsigned long p = 0; p < mData->PortCount; p++) + EffectAutomationParameters eap; + if (!GetAutomationParameters(eap)) { - parms += wxString::Format(wxT(",%f"), mInputControls[p]); + return false; } - return mHost->SetPrivateConfig(group, wxT("Value"), parms.Mid(1)); + wxString parms; + if (!eap.GetParameters(parms)) + { + return false; + } + + return mHost->SetPrivateConfig(group, wxT("Parameters"), parms); } LADSPA_Handle LadspaEffect::InitInstance(float sampleRate) diff --git a/src/effects/lv2/LV2Effect.cpp b/src/effects/lv2/LV2Effect.cpp index 318d0d9d2..714148e9f 100644 --- a/src/effects/lv2/LV2Effect.cpp +++ b/src/effects/lv2/LV2Effect.cpp @@ -1282,34 +1282,36 @@ void LV2Effect::ShowOptions() bool LV2Effect::LoadParameters(const wxString & group) { - wxString value; - - if (!mHost->GetPrivateConfig(group, wxT("Value"), value, wxEmptyString)) + wxString parms; + if (!mHost->GetPrivateConfig(group, wxT("Parameters"), parms, wxEmptyString)) { return false; } - wxStringTokenizer st(value, wxT(',')); - for (size_t p = 0; st.HasMoreTokens(); p++) + EffectAutomationParameters eap; + if (!eap.SetParameters(parms)) { - double val = 0.0; - st.GetNextToken().ToDouble(&val); - mControls[p].mVal = (float) val; + return false; } - return true; + return SetAutomationParameters(eap); } bool LV2Effect::SaveParameters(const wxString & group) { - wxString parms; - - for (size_t i = 0, cnt = mControls.GetCount(); i < cnt; i++) + EffectAutomationParameters eap; + if (!GetAutomationParameters(eap)) { - parms += wxString::Format(wxT(",%f"), mControls[i].mVal); + return false; } - return mHost->SetPrivateConfig(group, wxT("Value"), parms.Mid(1)); + wxString parms; + if (!eap.GetParameters(parms)) + { + return false; + } + + return mHost->SetPrivateConfig(group, wxT("Parameters"), parms); } LV2_Options_Option *LV2Effect::AddOption(const char *key, uint32_t size, const char *type, void *value)