Audacity  3.0.3
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 
22 #include "Amplify.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/intl.h>
31 #include <wx/sizer.h>
32 #include <wx/slider.h>
33 #include <wx/stattext.h>
34 #include <wx/textctrl.h>
35 #include <wx/valtext.h>
36 #include <wx/log.h>
37 
38 #include "../Shuttle.h"
39 #include "../ShuttleGui.h"
40 #include "../WaveTrack.h"
41 #include "../widgets/valnum.h"
42 
43 
44 enum
45 {
46  ID_Amp = 10000,
48  ID_Clip
49 };
50 
51 // Define keys, defaults, minimums, and maximums for the effect parameters
52 //
53 // Name Type Key Def Min Max Scale
54 Param( Ratio, float, wxT("Ratio"), 0.9f, 0.003162f, 316.227766f, 1.0f );
55 Param( Amp, float, wxT(""), -0.91515f, -50.0f, 50.0f, 10.0f );
56 Param( Clipping, bool, wxT("AllowClipping"), false, false, true, 1 );
57 
58 //
59 // EffectAmplify
60 //
61 
63 { XO("Amplify") };
64 
66 
67 BEGIN_EVENT_TABLE(EffectAmplify, wxEvtHandler)
73 
75 {
76  mAmp = DEF_Amp;
77  mRatio = DB_TO_LINEAR(mAmp);
78  mRatioClip = 0.0;
79  mCanClip = false;
80  mPeak = 0.0;
81 
82  SetLinearEffectFlag(true);
83 }
84 
86 {
87 }
88 
89 // ComponentInterface implementation
90 
92 {
93  return Symbol;
94 }
95 
97 {
98  // Note: This is useful only after ratio has been set.
99  return XO("Increases or decreases the volume of the audio you have selected");
100 }
101 
103 {
104  return L"Amplify";
105 }
106 
107 // EffectDefinitionInterface implementation
108 
110 {
111  return EffectTypeProcess;
112 }
113 
114 // EffectClientInterface implementation
115 
117 {
118  return 1;
119 }
120 
122 {
123  return 1;
124 }
125 
126 size_t EffectAmplify::ProcessBlock(float **inBlock, float **outBlock, size_t blockLen)
127 {
128  for (decltype(blockLen) i = 0; i < blockLen; i++)
129  {
130  outBlock[0][i] = inBlock[0][i] * mRatio;
131  }
132 
133  return blockLen;
134 }
136  S.SHUTTLE_PARAM( mRatio, Ratio );
137  if (!IsBatchProcessing())
138  S.SHUTTLE_PARAM( mCanClip, Clipping );
139  return true;
140 }
141 
143 {
144  parms.WriteFloat(KEY_Ratio, mRatio);
145  if (!IsBatchProcessing())
146  parms.WriteFloat(KEY_Clipping, mCanClip);
147 
148  return true;
149 }
150 
152 {
153  ReadAndVerifyFloat(Ratio);
154  mRatio = Ratio;
155 
156  if (!IsBatchProcessing()){
157  ReadAndVerifyBool(Clipping);
158  mCanClip = Clipping;
159  } else {
160  mCanClip = true;
161  }
162 
163  return true;
164 }
165 
167 {
168  Init();
169 
170  mRatioClip = 0.0;
171  if (mPeak > 0.0)
172  {
173  mRatio = 1.0 / mPeak;
174  mRatioClip = mRatio;
175  }
176  else
177  {
178  mRatio = 1.0;
179  }
180  mCanClip = false;
181 
182  return TransferDataToWindow();
183 }
184 
185 // Effect implementation
186 
188 {
189  mPeak = 0.0;
190 
191  for (auto t : inputTracks()->Selected< const WaveTrack >())
192  {
193  auto pair = t->GetMinMax(mT0, mT1); // may throw
194  const float min = pair.first, max = pair.second;
195  float newpeak = (fabs(min) > fabs(max) ? fabs(min) : fabs(max));
196 
197  if (newpeak > mPeak)
198  {
199  mPeak = newpeak;
200  }
201  }
202 
203  return true;
204 }
205 
206 void EffectAmplify::Preview(bool dryOnly)
207 {
208  auto cleanup1 = valueRestorer( mRatio );
209  auto cleanup2 = valueRestorer( mPeak );
210 
211  Effect::Preview(dryOnly);
212 }
213 
215 {
216  enum{ precision = 3 }; // allow (a generous) 3 decimal places for Amplification (dB)
217 
218  bool batch = IsBatchProcessing();
219  if ( batch )
220  {
221  mCanClip = true;
222  mPeak = 1.0;
223  }
224  else
225  {
226  if (mPeak > 0.0)
227  {
228  mRatio = 1.0 / mPeak;
229  mRatioClip = mRatio;
230  }
231  else
232  {
233  mRatio = 1.0;
234  }
235  }
236 
237  S.AddSpace(0, 5);
238 
239  S.StartVerticalLay(0);
240  {
241  // Amplitude
242  S.StartMultiColumn(2, wxCENTER);
243  {
244  mAmpT = S.Id(ID_Amp)
245  .Validator<FloatingPointValidator<double>>(
246  precision, &mAmp, NumValidatorStyle::ONE_TRAILING_ZERO, MIN_Amp, MAX_Amp
247  )
248  .AddTextBox(XXO("&Amplification (dB):"), wxT(""), 12);
249  }
250  S.EndMultiColumn();
251 
252  // Amplitude
253  S.StartHorizontalLay(wxEXPAND);
254  {
255  mAmpS = S.Id(ID_Amp)
256  .Style(wxSL_HORIZONTAL)
257  .Name(XO("Amplification dB"))
258  .AddSlider( {}, 0, MAX_Amp * SCL_Amp, MIN_Amp * SCL_Amp);
259  }
260  S.EndHorizontalLay();
261 
262  // Peak
263  S.StartMultiColumn(2, wxCENTER);
264  {
265  mNewPeakT = S.Id(ID_Peak)
266  .Validator<FloatingPointValidator<double>>(
267  // One extra decimal place so that rounding is visible to user
268  // (see: bug 958)
269  precision + 1,
270  &mNewPeak, NumValidatorStyle::ONE_TRAILING_ZERO,
271  // min and max need same precision as what we're validating (bug 963)
272  RoundValue( precision + 1, MIN_Amp + LINEAR_TO_DB(mPeak) ),
273  RoundValue( precision + 1, MAX_Amp + LINEAR_TO_DB(mPeak) )
274  )
275  .AddTextBox(XXO("&New Peak Amplitude (dB):"), wxT(""), 12);
276  }
277  S.EndMultiColumn();
278 
279  // Clipping
280  S.StartHorizontalLay(wxCENTER);
281  {
282 
283  mClip = S.Id(ID_Clip).Disable( batch )
284  .AddCheckBox(XXO("Allo&w clipping"), false);
285  }
286  S.EndHorizontalLay();
287  }
288  S.EndVerticalLay();
289 
290  return;
291 }
292 
294 {
295  // limit range of gain
296  double dBInit = LINEAR_TO_DB(mRatio);
297  double dB = TrapDouble(dBInit, MIN_Amp, MAX_Amp);
298  if (dB != dBInit)
299  mRatio = DB_TO_LINEAR(dB);
300 
302  mAmpT->GetValidator()->TransferToWindow();
303 
304  mAmpS->SetValue((int) (mAmp * SCL_Amp + 0.5f));
305 
307  mNewPeakT->GetValidator()->TransferToWindow();
308 
309  mClip->SetValue(mCanClip);
310 
311  CheckClip();
312 
313  return true;
314 }
315 
317 {
318  if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
319  {
320  return false;
321  }
322 
323  mRatio = DB_TO_LINEAR(TrapDouble(mAmp * SCL_Amp, MIN_Amp * SCL_Amp, MAX_Amp * SCL_Amp) / SCL_Amp);
324 
325  mCanClip = mClip->GetValue();
326 
327  if (!mCanClip && mRatio * mPeak > 1.0)
328  {
329  mRatio = 1.0 / mPeak;
330  }
331 
332  return true;
333 }
334 
335 // EffectAmplify implementation
336 
338 {
339  EnableApply(mClip->GetValue() || (mPeak > 0.0 && mRatio <= mRatioClip));
340 }
341 
342 void EffectAmplify::OnAmpText(wxCommandEvent & WXUNUSED(evt))
343 {
344  if (!mAmpT->GetValidator()->TransferFromWindow())
345  {
346  EnableApply(false);
347  return;
348  }
349 
350  mRatio = DB_TO_LINEAR(TrapDouble(mAmp * SCL_Amp, MIN_Amp * SCL_Amp, MAX_Amp * SCL_Amp) / SCL_Amp);
351 
352  mAmpS->SetValue((int) (LINEAR_TO_DB(mRatio) * SCL_Amp + 0.5));
353 
355  mNewPeakT->GetValidator()->TransferToWindow();
356 
357  CheckClip();
358 }
359 
360 void EffectAmplify::OnPeakText(wxCommandEvent & WXUNUSED(evt))
361 {
362  if (!mNewPeakT->GetValidator()->TransferFromWindow())
363  {
364  EnableApply(false);
365  return;
366  }
367 
368  if (mNewPeak == 0.0)
369  mRatio = mRatioClip;
370  else
372 
373  double ampInit = LINEAR_TO_DB(mRatio);
374  mAmp = TrapDouble(ampInit, MIN_Amp, MAX_Amp);
375  if (mAmp != ampInit)
377 
378  mAmpT->GetValidator()->TransferToWindow();
379 
380  mAmpS->SetValue((int) (mAmp * SCL_Amp + 0.5f));
381 
382  CheckClip();
383 }
384 
385 void EffectAmplify::OnAmpSlider(wxCommandEvent & evt)
386 {
387  double dB = evt.GetInt() / SCL_Amp;
388  mRatio = DB_TO_LINEAR(TrapDouble(dB, MIN_Amp, MAX_Amp));
389 
390  double dB2 = (evt.GetInt() - 1) / SCL_Amp;
391  double ratio2 = DB_TO_LINEAR(TrapDouble(dB2, MIN_Amp, MAX_Amp));
392 
393  if (!mClip->GetValue() && mRatio * mPeak > 1.0 && ratio2 * mPeak < 1.0)
394  {
395  mRatio = 1.0 / mPeak;
396  }
397 
399  mAmpT->GetValidator()->TransferToWindow();
400 
402  mNewPeakT->GetValidator()->TransferToWindow();
403 
404  CheckClip();
405 }
406 
407 void EffectAmplify::OnClipCheckBox(wxCommandEvent & WXUNUSED(evt))
408 {
409  CheckClip();
410 }
EffectAmplify::GetAudioOutCount
unsigned GetAudioOutCount() override
Definition: Amplify.cpp:121
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
EffectAmplify::mRatio
double mRatio
Definition: Amplify.h:74
CommandParameters
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
Definition: EffectAutomationParameters.h:67
valueRestorer
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:354
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
DB_TO_LINEAR
const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB)
ShuttleGuiBase::AddCheckBox
wxCheckBox * AddCheckBox(const TranslatableString &Prompt, bool Selected)
Definition: ShuttleGui.cpp:309
ID_Amp
@ ID_Amp
Definition: Amplify.cpp:46
Effect::EnableApply
virtual bool EnableApply(bool enable=true)
Definition: Effect.cpp:1926
EffectAmplify::GetDescription
TranslatableString GetDescription() override
Definition: Amplify.cpp:96
EffectAmplify::OnPeakText
void OnPeakText(wxCommandEvent &evt)
Definition: Amplify.cpp:360
Amplify.h
EffectAmplify::CheckClip
void CheckClip()
Definition: Amplify.cpp:337
Effect::mT1
double mT1
Definition: Effect.h:467
EffectAmplify::mRatioClip
double mRatioClip
Definition: Amplify.h:75
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2459
XO
#define XO(s)
Definition: Internat.h:31
EffectAmplify::mAmp
double mAmp
Definition: Amplify.h:76
EffectAmplify::SetAutomationParameters
bool SetAutomationParameters(CommandParameters &parms) override
Definition: Amplify.cpp:151
ShuttleParams
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:62
EffectAmplify::ManualPage
ManualPageID ManualPage() override
Definition: Amplify.cpp:102
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
Effect::IsBatchProcessing
virtual bool IsBatchProcessing()
Definition: Effect.cpp:1190
EffectAmplify::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: Amplify.h:29
CommandParameters::WriteFloat
bool WriteFloat(const wxString &key, float f)
Definition: EffectAutomationParameters.h:155
EffectAmplify::GetAudioInCount
unsigned GetAudioInCount() override
Definition: Amplify.cpp:116
EffectAmplify::mNewPeakT
wxTextCtrl * mNewPeakT
Definition: Amplify.h:82
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
EffectAmplify::mCanClip
bool mCanClip
Definition: Amplify.h:78
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2274
EffectAmplify::LoadFactoryDefaults
bool LoadFactoryDefaults() override
Definition: Amplify.cpp:166
ShuttleGui::Style
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:727
XXO
#define XXO(s)
Definition: Internat.h:44
Effect::inputTracks
const TrackList * inputTracks() const
Definition: Effect.h:463
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1177
Effect::mT0
double mT0
Definition: Effect.h:466
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1167
EffectAmplify::mAmpT
wxTextCtrl * mAmpT
Definition: Amplify.h:81
ShuttleGui::Disable
ShuttleGui & Disable(bool disabled=true)
Definition: ShuttleGui.h:650
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
EffectAmplify::GetType
EffectType GetType() override
Definition: Amplify.cpp:109
EffectAmplify::DefineParams
bool DefineParams(ShuttleParams &S) override
Definition: Amplify.cpp:135
EffectAmplify::ProcessBlock
size_t ProcessBlock(float **inBlock, float **outBlock, size_t blockLen) override
Definition: Amplify.cpp:126
EffectAmplify::mNewPeak
double mNewPeak
Definition: Amplify.h:77
ShuttleGui::Validator
ShuttleGui & Validator(const Factory &f)
Definition: ShuttleGui.h:678
EffectAmplify::OnAmpSlider
void OnAmpSlider(wxCommandEvent &evt)
Definition: Amplify.cpp:385
EffectAmplify::mPeak
double mPeak
Definition: Amplify.h:72
EffectAmplify::OnClipCheckBox
void OnClipCheckBox(wxCommandEvent &evt)
Definition: Amplify.cpp:407
EffectAmplify::TransferDataToWindow
bool TransferDataToWindow() override
Definition: Amplify.cpp:293
Effect::Preview
virtual void Preview(bool dryOnly)
Definition: Effect.cpp:2295
LoadEffects.h
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
anonymous_namespace{Amplify.cpp}::reg
BuiltinEffectsModule::Registration< EffectAmplify > reg
Definition: Amplify.cpp:65
EffectAmplify::Init
bool Init() override
Definition: Amplify.cpp:187
EffectAmplify::GetAutomationParameters
bool GetAutomationParameters(CommandParameters &parms) override
Definition: Amplify.cpp:142
ID_Clip
@ ID_Clip
Definition: Amplify.cpp:48
EffectAmplify::mClip
wxCheckBox * mClip
Definition: Amplify.h:83
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
Effect::mUIParent
wxWindow * mUIParent
Definition: Effect.h:478
TaggedIdentifier< ManualPageIDTag >
EffectAmplify::OnAmpText
void OnAmpText(wxCommandEvent &evt)
Definition: Amplify.cpp:342
EffectAmplify::mAmpS
wxSlider * mAmpS
Definition: Amplify.h:80
EffectAmplify::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: Amplify.cpp:214
LINEAR_TO_DB
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:631
EffectAmplify::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: Amplify.cpp:91
EffectAmplify
An Effect that makes a sound louder or softer.
Definition: Amplify.h:27
EffectAmplify::Preview
void Preview(bool dryOnly) override
Definition: Amplify.cpp:206
TrapDouble
double TrapDouble(double x, double min, double max)
Definition: Effect.h:564
EffectAmplify::~EffectAmplify
virtual ~EffectAmplify()
Definition: Amplify.cpp:85
Param
Param(Ratio, float, wxT("Ratio"), 0.9f, 0.003162f, 316.227766f, 1.0f)
ID_Peak
@ ID_Peak
Definition: Amplify.cpp:47
EffectType
EffectType
Definition: EffectInterface.h:55
END_EVENT_TABLE
END_EVENT_TABLE()
EffectAmplify::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: Amplify.cpp:316
ReadAndVerifyBool
#define ReadAndVerifyBool(name)
Definition: Effect.h:635
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
ReadAndVerifyFloat
#define ReadAndVerifyFloat(name)
Definition: Effect.h:634