/********************************************************************** Audacity: A Digital Audio Editor Audacity(R) is copyright (c) 1999-2013 Audacity Team. License: GPL v2. See License.txt. Reverb.cpp Rob Sykes, Vaughan Johnson ******************************************************************//** \class EffectReverb \brief A reverberation effect *//****************************************************************//** \class ReverbDialogue \brief A configuration class used by effect, EffectReverb. *//*******************************************************************/ #include "Reverb.h" #include "Reverb_libSoX.h" #include "../Prefs.h" // // EffectReverb // struct Reverb_priv_t { size_t ichannels, ochannels; struct { reverb_t reverb; float * dry, * wet[2]; } chan[2]; }; void EffectReverb::Create(double rate, bool isStereo) { mP = (Reverb_priv_t *)calloc(sizeof *mP, 1); size_t i; #define BLOCK 0x4000u mP->ichannels = mP->ochannels = 1 + isStereo; for (i = 0; i < mP->ichannels; ++i) reverb_create( &mP->chan[i].reverb, rate, mParams.mWetGain, mParams.mRoomSize, mParams.mReverberance, mParams.mHfDamping, mParams.mDelay, mParams.mStereoWidth*isStereo, mParams.mToneLow, mParams.mToneHigh, BLOCK, mP->chan[i].wet); } bool EffectReverb::ProcessOneBlock(sampleCount len0, float * const * chans0) { float * chans[2]; chans[0] = chans0[0], chans[1] = chans0[1]; size_t c, i, w, len = len0; float const dryMult(mParams.mWetOnly? 0 : dB_to_linear(mParams.mDryGain)); while (len) { size_t len1 = min(len, (size_t)BLOCK); for (c = 0; c < mP->ichannels; ++c) { mP->chan[c].dry = (float *)fifo_write(&mP->chan[c].reverb.input_fifo, len1, chans[c]); reverb_process(&mP->chan[c].reverb, len1); } if (mP->ichannels == 2) for (i = 0; i < len1; ++i) for (w = 0; w < 2; ++w) chans[w][i] = dryMult * mP->chan[w].dry[i] + .5 * (mP->chan[0].wet[w][i] + mP->chan[1].wet[w][i]); else for (i = 0; i < len1; ++i) for (w = 0; w < mP->ochannels; ++w) chans[0][i] = dryMult * mP->chan[0].dry[i] + mP->chan[0].wet[w][i]; len -= len1; for (c = 0; c < mP->ichannels; chans[c++] += len1); } return true; } void EffectReverb::Delete() { for (size_t i = 0; i < mP->ichannels; reverb_delete(&mP->chan[i++].reverb)); free(mP); } // Most of what follows should really be provided by Audacity framework classes: //vvvvv Not sure what you mean by that, Rob. A la EffectSimpleMono, e.g.? bool EffectReverb::ProcessOneTrack(size_t n, WaveTrack * track, WaveTrack * track2, wxString const & msg) { sampleCount begin = track->TimeToLongSamples(mCurT0), pos = begin; sampleCount end = track->TimeToLongSamples(mCurT1); float * buffers[2]; buffers[0] = new float[track->GetMaxBlockSize()]; buffers[1] = track2? new float[track->GetMaxBlockSize()] : 0; bool cancelled = false; Create(track->GetRate(), track2 != 0); while (!cancelled && pos < end) { sampleCount block = track->GetBestBlockSize(pos); block = min(block, end - pos); track->Get((samplePtr) buffers[0], floatSample, pos, block); if (track2) track2->Get((samplePtr) buffers[1], floatSample, pos, block); ProcessOneBlock(block, buffers); track->Set((samplePtr) buffers[0], floatSample, pos, block); if (track2) track2->Set((samplePtr) buffers[1], floatSample, pos, block); pos += block; cancelled = TrackProgress(n, (1. * pos - begin) / (1. * end - begin) * .5 + .5, msg); } Delete(); delete[] buffers[0]; delete[] buffers[1]; return !cancelled; } bool EffectReverb::Process() { CopyInputTracks(); // Set up mOutputTracks. SelectedTrackListOfKindIterator iter(Track::Wave, mOutputTracks); WaveTrack * track = (WaveTrack *)iter.First(); bool success = true; for (int n = 0; success && track; track = (WaveTrack *)iter.Next(), ++n) { mCurT0 = max(mT0, track->GetStartTime()); mCurT1 = min(mT1, track->GetEndTime()); if (mCurT1 > mCurT0) { wxString msg(_("Processing: ") + track->GetName()); if (track->GetLinked() && mParams.mStereoWidth) // do stereo? success = ProcessOneTrack(++n, track, (WaveTrack *)iter.Next(), msg); else success = ProcessOneTrack(n, track, 0, msg); } } ReplaceProcessedTracks(success); return success; } wxString EffectReverb::SettingsPath(int settingsNumber) const { wxString x(wxString::FromAscii("/Effects/Reverb/")); if (settingsNumber >= 0) x += wxString::Format(wxString::FromAscii("%i/"), settingsNumber); return x; } wxString EffectReverb::SettingsName(int settingsNumber) const { wxString x(SettingsPath(settingsNumber)); gPrefs->Read(x + wxT("name"), &x, wxString::Format(wxString::FromAscii("Settings%i"), settingsNumber)); return x; } void EffectReverb::LoadSettings(int settingsNumber, EffectReverb::Params & params) { wxString sSettingsPath(SettingsPath(settingsNumber)); gPrefs->Read(sSettingsPath + wxT("RoomSize"), ¶ms.mRoomSize, 75); gPrefs->Read(sSettingsPath + wxT("Delay"), ¶ms.mDelay, 10); gPrefs->Read(sSettingsPath + wxT("Reverberance"), ¶ms.mReverberance, 50); gPrefs->Read(sSettingsPath + wxT("HfDamping"), ¶ms.mHfDamping, 50); gPrefs->Read(sSettingsPath + wxT("ToneLow"), ¶ms.mToneLow, 100); gPrefs->Read(sSettingsPath + wxT("ToneHigh"), ¶ms.mToneHigh, 100); gPrefs->Read(sSettingsPath + wxT("WetGain"), ¶ms.mWetGain, -1); gPrefs->Read(sSettingsPath + wxT("DryGain"), ¶ms.mDryGain, -1); gPrefs->Read(sSettingsPath + wxT("StereoWidth"), ¶ms.mStereoWidth, 100); gPrefs->Read(sSettingsPath + wxT("WetOnly"), ¶ms.mWetOnly, 0); } void EffectReverb::SaveSettings(int settingsNumber, EffectReverb::Params const * params, wxString const * name) const { wxString sSettingsPath(SettingsPath(settingsNumber)); if (name) gPrefs->Write(sSettingsPath + wxT("name"), *name); if (params) { gPrefs->Write(sSettingsPath + wxT("RoomSize"), params->mRoomSize); gPrefs->Write(sSettingsPath + wxT("Delay"), params->mDelay); gPrefs->Write(sSettingsPath + wxT("Reverberance"), params->mReverberance); gPrefs->Write(sSettingsPath + wxT("HfDamping"), params->mHfDamping); gPrefs->Write(sSettingsPath + wxT("ToneLow"), params->mToneLow); gPrefs->Write(sSettingsPath + wxT("ToneHigh"), params->mToneHigh); gPrefs->Write(sSettingsPath + wxT("WetGain"), params->mWetGain); gPrefs->Write(sSettingsPath + wxT("DryGain"), params->mDryGain); gPrefs->Write(sSettingsPath + wxT("StereoWidth"), params->mStereoWidth); gPrefs->Write(sSettingsPath + wxT("WetOnly"), params->mWetOnly); } gPrefs->Flush(); } EffectReverb::EffectReverb() { LoadSettings(-1, mParams); } wxString EffectReverb::GetEffectDescription() { wxString strResult = wxString::Format(_("Applied effect: %s"), GetEffectName().c_str()); strResult += wxString::Format(_(", Room Size = %.0f"), mParams.mRoomSize); strResult += wxString::Format(_(", Delay = %.0fms"), mParams.mDelay); strResult += wxString::Format(_(", Reverberance = %.0f%%"), mParams.mReverberance); strResult += wxString::Format(_(", Damping = %.0f%%"), mParams.mHfDamping); strResult += wxString::Format(_(", Tone Low = %.0f%%"), mParams.mToneLow); strResult += wxString::Format(_(", Tone High = %.0f%%"), mParams.mToneHigh); strResult += wxString::Format(_(", Wet Gain = %.0fdB"), mParams.mWetGain); strResult += wxString::Format(_(", Dry Gain Size = %.0fdB"), mParams.mDryGain); strResult += wxString::Format(_(", Stereo Width = %.0f%%"), mParams.mStereoWidth); strResult += wxString::Format(_(", Wet Only = %s"), mParams.mWetOnly ? _("true") : _("false")); return strResult; } bool EffectReverb::PromptUser() { ReverbDialogue d(this, mParent); d.CentreOnParent(); d.ShowModal(); if (d.GetReturnCode() == wxID_CANCEL) return false; SaveSettings(-1, &mParams); return true; } bool EffectReverb::TransferParameters(Shuttle & shuttle) { shuttle.TransferDouble(wxT("RoomSize"), mParams.mRoomSize, 75); shuttle.TransferDouble(wxT("Delay"), mParams.mDelay, 10); shuttle.TransferDouble(wxT("Reverberance"), mParams.mReverberance, 50); shuttle.TransferDouble(wxT("HfDamping"), mParams.mHfDamping, 50); shuttle.TransferDouble(wxT("ToneLow"), mParams.mToneLow, 100); shuttle.TransferDouble(wxT("ToneHigh"), mParams.mToneHigh, 100); shuttle.TransferDouble(wxT("WetGain"), mParams.mWetGain, -1); shuttle.TransferDouble(wxT("DryGain"), mParams.mDryGain, -1); shuttle.TransferDouble(wxT("StereoWidth"), mParams.mStereoWidth, 100); shuttle.TransferBool(wxT("WetOnly"), mParams.mWetOnly, 0); return true; } //---------------------------------------------------------------------------- // ReverbDialogue //---------------------------------------------------------------------------- #include #include #include #include #include #include enum {ID_START = 10000, ID_PRESETS, ID_LOAD_SETTINGS, ID_SAVE_SETTINGS, ID_RENAME_SETTINGS, ID_RoomSize_TEXT, ID_RoomSize_WIDGET, ID_Delay_TEXT, ID_Delay_WIDGET, ID_Reverberance_TEXT, ID_Reverberance_WIDGET, ID_HfDamping_TEXT, ID_HfDamping_WIDGET, ID_ToneLow_TEXT, ID_ToneLow_WIDGET, ID_ToneHigh_TEXT, ID_ToneHigh_WIDGET, ID_WetGain_TEXT, ID_WetGain_WIDGET, ID_DryGain_TEXT, ID_DryGain_WIDGET, ID_StereoWidth_TEXT, ID_StereoWidth_WIDGET, ID_WetOnly_WIDGET, ID_END}; BEGIN_EVENT_TABLE(ReverbDialogue, EffectDialog) EVT_SLIDER(ID_RoomSize_WIDGET, ReverbDialogue::OnRoomSizeWidget) EVT_TEXT(ID_RoomSize_TEXT, ReverbDialogue::OnRoomSizeText) EVT_SLIDER(ID_Delay_WIDGET, ReverbDialogue::OnDelayWidget) EVT_TEXT(ID_Delay_TEXT, ReverbDialogue::OnDelayText) EVT_SLIDER(ID_Reverberance_WIDGET, ReverbDialogue::OnReverberanceWidget) EVT_TEXT(ID_Reverberance_TEXT, ReverbDialogue::OnReverberanceText) EVT_SLIDER(ID_HfDamping_WIDGET, ReverbDialogue::OnHfDampingWidget) EVT_TEXT(ID_HfDamping_TEXT, ReverbDialogue::OnHfDampingText) EVT_SLIDER(ID_ToneLow_WIDGET, ReverbDialogue::OnToneLowWidget) EVT_TEXT(ID_ToneLow_TEXT, ReverbDialogue::OnToneLowText) EVT_SLIDER(ID_ToneHigh_WIDGET, ReverbDialogue::OnToneHighWidget) EVT_TEXT(ID_ToneHigh_TEXT, ReverbDialogue::OnToneHighText) EVT_SLIDER(ID_WetGain_WIDGET, ReverbDialogue::OnWetGainWidget) EVT_TEXT(ID_WetGain_TEXT, ReverbDialogue::OnWetGainText) EVT_SLIDER(ID_DryGain_WIDGET, ReverbDialogue::OnDryGainWidget) EVT_TEXT(ID_DryGain_TEXT, ReverbDialogue::OnDryGainText) EVT_SLIDER(ID_StereoWidth_WIDGET, ReverbDialogue::OnStereoWidthWidget) EVT_TEXT(ID_StereoWidth_TEXT, ReverbDialogue::OnStereoWidthText) EVT_BUTTON(ePreviewID, ReverbDialogue::OnPreview) EVT_BUTTON(ePreviewDryID, ReverbDialogue::OnPreview) EVT_BUTTON(ID_PRESETS, ReverbDialogue::LoadPreset) EVT_BUTTON(ID_SAVE_SETTINGS, ReverbDialogue::SaveSettings) EVT_BUTTON(ID_LOAD_SETTINGS, ReverbDialogue::LoadSettings) EVT_BUTTON(ID_RENAME_SETTINGS, ReverbDialogue::RenameSettings) END_EVENT_TABLE() ReverbDialogue::ReverbDialogue(EffectReverb * effect, wxWindow * parent): EffectDialog(parent, _("Reverb"), PROCESS_EFFECT, wxDEFAULT_DIALOG_STYLE, ePreviewDryButton), mEffect(*effect), mParams(effect->mParams) { Init(); } void ReverbDialogue::PopulateOrExchange(ShuttleGui & s) { s.StartHorizontalLay(wxCENTER, false); s.AddTitle(_("by Rob Sykes")); /* i18n-hint: Rob Sykes is a person's name.*/ s.EndHorizontalLay(); s.StartHorizontalLay(wxCENTER, false); // Add a little space s.EndHorizontalLay(); s.StartMultiColumn(3, wxEXPAND); { s.SetStretchyCol(2); mRoomSizeText = s.Id(ID_RoomSize_TEXT).AddSpinCtrl(_("Room Size (%):"), 0, 100, 0); s.SetStyle(wxSL_HORIZONTAL); mRoomSizeWidget = s.Id(ID_RoomSize_WIDGET).AddSlider(wxT(""), 0, 100, 0); mDelayText = s.Id(ID_Delay_TEXT).AddSpinCtrl(_("Delay (ms):"), 0, 200, 0); s.SetStyle(wxSL_HORIZONTAL); mDelayWidget = s.Id(ID_Delay_WIDGET).AddSlider(wxT(""), 0, 200, 0); mReverberanceText = s.Id(ID_Reverberance_TEXT).AddSpinCtrl(_("Reverberance (%):"), 0, 100, 0); s.SetStyle(wxSL_HORIZONTAL); mReverberanceWidget = s.Id(ID_Reverberance_WIDGET).AddSlider(wxT(""), 0, 100, 0); mHfDampingText = s.Id(ID_HfDamping_TEXT).AddSpinCtrl(_("Damping (%):"), 0, 100, 0); s.SetStyle(wxSL_HORIZONTAL); mHfDampingWidget = s.Id(ID_HfDamping_WIDGET).AddSlider(wxT(""), 0, 100, 0); mToneLowText = s.Id(ID_ToneLow_TEXT).AddSpinCtrl(_("Tone Low (%):"), 0, 100, 0); s.SetStyle(wxSL_HORIZONTAL); mToneLowWidget = s.Id(ID_ToneLow_WIDGET).AddSlider(wxT(""), 0, 100, 0); mToneHighText = s.Id(ID_ToneHigh_TEXT).AddSpinCtrl(_("Tone High (%):"), 0, 100, 0); s.SetStyle(wxSL_HORIZONTAL); mToneHighWidget = s.Id(ID_ToneHigh_WIDGET).AddSlider(wxT(""), 0, 100, 0); mWetGainText = s.Id(ID_WetGain_TEXT).AddSpinCtrl(_("Wet Gain (dB):"), 0, 10, -20); s.SetStyle(wxSL_HORIZONTAL); mWetGainWidget = s.Id(ID_WetGain_WIDGET).AddSlider(wxT(""), 0, 10, -20); mDryGainText = s.Id(ID_DryGain_TEXT).AddSpinCtrl(_("Dry Gain (dB):"), 0, 10, -20); s.SetStyle(wxSL_HORIZONTAL); mDryGainWidget = s.Id(ID_DryGain_WIDGET).AddSlider(wxT(""), 0, 10, -20); mStereoWidthText = s.Id(ID_StereoWidth_TEXT).AddSpinCtrl(_("Stereo Width (%):"), 0, 100, 0); s.SetStyle(wxSL_HORIZONTAL); mStereoWidthWidget = s.Id(ID_StereoWidth_WIDGET).AddSlider(wxT(""), 0, 100, 0); } s.EndMultiColumn(); s.StartHorizontalLay(wxCENTER, false); { mWetOnlyWidget = s.Id(ID_WetOnly_WIDGET).AddCheckBox(wxT("Wet Only"), wxT("false")); } s.EndHorizontalLay(); s.StartHorizontalLay(wxCENTER); { s.StartStatic(_("Presets:")); { s.Id(ID_PRESETS), s.AddButton(_("Load")); } s.EndStatic(); s.StartStatic(_("User settings:")); { s.StartHorizontalLay(wxCENTER); { s.Id(ID_LOAD_SETTINGS), s.AddButton(_("Load")); s.Id(ID_SAVE_SETTINGS), s.AddButton(_("Save")); s.Id(ID_RENAME_SETTINGS), s.AddButton(_("Rename")); } s.EndHorizontalLay(); } s.EndStatic(); } s.EndHorizontalLay(); return; } bool ReverbDialogue::TransferDataToWindow() { mRoomSizeWidget->SetValue(int(mParams.mRoomSize)); mRoomSizeText->SetValue(wxString::Format(wxT("%d"), int(mParams.mRoomSize))); mDelayWidget->SetValue(int(mParams.mDelay)); mDelayText->SetValue(wxString::Format(wxT("%d"), int(mParams.mDelay))); mReverberanceWidget->SetValue(int(mParams.mReverberance)); mReverberanceText->SetValue(wxString::Format(wxT("%d"), int(mParams.mReverberance))); mHfDampingWidget->SetValue(int(mParams.mHfDamping)); mHfDampingText->SetValue(wxString::Format(wxT("%d"), int(mParams.mHfDamping))); mToneLowWidget->SetValue(int(mParams.mToneLow)); mToneLowText->SetValue(wxString::Format(wxT("%d"), int(mParams.mToneLow))); mToneHighWidget->SetValue(int(mParams.mToneHigh)); mToneHighText->SetValue(wxString::Format(wxT("%d"), int(mParams.mToneHigh))); mWetGainWidget->SetValue(int(mParams.mWetGain)); mWetGainText->SetValue(wxString::Format(wxT("%d"), int(mParams.mWetGain))); mDryGainWidget->SetValue(int(mParams.mDryGain)); mDryGainText->SetValue(wxString::Format(wxT("%d"), int(mParams.mDryGain))); mStereoWidthWidget->SetValue(int(mParams.mStereoWidth)); mStereoWidthText->SetValue(wxString::Format(wxT("%d"), int(mParams.mStereoWidth))); mWetOnlyWidget->SetValue(int(mParams.mWetOnly)); return true; } bool ReverbDialogue::TransferDataFromWindow() { mParams.mRoomSize = mRoomSizeWidget->GetValue(); mParams.mDelay = mDelayWidget->GetValue(); mParams.mReverberance = mReverberanceWidget->GetValue(); mParams.mHfDamping = mHfDampingWidget->GetValue(); mParams.mToneLow = mToneLowWidget->GetValue(); mParams.mToneHigh = mToneHighWidget->GetValue(); mParams.mWetGain = mWetGainWidget->GetValue(); mParams.mDryGain = mDryGainWidget->GetValue(); mParams.mStereoWidth = mStereoWidthWidget->GetValue(); mParams.mWetOnly = mWetOnlyWidget->GetValue(); return true; } void ReverbDialogue::OnRoomSizeText(wxCommandEvent & WXUNUSED(event)) { int val = mRoomSizeText->GetValue(); mRoomSizeWidget->SetValue(TrapLong(val, 0, 100)); } void ReverbDialogue::OnRoomSizeWidget(wxCommandEvent & WXUNUSED(event)) { mRoomSizeText->SetValue(wxString::Format(wxT("%d"), mRoomSizeWidget->GetValue())); } void ReverbDialogue::OnDelayText(wxCommandEvent & WXUNUSED(event)) { int val = mDelayText->GetValue(); mDelayWidget->SetValue(TrapLong(val, 0, 200)); } void ReverbDialogue::OnDelayWidget(wxCommandEvent & WXUNUSED(event)) { mDelayText->SetValue(wxString::Format(wxT("%d"), mDelayWidget->GetValue())); } void ReverbDialogue::OnReverberanceText(wxCommandEvent & WXUNUSED(event)) { int val = mReverberanceText->GetValue(); mReverberanceWidget->SetValue(TrapLong(val, 0, 100)); } void ReverbDialogue::OnReverberanceWidget(wxCommandEvent & WXUNUSED(event)) { mReverberanceText->SetValue(wxString::Format(wxT("%d"), mReverberanceWidget->GetValue())); } void ReverbDialogue::OnHfDampingText(wxCommandEvent & WXUNUSED(event)) { int val = mHfDampingText->GetValue(); mHfDampingWidget->SetValue(TrapLong(val, 0, 100)); } void ReverbDialogue::OnHfDampingWidget(wxCommandEvent & WXUNUSED(event)) { mHfDampingText->SetValue(wxString::Format(wxT("%d"), mHfDampingWidget->GetValue())); } void ReverbDialogue::OnToneLowText(wxCommandEvent & WXUNUSED(event)) { int val = mToneLowText->GetValue(); mToneLowWidget->SetValue(TrapLong(val, 0, 100)); } void ReverbDialogue::OnToneLowWidget(wxCommandEvent & WXUNUSED(event)) { mToneLowText->SetValue(wxString::Format(wxT("%d"), mToneLowWidget->GetValue())); } void ReverbDialogue::OnToneHighText(wxCommandEvent & WXUNUSED(event)) { int val = mToneHighText->GetValue(); mToneHighWidget->SetValue(TrapLong(val, 0, 100)); } void ReverbDialogue::OnToneHighWidget(wxCommandEvent & WXUNUSED(event)) { mToneHighText->SetValue(wxString::Format(wxT("%d"), mToneHighWidget->GetValue())); } void ReverbDialogue::OnWetGainText(wxCommandEvent & WXUNUSED(event)) { int val = mWetGainText->GetValue(); mWetGainWidget->SetValue(TrapLong(val, -20, 10)); } void ReverbDialogue::OnWetGainWidget(wxCommandEvent & WXUNUSED(event)) { mWetGainText->SetValue(wxString::Format(wxT("%d"), mWetGainWidget->GetValue())); } void ReverbDialogue::OnDryGainText(wxCommandEvent & WXUNUSED(event)) { int val = mDryGainText->GetValue(); mDryGainWidget->SetValue(TrapLong(val, -20, 10)); } void ReverbDialogue::OnDryGainWidget(wxCommandEvent & WXUNUSED(event)) { mDryGainText->SetValue(wxString::Format(wxT("%d"), mDryGainWidget->GetValue())); } void ReverbDialogue::OnStereoWidthText(wxCommandEvent & WXUNUSED(event)) { int val = mStereoWidthText->GetValue(); mStereoWidthWidget->SetValue(TrapLong(val, 0, 100)); } void ReverbDialogue::OnStereoWidthWidget(wxCommandEvent & WXUNUSED(event)) { mStereoWidthText->SetValue(wxString::Format(wxT("%d"), mStereoWidthWidget->GetValue())); } static int wxGetChoiceFromUser(wxWindow * parent, wxString const & message, wxString const & caption, wxArrayString const & choices, char * * clientData = 0, long style = wxCHOICEDLG_STYLE, wxPoint const & pos = wxDefaultPosition) // Home-grown function { wxSingleChoiceDialog d(parent, message, caption, choices, clientData, style, pos); d.ShowModal(); return d.GetReturnCode() == wxID_CANCEL? -1 : d.GetSelection(); } void ReverbDialogue::LoadPreset(wxCommandEvent & WXUNUSED(event)) { EffectReverb::Params & p = mParams; wxString caption(_("Reverb settings")); wxString message(_("Load preset:")); wxArrayString choices; choices.Add(_("Vocal I")); choices.Add(_("Vocal II")); choices.Add(_("Bathroom")); choices.Add(_("Small Room Bright")); choices.Add(_("Small Room Dark")); choices.Add(_("Medium Room")); choices.Add(_("Large Room")); choices.Add(_("Church Hall")); choices.Add(_("Cathedral")); int i(wxGetChoiceFromUser(this, message, caption, choices)); switch (i) { case 0: p.mRoomSize=70; p.mHfDamping=99; p.mDelay=20; p.mReverberance=40; p.mToneLow=100; p.mToneHigh=50 ; p.mWetGain=-12; p.mDryGain=0 ; p.mStereoWidth=70 ; break; case 1: p.mRoomSize=50; p.mHfDamping=99; p.mDelay=0 ; p.mReverberance=50; p.mToneLow=50 ; p.mToneHigh=100; p.mWetGain=-1 ; p.mDryGain=-1 ; p.mStereoWidth=70 ; break; case 2: p.mRoomSize=16; p.mHfDamping=0 ; p.mDelay=8 ; p.mReverberance=80; p.mToneLow=0 ; p.mToneHigh=100; p.mWetGain=-6 ; p.mDryGain=0 ; p.mStereoWidth=100; break; case 3: p.mRoomSize=30; p.mHfDamping=50; p.mDelay=10; p.mReverberance=50; p.mToneLow=50 ; p.mToneHigh=100; p.mWetGain=-1 ; p.mDryGain=-1 ; p.mStereoWidth=100; break; case 4: p.mRoomSize=30; p.mHfDamping=50; p.mDelay=10; p.mReverberance=50; p.mToneLow=100; p.mToneHigh=0 ; p.mWetGain=-1 ; p.mDryGain=-1 ; p.mStereoWidth=100; break; case 5: p.mRoomSize=75; p.mHfDamping=50; p.mDelay=10; p.mReverberance=40; p.mToneLow=100; p.mToneHigh=70 ; p.mWetGain=-1 ; p.mDryGain=-1 ; p.mStereoWidth=70 ; break; case 6: p.mRoomSize=85; p.mHfDamping=50; p.mDelay=10; p.mReverberance=40; p.mToneLow=100; p.mToneHigh=80 ; p.mWetGain=0 ; p.mDryGain=-6 ; p.mStereoWidth=90 ; break; case 7: p.mRoomSize=90; p.mHfDamping=50; p.mDelay=32; p.mReverberance=60; p.mToneLow=100; p.mToneHigh=50 ; p.mWetGain=0 ; p.mDryGain=-12; p.mStereoWidth=100; break; case 8: p.mRoomSize=90; p.mHfDamping=50; p.mDelay=16; p.mReverberance=90; p.mToneLow=100; p.mToneHigh=0 ; p.mWetGain=0 ; p.mDryGain=-20; p.mStereoWidth=100; break; default: return; } p.mWetOnly=0; TransferDataToWindow(); SetTitle(choices[i]); } int ReverbDialogue::ChooseSettings(wxString const & message) { wxString caption(_("Reverb settings")); wxArrayString choices; for (int i = 0; i < 10; choices.Add(mEffect.SettingsName(i++))); return wxGetChoiceFromUser(this, message, caption, choices); } void ReverbDialogue::SaveSettings(wxCommandEvent & WXUNUSED(event)) { int i(ChooseSettings(_("Save current settings as:"))); if (i >= 0) { EffectReverb::Params savedParams(mParams); TransferDataFromWindow(); mEffect.SaveSettings(i, &mParams); mParams = savedParams; SetTitle(mEffect.SettingsName(i)); } } void ReverbDialogue::SetTitle(wxString const & name) { wxString title(_("Reverb")); if (name != wxT("")) title += wxT(": ") + name; wxTopLevelWindow::SetTitle(title); } void ReverbDialogue::LoadSettings(wxCommandEvent & WXUNUSED(event)) { int i(ChooseSettings(_("Load settings:"))); if (i >= 0) { mEffect.LoadSettings(i, mParams); TransferDataToWindow(); SetTitle(mEffect.SettingsName(i)); } } void ReverbDialogue::RenameSettings(wxCommandEvent & WXUNUSED(event)) { int i(ChooseSettings(_("Rename settings:"))); if (i >= 0) { wxString oldName = mEffect.SettingsName(i); wxString newName = wxGetTextFromUser(_("Change name to:"), oldName, oldName, this); if (newName != wxT("")) mEffect.SaveSettings(i, 0, &newName); } } void ReverbDialogue::OnPreview(wxCommandEvent & event) { if (event.GetId() == ePreviewID) { EffectReverb::Params savedParams(mParams); TransferDataFromWindow(); mEffect.Preview(); mParams = savedParams; } else mEffect.Preview(true); }