Audacity 3.2.0
Amplify.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 Amplify.cpp
6
7 Dominic Mazzoni
8 Vaughan Johnson (Preview)
9
10*******************************************************************//*******************************************************************/
20
21#include "Amplify.h"
22#include "EffectEditor.h"
23#include "LoadEffects.h"
24
25#include <math.h>
26#include <float.h>
27
28#include <wx/button.h>
29#include <wx/checkbox.h>
30#include <wx/sizer.h>
31#include <wx/slider.h>
32#include <wx/stattext.h>
33#include <wx/textctrl.h>
34#include <wx/valtext.h>
35#include <wx/log.h>
36
37#include "EffectOutputTracks.h"
38#include "ShuttleGui.h"
40#include "WaveTrack.h"
41#include "TimeStretching.h"
42#include "../widgets/valnum.h"
43
44
45enum
46{
47 ID_Amp = 10000,
50};
51
53
54BEGIN_EVENT_TABLE(EffectAmplify, wxEvtHandler)
60
61// ComponentInterface implementation
62
64{
65 return Symbol;
66}
67
69{
70 // Note: This is useful only after ratio has been set.
71 return XO("Increases or decreases the volume of the audio you have selected");
72}
73
75{
76 return L"Amplify";
77}
78
79// EffectDefinitionInterface implementation
80
81std::unique_ptr<EffectEditor> EffectAmplify::PopulateOrExchange(
83 const EffectOutputs *)
84{
85 mUIParent = S.GetParent();
86
87 enum{ precision = 3 }; // allow (a generous) 3 decimal places for Amplification (dB)
88
89 bool batch = IsBatchProcessing();
90 if ( batch )
91 {
92 mCanClip = true;
93 mPeak = 1.0;
94 }
95 else
96 {
97 if (mPeak > 0.0)
98 {
99 mRatio = 1.0 / mPeak;
101 }
102 else
103 {
104 mRatio = 1.0;
105 }
106 }
107
108 // At this point mNewPeak is still uninitialized; this will initialize it
109 ClampRatio();
110
111 S.AddSpace(0, 5);
112
113 S.StartVerticalLay(0);
114 {
115 // Amplitude
116 S.StartMultiColumn(2, wxCENTER);
117 {
118 mAmpT = S.Id(ID_Amp)
119 .Validator<FloatingPointValidator<double>>(
120 precision, &mAmp, NumValidatorStyle::ONE_TRAILING_ZERO, Amp.min, Amp.max )
121 .AddTextBox(XXO("&Amplification (dB):"), L"", 12);
122 }
123 S.EndMultiColumn();
124
125 // Amplitude
126 S.StartHorizontalLay(wxEXPAND);
127 {
128 mAmpS = S.Id(ID_Amp)
129 .Style(wxSL_HORIZONTAL)
130 .Name(XO("Amplification dB"))
131 .AddSlider( {}, 0, Amp.max * Amp.scale, Amp.min * Amp.scale);
132 }
133 S.EndHorizontalLay();
134
135 // Peak
136 S.StartMultiColumn(2, wxCENTER);
137 {
138 mNewPeakT = S.Id(ID_Peak)
139 .Validator<FloatingPointValidator<double>>(
140 // One extra decimal place so that rounding is visible to user
141 // (see: bug 958)
142 precision + 1,
143 &mNewPeak, NumValidatorStyle::ONE_TRAILING_ZERO,
144 // min and max need same precision as what we're validating (bug 963)
145 RoundValue( precision + 1, Amp.min + LINEAR_TO_DB(mPeak) ),
146 RoundValue( precision + 1, Amp.max + LINEAR_TO_DB(mPeak) ) )
147 .AddTextBox(XXO("&New Peak Amplitude (dB):"), L"", 12);
148 }
149 S.EndMultiColumn();
150
151 // Clipping
152 S.StartHorizontalLay(wxCENTER);
153 {
154
155 mClip = S.Id(ID_Clip).Disable( batch )
156 .AddCheckBox(XXO("Allo&w clipping"), false);
157 }
158 S.EndHorizontalLay();
159 }
160 S.EndVerticalLay();
161
162 return nullptr;
163}
164
166{
167 mAmpT->GetValidator()->TransferToWindow();
168
169 mAmpS->SetValue((int) (mAmp * Amp.scale + 0.5f));
170
171 mNewPeakT->GetValidator()->TransferToWindow();
172
173 mClip->SetValue(mCanClip);
174
175 CheckClip();
176
177 return true;
178}
179
181{
182 if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
183 {
184 return false;
185 }
186
187 mRatio = DB_TO_LINEAR(std::clamp<double>(mAmp * Amp.scale, Amp.min * Amp.scale, Amp.max * Amp.scale) / Amp.scale);
188
189 mCanClip = mClip->GetValue();
190
191 if (!mCanClip && mRatio * mPeak > 1.0)
192 {
193 mRatio = 1.0 / mPeak;
194 }
195
196 ClampRatio();
197
198 return true;
199}
200
201std::shared_ptr<EffectInstance> EffectAmplify::MakeInstance() const
202{
203 // Cheat with const_cast to return an object that calls through to
204 // non-const methods of a stateful effect.
205 return std::make_shared<Instance>(const_cast<EffectAmplify&>(*this));
206}
207
208// AmplifyBase implementation
209
211{
213 mClip->GetValue() || (mPeak > 0.0 && mRatio <= mRatioClip));
214}
215
216void EffectAmplify::OnAmpText(wxCommandEvent & WXUNUSED(evt))
217{
218 if (!mAmpT->GetValidator()->TransferFromWindow())
219 {
221 return;
222 }
223
224 mRatio = DB_TO_LINEAR(std::clamp<double>(mAmp * Amp.scale, Amp.min * Amp.scale, Amp.max * Amp.scale) / Amp.scale);
225
226 mAmpS->SetValue((int) (LINEAR_TO_DB(mRatio) * Amp.scale + 0.5));
227
229 mNewPeakT->GetValidator()->TransferToWindow();
230
231 CheckClip();
232}
233
234void EffectAmplify::OnPeakText(wxCommandEvent & WXUNUSED(evt))
235{
236 if (!mNewPeakT->GetValidator()->TransferFromWindow())
237 {
239 return;
240 }
241
242 if (mNewPeak == 0.0)
244 else
246
247 double ampInit = LINEAR_TO_DB(mRatio);
248 mAmp = std::clamp<double>(ampInit, Amp.min, Amp.max);
249 if (mAmp != ampInit)
251
252 mAmpT->GetValidator()->TransferToWindow();
253
254 mAmpS->SetValue((int) (mAmp * Amp.scale + 0.5f));
255
256 CheckClip();
257}
258
259void EffectAmplify::OnAmpSlider(wxCommandEvent & evt)
260{
261 double dB = evt.GetInt() / Amp.scale;
262 mRatio = DB_TO_LINEAR(std::clamp<double>(dB, Amp.min, Amp.max));
263
264 double dB2 = (evt.GetInt() - 1) / Amp.scale;
265 double ratio2 = DB_TO_LINEAR(std::clamp<double>(dB2, Amp.min, Amp.max));
266
267 if (!mClip->GetValue() && mRatio * mPeak > 1.0 && ratio2 * mPeak < 1.0)
268 {
269 mRatio = 1.0 / mPeak;
270 }
271
273 mAmpT->GetValidator()->TransferToWindow();
274
276 mNewPeakT->GetValidator()->TransferToWindow();
277
278 CheckClip();
279}
280
281void EffectAmplify::OnClipCheckBox(wxCommandEvent & WXUNUSED(evt))
282{
283 CheckClip();
284}
@ ID_Clip
Definition: Amplify.cpp:49
@ ID_Peak
Definition: Amplify.cpp:48
@ ID_Amp
Definition: Amplify.cpp:47
END_EVENT_TABLE()
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:339
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:338
#define S(N)
Definition: ToChars.cpp:64
double mNewPeak
Definition: AmplifyBase.h:55
double mRatio
Definition: AmplifyBase.h:51
double mPeak
Definition: AmplifyBase.h:49
void ClampRatio()
double mAmp
Definition: AmplifyBase.h:54
double mRatioClip
Definition: AmplifyBase.h:52
static constexpr EffectParameter Amp
Definition: AmplifyBase.h:66
bool mCanClip
Definition: AmplifyBase.h:56
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
An Effect that makes a sound louder or softer.
Definition: Amplify.h:28
wxWeakRef< wxWindow > mUIParent
Definition: Amplify.h:54
wxTextCtrl * mNewPeakT
Definition: Amplify.h:58
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
Definition: Amplify.cpp:201
void OnClipCheckBox(wxCommandEvent &evt)
Definition: Amplify.cpp:281
wxSlider * mAmpS
Definition: Amplify.h:56
void OnAmpSlider(wxCommandEvent &evt)
Definition: Amplify.cpp:259
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
Definition: Amplify.cpp:74
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Add controls to effect panel; always succeeds.
Definition: Amplify.cpp:81
bool TransferDataToWindow(const EffectSettings &settings) override
Definition: Amplify.cpp:165
bool TransferDataFromWindow(EffectSettings &settings) override
Definition: Amplify.cpp:180
wxCheckBox * mClip
Definition: Amplify.h:59
void OnAmpText(wxCommandEvent &evt)
Definition: Amplify.cpp:216
TranslatableString GetDescription() const override
Definition: Amplify.cpp:68
void OnPeakText(wxCommandEvent &evt)
Definition: Amplify.cpp:234
wxTextCtrl * mAmpT
Definition: Amplify.h:57
void CheckClip()
Definition: Amplify.cpp:210
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
bool IsBatchProcessing() const override
Definition: Effect.cpp:295
Performs effect computation.
Hold values to send to effect output meters.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
Holds a msgid for the translation catalog; may also bind format arguments.
BuiltinEffectsModule::Registration< EffectAmplify > reg
Definition: Amplify.cpp:52
const Type scale
Scaling factor, for slider control.
const Type min
Minimum value.
const Type max
Maximum value.
Externalized state of a plug-in.