Audacity  3.2.0
Distortion.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  Distortion.cpp
6 
7  Steve Daulton
8 
9  // TODO: Add a graph display of the waveshaper equation.
10  // TODO: Allow the user to draw the graph.
11 
12 ******************************************************************//*******************************************************************/
18 
19 
20 #include "Distortion.h"
21 #include "LoadEffects.h"
22 
23 #include <cmath>
24 #include <algorithm>
25 #define _USE_MATH_DEFINES
26 
27 // Belt and braces
28 #ifndef M_PI
29 #define M_PI 3.1415926535897932384626433832795
30 #endif
31 #ifndef M_PI_2
32 #define M_PI_2 1.57079632679489661923132169163975
33 #endif
34 
35 #include <wx/checkbox.h>
36 #include <wx/choice.h>
37 #include <wx/intl.h>
38 #include <wx/valgen.h>
39 #include <wx/log.h>
40 #include <wx/slider.h>
41 #include <wx/stattext.h>
42 
43 #include "Prefs.h"
44 #include "../Shuttle.h"
45 #include "../ShuttleGui.h"
46 #include "../widgets/valnum.h"
47 
49 {
62 };
63 
65 {
66  { XO("Hard Clipping") },
67  { XO("Soft Clipping") },
68  { XO("Soft Overdrive") },
69  { XO("Medium Overdrive") },
70  { XO("Hard Overdrive") },
71  { XO("Cubic Curve (odd harmonics)") },
72  { XO("Even Harmonics") },
73  { XO("Expand and Compress") },
74  { XO("Leveller") },
75  { XO("Rectifier Distortion") },
76  { XO("Hard Limiter 1413") }
77 };
78 
79 // Define keys, defaults, minimums, and maximums for the effect parameters
80 // (Note: 'Repeats' is the total number of times the effect is applied.)
81 //
82 // Name Type Key Def Min Max Scale
83 Param( TableTypeIndx, int, wxT("Type"), 0, 0, nTableTypes-1, 1 );
84 Param( DCBlock, bool, wxT("DC Block"), false, false, true, 1 );
85 Param( Threshold_dB, double, wxT("Threshold dB"), -6.0, -100.0, 0.0, 1000.0f );
86 Param( NoiseFloor, double, wxT("Noise Floor"), -70.0, -80.0, -20.0, 1 );
87 Param( Param1, double, wxT("Parameter 1"), 50.0, 0.0, 100.0, 1 );
88 Param( Param2, double, wxT("Parameter 2"), 50.0, 0.0, 100.0, 1 );
89 Param( Repeats, int, wxT("Repeats"), 1, 0, 5, 1 );
90 
91 // How many samples are processed before recomputing the lookup table again
92 #define skipsamples 1000
93 
94 const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB);
95 
96 static const struct
97 {
100 }
101 FactoryPresets[] =
102 {
103  // Table DCBlock threshold floor Param1 Param2 Repeats
104  // Defaults: 0 false -6.0 -70.0(off) 50.0 50.0 1
105  //
106  // xgettext:no-c-format
107  { XO("Hard clip -12dB, 80% make-up gain"), { 0, 0, -12.0, -70.0, 0.0, 80.0, 0 } },
108  // xgettext:no-c-format
109  { XO("Soft clip -12dB, 80% make-up gain"), { 1, 0, -12.0, -70.0, 50.0, 80.0, 0 } },
110  { XO("Fuzz Box"), { 1, 0, -30.0, -70.0, 80.0, 80.0, 0 } },
111  { XO("Walkie-talkie"), { 1, 0, -50.0, -70.0, 60.0, 80.0, 0 } },
112  { XO("Blues drive sustain"), { 2, 0, -6.0, -70.0, 30.0, 80.0, 0 } },
113  { XO("Light Crunch Overdrive"), { 3, 0, -6.0, -70.0, 20.0, 80.0, 0 } },
114  { XO("Heavy Overdrive"), { 4, 0, -6.0, -70.0, 90.0, 80.0, 0 } },
115  { XO("3rd Harmonic (Perfect Fifth)"), { 5, 0, -6.0, -70.0, 100.0, 60.0, 0 } },
116  { XO("Valve Overdrive"), { 6, 1, -6.0, -70.0, 30.0, 40.0, 0 } },
117  { XO("2nd Harmonic (Octave)"), { 6, 1, -6.0, -70.0, 50.0, 0.0, 0 } },
118  { XO("Gated Expansion Distortion"), { 7, 0, -6.0, -70.0, 30.0, 80.0, 0 } },
119  { XO("Leveller, Light, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 1 } },
120  { XO("Leveller, Moderate, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 2 } },
121  { XO("Leveller, Heavy, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 3 } },
122  { XO("Leveller, Heavier, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 4 } },
123  { XO("Leveller, Heaviest, -70dB noise floor"), { 8, 0, -6.0, -70.0, 0.0, 50.0, 5 } },
124  { XO("Half-wave Rectifier"), { 9, 0, -6.0, -70.0, 50.0, 50.0, 0 } },
125  { XO("Full-wave Rectifier"), { 9, 0, -6.0, -70.0, 100.0, 50.0, 0 } },
126  { XO("Full-wave Rectifier (DC blocked)"), { 9, 1, -6.0, -70.0, 100.0, 50.0, 0 } },
127  { XO("Percussion Limiter"), {10, 0, -12.0, -70.0, 100.0, 30.0, 0 } },
128 };
129 
131 {
132  static const TranslatableString names[] = {
133  XO("Upper Threshold"),
134  XO("Noise Floor"),
135  XO("Parameter 1"),
136  XO("Parameter 2"),
137  XO("Number of repeats"),
138  };
139 
140  return names[ index ];
141 }
142 
143 //
144 // EffectDistortion
145 //
146 
148 { XO("Distortion") };
149 
151 
152 BEGIN_EVENT_TABLE(EffectDistortion, wxEvtHandler)
154  EVT_CHECKBOX(ID_DCBlock, EffectDistortion::OnDCBlockCheckbox)
159  EVT_TEXT(ID_Param1, EffectDistortion::OnParam1Text)
160  EVT_SLIDER(ID_Param1, EffectDistortion::OnParam1Slider)
161  EVT_TEXT(ID_Param2, EffectDistortion::OnParam2Text)
162  EVT_SLIDER(ID_Param2, EffectDistortion::OnParam2Slider)
163  EVT_TEXT(ID_Repeats, EffectDistortion::OnRepeatsText)
164  EVT_SLIDER(ID_Repeats, EffectDistortion::OnRepeatsSlider)
166 
168 {
169  wxASSERT(nTableTypes == WXSIZEOF(kTableTypeStrings));
170 
171  mParams.mTableChoiceIndx = DEF_TableTypeIndx;
172  mParams.mDCBlock = DEF_DCBlock;
173  mParams.mThreshold_dB = DEF_Threshold_dB;
174  mThreshold = DB_TO_LINEAR(mParams.mThreshold_dB);
175  mParams.mNoiseFloor = DEF_NoiseFloor;
176  mParams.mParam1 = DEF_Param1;
177  mParams.mParam2 = DEF_Param2;
178  mParams.mRepeats = DEF_Repeats;
179  mMakeupGain = 1.0;
180  mbSavedFilterState = DEF_DCBlock;
181 
182  SetLinearEffectFlag(false);
183 }
184 
186 {
187 }
188 
189 // ComponentInterface implementation
190 
192 {
193  return Symbol;
194 }
195 
197 {
198  return XO("Waveshaping distortion effect");
199 }
200 
202 {
203  return L"Distortion";
204 }
205 
206 // EffectDefinitionInterface implementation
207 
209 {
210  return EffectTypeProcess;
211 }
212 
214 {
215  return true;
216 }
217 
218 // EffectProcessor implementation
219 
221 {
222  return 1;
223 }
224 
226 {
227  return 1;
228 }
229 
230 bool EffectDistortion::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames WXUNUSED(chanMap))
231 {
233  return true;
234 }
235 
236 size_t EffectDistortion::ProcessBlock(float **inBlock, float **outBlock, size_t blockLen)
237 {
238  return InstanceProcess(mMaster, inBlock, outBlock, blockLen);
239 }
240 
242 {
243  SetBlockSize(512);
244 
245  mSlaves.clear();
246 
247  return true;
248 }
249 
250 bool EffectDistortion::RealtimeAddProcessor(unsigned WXUNUSED(numChannels), float sampleRate)
251 {
252  EffectDistortionState slave;
253 
254  InstanceInit(slave, sampleRate);
255 
256  mSlaves.push_back(slave);
257 
258  return true;
259 }
260 
262 {
263  mSlaves.clear();
264 
265  return true;
266 }
267 
269  float **inbuf,
270  float **outbuf,
271  size_t numSamples)
272 {
273 
274  return InstanceProcess(mSlaves[group], inbuf, outbuf, numSamples);
275 }
277  S.SHUTTLE_ENUM_PARAM( mParams.mTableChoiceIndx, TableTypeIndx,
279  S.SHUTTLE_PARAM( mParams.mDCBlock, DCBlock );
280  S.SHUTTLE_PARAM( mParams.mThreshold_dB, Threshold_dB );
281  S.SHUTTLE_PARAM( mParams.mNoiseFloor, NoiseFloor );
282  S.SHUTTLE_PARAM( mParams.mParam1, Param1 );
283  S.SHUTTLE_PARAM( mParams.mParam2, Param2 );
284  S.SHUTTLE_PARAM( mParams.mRepeats, Repeats );
285  return true;
286 }
287 
289 {
290  parms.Write(KEY_TableTypeIndx,
292  parms.Write(KEY_DCBlock, mParams.mDCBlock);
293  parms.Write(KEY_Threshold_dB, mParams.mThreshold_dB);
294  parms.Write(KEY_NoiseFloor, mParams.mNoiseFloor);
295  parms.Write(KEY_Param1, mParams.mParam1);
296  parms.Write(KEY_Param2, mParams.mParam2);
297  parms.Write(KEY_Repeats, mParams.mRepeats);
298 
299  return true;
300 }
301 
303 {
305  ReadAndVerifyBool(DCBlock);
306  ReadAndVerifyDouble(Threshold_dB);
307  ReadAndVerifyDouble(NoiseFloor);
308  ReadAndVerifyDouble(Param1);
309  ReadAndVerifyDouble(Param2);
310  ReadAndVerifyInt(Repeats);
311 
312  mParams.mTableChoiceIndx = TableTypeIndx;
313  mParams.mDCBlock = DCBlock;
314  mParams.mThreshold_dB = Threshold_dB;
315  mParams.mNoiseFloor = NoiseFloor;
316  mParams.mParam1 = Param1;
317  mParams.mParam2 = Param2;
318  mParams.mRepeats = Repeats;
319 
320  return true;
321 }
322 
324 {
326 
327  for (size_t i = 0; i < WXSIZEOF(FactoryPresets); i++)
328  {
329  names.push_back( FactoryPresets[i].name.Translation() );
330  }
331 
332  return names;
333 }
334 
336 {
337  if (id < 0 || id >= (int) WXSIZEOF(FactoryPresets))
338  {
339  return false;
340  }
341 
342  mParams = FactoryPresets[id].params;
344 
345  if (mUIDialog)
346  {
348  }
349 
350  return true;
351 }
352 
353 
354 // Effect implementation
355 
357 {
358  S.AddSpace(0, 5);
359  S.StartVerticalLay();
360  {
361  S.StartMultiColumn(4, wxCENTER);
362  {
364  .MinSize( { -1, -1 } )
366  .AddChoice(XXO("Distortion type:"),
368 
369  mDCBlockCheckBox = S.Id(ID_DCBlock).AddCheckBox(XXO("DC blocking filter"),
370  DEF_DCBlock);
371  }
372  S.EndMultiColumn();
373  S.AddSpace(0, 10);
374 
375 
376  S.StartStatic(XO("Threshold controls"));
377  {
378  S.StartMultiColumn(4, wxEXPAND);
379  S.SetStretchyCol(2);
380  {
381  // Allow space for first Column
382  S.AddSpace(250,0); S.AddSpace(0,0); S.AddSpace(0,0); S.AddSpace(0,0);
383 
384  // Upper threshold control
385  mThresholdTxt = S.AddVariableText(defaultLabel(0),
386  false, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
388  .Name(defaultLabel(0))
389  .Validator<FloatingPointValidator<double>>(
390  2, &mParams.mThreshold_dB, NumValidatorStyle::DEFAULT,
391  MIN_Threshold_dB, MAX_Threshold_dB)
392  .AddTextBox( {}, wxT(""), 10);
393 
395  .Name(defaultLabel(0))
396  .Style(wxSL_HORIZONTAL)
397  .AddSlider( {}, 0,
398  DB_TO_LINEAR(MAX_Threshold_dB) * SCL_Threshold_dB,
399  DB_TO_LINEAR(MIN_Threshold_dB) * SCL_Threshold_dB);
400  S.AddSpace(20, 0);
401 
402  // Noise floor control
403  mNoiseFloorTxt = S.AddVariableText(defaultLabel(1),
404  false, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
406  .Name(defaultLabel(1))
407  .Validator<FloatingPointValidator<double>>(
408  2, &mParams.mNoiseFloor, NumValidatorStyle::DEFAULT,
409  MIN_NoiseFloor, MAX_NoiseFloor
410  )
411  .AddTextBox( {}, wxT(""), 10);
412 
414  .Name(defaultLabel(1))
415  .Style(wxSL_HORIZONTAL)
416  .AddSlider( {}, 0, MAX_NoiseFloor, MIN_NoiseFloor);
417  S.AddSpace(20, 0);
418  }
419  S.EndMultiColumn();
420  }
421  S.EndStatic();
422 
423  S.StartStatic(XO("Parameter controls"));
424  {
425  S.StartMultiColumn(4, wxEXPAND);
426  S.SetStretchyCol(2);
427  {
428  // Allow space for first Column
429  S.AddSpace(250,0); S.AddSpace(0,0); S.AddSpace(0,0); S.AddSpace(0,0);
430 
431  // Parameter1 control
432  mParam1Txt = S.AddVariableText(defaultLabel(2),
433  false, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
434  mParam1T = S.Id(ID_Param1)
435  .Name(defaultLabel(2))
436  .Validator<FloatingPointValidator<double>>(
437  2, &mParams.mParam1, NumValidatorStyle::DEFAULT,
438  MIN_Param1, MAX_Param1
439  )
440  .AddTextBox( {}, wxT(""), 10);
441 
442  mParam1S = S.Id(ID_Param1)
443  .Name(defaultLabel(2))
444  .Style(wxSL_HORIZONTAL)
445  .AddSlider( {}, 0, MAX_Param1, MIN_Param1);
446  S.AddSpace(20, 0);
447 
448  // Parameter2 control
449  mParam2Txt = S.AddVariableText(defaultLabel(3),
450  false, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
451  mParam2T = S.Id(ID_Param2)
452  .Name(defaultLabel(3))
453  .Validator<FloatingPointValidator<double>>(
454  2, &mParams.mParam2, NumValidatorStyle::DEFAULT,
455  MIN_Param2, MAX_Param2
456  )
457  .AddTextBox( {}, wxT(""), 10);
458 
459  mParam2S = S.Id(ID_Param2)
460  .Name(defaultLabel(3))
461  .Style(wxSL_HORIZONTAL)
462  .AddSlider( {}, 0, MAX_Param2, MIN_Param2);
463  S.AddSpace(20, 0);
464 
465  // Repeats control
466  mRepeatsTxt = S.AddVariableText(defaultLabel(4),
467  false, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
468  mRepeatsT = S.Id(ID_Repeats)
469  .Name(defaultLabel(4))
470  .Validator<IntegerValidator<int>>(
471  &mParams.mRepeats, NumValidatorStyle::DEFAULT,
472  MIN_Repeats, MAX_Repeats
473  )
474  .AddTextBox( {}, wxT(""), 10);
475 
476  mRepeatsS = S.Id(ID_Repeats)
477  .Name(defaultLabel(4))
478  .Style(wxSL_HORIZONTAL)
479  .AddSlider( {}, DEF_Repeats, MAX_Repeats, MIN_Repeats);
480  S.AddSpace(20, 0);
481  }
482  S.EndMultiColumn();
483  }
484  S.EndStatic();
485  }
486  S.EndVerticalLay();
487 
488  return;
489 }
490 
492 {
493  if (!mUIParent->TransferDataToWindow())
494  {
495  return false;
496  }
497 
498  mThresholdS->SetValue((int) (mThreshold * SCL_Threshold_dB + 0.5));
499  mDCBlockCheckBox->SetValue(mParams.mDCBlock);
500  mNoiseFloorS->SetValue((int) mParams.mNoiseFloor + 0.5);
501  mParam1S->SetValue((int) mParams.mParam1 + 0.5);
502  mParam2S->SetValue((int) mParams.mParam2 + 0.5);
503  mRepeatsS->SetValue(mParams.mRepeats);
504 
506 
507  UpdateUI();
508 
509  return true;
510 }
511 
513 {
514  if (!mUIParent->Validate() || !mUIParent->TransferDataFromWindow())
515  {
516  return false;
517  }
518 
520 
521  return true;
522 }
523 
525 {
526  data.samplerate = sampleRate;
527  data.skipcount = 0;
529  data.dcblock = mParams.mDCBlock;
532  data.param1 = mParams.mParam1;
533  data.param2 = mParams.mParam2;
534  data.repeats = mParams.mRepeats;
535 
536  // DC block filter variables
537  data.queuetotal = 0.0;
538 
539  //std::queue<float>().swap(data.queuesamples);
540  while (!data.queuesamples.empty())
541  data.queuesamples.pop();
542 
543  MakeTable();
544 
545  return;
546 }
547 
548 size_t EffectDistortion::InstanceProcess(EffectDistortionState& data, float** inBlock, float** outBlock, size_t blockLen)
549 {
550  float *ibuf = inBlock[0];
551  float *obuf = outBlock[0];
552 
553  bool update = (mParams.mTableChoiceIndx == data.tablechoiceindx &&
554  mParams.mNoiseFloor == data.noisefloor &&
555  mParams.mThreshold_dB == data.threshold &&
556  mParams.mParam1 == data.param1 &&
557  mParams.mParam2 == data.param2 &&
558  mParams.mRepeats == data.repeats)? false : true;
559 
560  double p1 = mParams.mParam1 / 100.0;
561  double p2 = mParams.mParam2 / 100.0;
562 
566  data.param1 = mParams.mParam1;
567  data.repeats = mParams.mRepeats;
568 
569  for (decltype(blockLen) i = 0; i < blockLen; i++) {
570  if (update && ((data.skipcount++) % skipsamples == 0)) {
571  MakeTable();
572  }
573 
574  switch (mParams.mTableChoiceIndx)
575  {
576  case kHardClip:
577  // Param2 = make-up gain.
578  obuf[i] = WaveShaper(ibuf[i]) * ((1 - p2) + (mMakeupGain * p2));
579  break;
580  case kSoftClip:
581  // Param2 = make-up gain.
582  obuf[i] = WaveShaper(ibuf[i]) * ((1 - p2) + (mMakeupGain * p2));
583  break;
584  case kHalfSinCurve:
585  obuf[i] = WaveShaper(ibuf[i]) * p2;
586  break;
587  case kExpCurve:
588  obuf[i] = WaveShaper(ibuf[i]) * p2;
589  break;
590  case kLogCurve:
591  obuf[i] = WaveShaper(ibuf[i]) * p2;
592  break;
593  case kCubic:
594  obuf[i] = WaveShaper(ibuf[i]) * p2;
595  break;
596  case kEvenHarmonics:
597  obuf[i] = WaveShaper(ibuf[i]);
598  break;
599  case kSinCurve:
600  obuf[i] = WaveShaper(ibuf[i]) * p2;
601  break;
602  case kLeveller:
603  obuf[i] = WaveShaper(ibuf[i]);
604  break;
605  case kRectifier:
606  obuf[i] = WaveShaper(ibuf[i]);
607  break;
608  case kHardLimiter:
609  // Mix equivalent to LADSPA effect's "Wet / Residual" mix
610  obuf[i] = (WaveShaper(ibuf[i]) * (p1 - p2)) + (ibuf[i] * p2);
611  break;
612  default:
613  obuf[i] = WaveShaper(ibuf[i]);
614  }
615  if (mParams.mDCBlock) {
616  obuf[i] = DCFilter(data, obuf[i]);
617  }
618  }
619 
620  return blockLen;
621 }
622 
623 void EffectDistortion::OnTypeChoice(wxCommandEvent& /*evt*/)
624 {
625  mTypeChoiceCtrl->GetValidator()->TransferFromWindow();
626 
627  UpdateUI();
628 }
629 
630 void EffectDistortion::OnDCBlockCheckbox(wxCommandEvent& /*evt*/)
631 {
632  mParams.mDCBlock = mDCBlockCheckBox->GetValue();
634 }
635 
636 
637 void EffectDistortion::OnThresholdText(wxCommandEvent& /*evt*/)
638 {
639  mThresholdT->GetValidator()->TransferFromWindow();
641  mThresholdS->SetValue((int) (mThreshold * SCL_Threshold_dB + 0.5));
642 }
643 
644 void EffectDistortion::OnThresholdSlider(wxCommandEvent& evt)
645 {
646  mThreshold = (double) evt.GetInt() / SCL_Threshold_dB;
647  mParams.mThreshold_dB = wxMax(LINEAR_TO_DB(mThreshold), MIN_Threshold_dB);
648  mThreshold = std::max(MIN_Threshold_Linear, mThreshold);
649  mThresholdT->GetValidator()->TransferToWindow();
650 }
651 
652 void EffectDistortion::OnNoiseFloorText(wxCommandEvent& /*evt*/)
653 {
654  mNoiseFloorT->GetValidator()->TransferFromWindow();
655  mNoiseFloorS->SetValue((int) floor(mParams.mNoiseFloor + 0.5));
656 }
657 
658 void EffectDistortion::OnNoiseFloorSlider(wxCommandEvent& evt)
659 {
660  mParams.mNoiseFloor = (double) evt.GetInt();
661  mNoiseFloorT->GetValidator()->TransferToWindow();
662 }
663 
664 
665 void EffectDistortion::OnParam1Text(wxCommandEvent& /*evt*/)
666 {
667  mParam1T->GetValidator()->TransferFromWindow();
668  mParam1S->SetValue((int) floor(mParams.mParam1 + 0.5));
669 }
670 
671 void EffectDistortion::OnParam1Slider(wxCommandEvent& evt)
672 {
673  mParams.mParam1 = (double) evt.GetInt();
674  mParam1T->GetValidator()->TransferToWindow();
675 }
676 
677 void EffectDistortion::OnParam2Text(wxCommandEvent& /*evt*/)
678 {
679  mParam2T->GetValidator()->TransferFromWindow();
680  mParam2S->SetValue((int) floor(mParams.mParam2 + 0.5));
681 }
682 
683 void EffectDistortion::OnParam2Slider(wxCommandEvent& evt)
684 {
685  mParams.mParam2 = (double) evt.GetInt();
686  mParam2T->GetValidator()->TransferToWindow();
687 }
688 
689 void EffectDistortion::OnRepeatsText(wxCommandEvent& /*evt*/)
690 {
691  mRepeatsT->GetValidator()->TransferFromWindow();
692  mRepeatsS->SetValue(mParams.mRepeats);
693 }
694 
695 void EffectDistortion::OnRepeatsSlider(wxCommandEvent& evt)
696 {
697  mParams.mRepeats = evt.GetInt();
698  mRepeatsT->GetValidator()->TransferToWindow();
699 
700 }
701 
703 {
704  // set control text and names to match distortion type
705  switch (mParams.mTableChoiceIndx)
706  {
707  case kHardClip:
713 
714  UpdateControl(ID_Threshold, true, XO("Clipping level"));
716  UpdateControl(ID_Param1, true, XO("Drive"));
717  UpdateControl(ID_Param2, true, XO("Make-up Gain"));
719  UpdateControl(ID_DCBlock, false, {});
720  break;
721  case kSoftClip:
727 
728  UpdateControl(ID_Threshold, true, XO("Clipping threshold"));
730  UpdateControl(ID_Param1, true, XO("Hardness"));
731  UpdateControl(ID_Param2, true, XO("Make-up Gain"));
733  UpdateControl(ID_DCBlock, false, {});
734  break;
735  case kHalfSinCurve:
741 
744  UpdateControl(ID_Param1, true, XO("Distortion amount"));
745  UpdateControl(ID_Param2, true, XO("Output level"));
747  UpdateControl(ID_DCBlock, false, {});
748  break;
749  case kExpCurve:
755 
758  UpdateControl(ID_Param1, true, XO("Distortion amount"));
759  UpdateControl(ID_Param2, true, XO("Output level"));
761  UpdateControl(ID_DCBlock, false, {});
762  break;
763  case kLogCurve:
769 
772  UpdateControl(ID_Param1, true, XO("Distortion amount"));
773  UpdateControl(ID_Param2, true, XO("Output level"));
775  UpdateControl(ID_DCBlock, false, {});
776  break;
777  case kCubic:
783 
786  UpdateControl(ID_Param1, true, XO("Distortion amount"));
787  UpdateControl(ID_Param2, true, XO("Output level"));
788  UpdateControl(ID_Repeats, true, XO("Repeat processing"));
789  UpdateControl(ID_DCBlock, false, {});
790  break;
791  case kEvenHarmonics:
797 
800  UpdateControl(ID_Param1, true, XO("Distortion amount"));
801  UpdateControl(ID_Param2, true, XO("Harmonic brightness"));
803  UpdateControl(ID_DCBlock, true, {});
804  break;
805  case kSinCurve:
811 
814  UpdateControl(ID_Param1, true, XO("Distortion amount"));
815  UpdateControl(ID_Param2, true, XO("Output level"));
817  UpdateControl(ID_DCBlock, false, {});
818  break;
819  case kLeveller:
825 
828  UpdateControl(ID_Param1, true, XO("Levelling fine adjustment"));
830  UpdateControl(ID_Repeats, true, XO("Degree of Levelling"));
831  UpdateControl(ID_DCBlock, false, {});
832  break;
833  case kRectifier:
839 
842  UpdateControl(ID_Param1, true, XO("Distortion amount"));
845  UpdateControl(ID_DCBlock, true, {});
846  break;
847  case kHardLimiter:
853 
854  UpdateControl(ID_Threshold, true, XO("dB Limit"));
856  UpdateControl(ID_Param1, true, XO("Wet level"));
857  UpdateControl(ID_Param2, true, XO("Residual level"));
859  UpdateControl(ID_DCBlock, false, {});
860  break;
861  default:
867  UpdateControl(ID_DCBlock, false, {});
868  }
869 }
870 
872  control id, bool enabled, TranslatableString name)
873 {
874  auto suffix = XO("(Not Used):");
875  switch (id)
876  {
877  case ID_Threshold: {
878  /* i18n-hint: Control range. */
879  if (enabled) suffix = XO("(-100 to 0 dB):");
880  name.Join( suffix, wxT(" ") );
881 
882  // Logarithmic slider is set indirectly
884  mThresholdS->SetValue((int) (mThreshold * SCL_Threshold_dB + 0.5));
885 
886  auto translated = name.Translation();
887  mThresholdTxt->SetLabel(translated);
888  mThresholdS->SetName(translated);
889  mThresholdT->SetName(translated);
890  mThresholdS->Enable(enabled);
891  mThresholdT->Enable(enabled);
892  break;
893  }
894  case ID_NoiseFloor: {
895  /* i18n-hint: Control range. */
896  if (enabled) suffix = XO("(-80 to -20 dB):");
897  name.Join( suffix, wxT(" ") );
898 
899  auto translated = name.Translation();
900  mNoiseFloorTxt->SetLabel(translated);
901  mNoiseFloorS->SetName(translated);
902  mNoiseFloorT->SetName(translated);
903  mNoiseFloorS->Enable(enabled);
904  mNoiseFloorT->Enable(enabled);
905  break;
906  }
907  case ID_Param1: {
908  /* i18n-hint: Control range. */
909  if (enabled) suffix = XO("(0 to 100):");
910  name.Join( suffix, wxT(" ") );
911 
912  auto translated = name.Translation();
913  mParam1Txt->SetLabel(translated);
914  mParam1S->SetName(translated);
915  mParam1T->SetName(translated);
916  mParam1S->Enable(enabled);
917  mParam1T->Enable(enabled);
918  break;
919  }
920  case ID_Param2: {
921  /* i18n-hint: Control range. */
922  if (enabled) suffix = XO("(0 to 100):");
923  name.Join( suffix, wxT(" ") );
924 
925  auto translated = name.Translation();
926  mParam2Txt->SetLabel(translated);
927  mParam2S->SetName(translated);
928  mParam2T->SetName(translated);
929  mParam2S->Enable(enabled);
930  mParam2T->Enable(enabled);
931  break;
932  }
933  case ID_Repeats: {
934  /* i18n-hint: Control range. */
935  if (enabled) suffix = XO("(0 to 5):");
936  name.Join( suffix, wxT(" ") );
937 
938  auto translated = name.Translation();
939  mRepeatsTxt->SetLabel(translated);
940  mRepeatsS->SetName(translated);
941  mRepeatsT->SetName(translated);
942  mRepeatsS->Enable(enabled);
943  mRepeatsT->Enable(enabled);
944  break;
945  }
946  case ID_DCBlock: {
947  if (enabled) {
950  }
951  else {
952  mDCBlockCheckBox->SetValue(false);
953  mParams.mDCBlock = false;
954  }
955 
956  mDCBlockCheckBox->Enable(enabled);
957  break;
958  }
959  default:
960  break;
961  }
962 }
963 
964 void EffectDistortion::UpdateControlText(wxTextCtrl* textCtrl, wxString& string, bool enabled)
965 {
966  if (enabled) {
967  if (textCtrl->GetValue().empty())
968  textCtrl->SetValue(string);
969  else
970  string = textCtrl->GetValue();
971  }
972  else {
973  if (!textCtrl->GetValue().empty())
974  string = textCtrl->GetValue();
975  textCtrl->SetValue(wxT(""));
976  }
977 }
978 
980 {
981  switch (mParams.mTableChoiceIndx)
982  {
983  case kHardClip:
984  HardClip();
985  break;
986  case kSoftClip:
987  SoftClip();
988  break;
989  case kHalfSinCurve:
990  HalfSinTable();
991  break;
992  case kExpCurve:
994  break;
995  case kLogCurve:
997  break;
998  case kCubic:
999  CubicTable();
1000  break;
1001  case kEvenHarmonics:
1003  break;
1004  case kSinCurve:
1005  SineTable();
1006  break;
1007  case kLeveller:
1008  Leveller();
1009  break;
1010  case kRectifier:
1011  Rectifier();
1012  break;
1013  case kHardLimiter:
1014  HardLimiter();
1015  break;
1016  }
1017 }
1018 
1019 
1020 //
1021 // Preset tables for gain lookup
1022 //
1023 
1025 {
1026  double lowThresh = 1 - mThreshold;
1027  double highThresh = 1 + mThreshold;
1028 
1029  for (int n = 0; n < TABLESIZE; n++) {
1030  if (n < (STEPS * lowThresh))
1031  mTable[n] = - mThreshold;
1032  else if (n > (STEPS * highThresh))
1033  mTable[n] = mThreshold;
1034  else
1035  mTable[n] = n/(double)STEPS - 1;
1036 
1037  mMakeupGain = 1.0 / mThreshold;
1038  }
1039 }
1040 
1042 {
1043  double threshold = 1 + mThreshold;
1044  double amount = std::pow(2.0, 7.0 * mParams.mParam1 / 100.0); // range 1 to 128
1045  double peak = LogCurve(mThreshold, 1.0, amount);
1046  mMakeupGain = 1.0 / peak;
1047  mTable[STEPS] = 0.0; // origin
1048 
1049  // positive half of table
1050  for (int n = STEPS; n < TABLESIZE; n++) {
1051  if (n < (STEPS * threshold)) // origin to threshold
1052  mTable[n] = n/(float)STEPS - 1;
1053  else
1054  mTable[n] = LogCurve(mThreshold, n/(double)STEPS - 1, amount);
1055  }
1056  CopyHalfTable();
1057 }
1058 
1059 float EffectDistortion::LogCurve(double threshold, float value, double ratio)
1060 {
1061  return threshold + ((std::exp(ratio * (threshold - value)) - 1) / -ratio);
1062 }
1063 
1065 {
1066  double amount = std::min(0.999, DB_TO_LINEAR(-1 * mParams.mParam1)); // avoid divide by zero
1067 
1068  for (int n = STEPS; n < TABLESIZE; n++) {
1069  double linVal = n/(float)STEPS;
1070  double scale = -1.0 / (1.0 - amount); // unity gain at 0dB
1071  double curve = std::exp((linVal - 1) * std::log(amount));
1072  mTable[n] = scale * (curve -1);
1073  }
1074  CopyHalfTable();
1075 }
1076 
1078 {
1079  double amount = mParams.mParam1;
1080  double stepsize = 1.0 / STEPS;
1081  double linVal = 0;
1082 
1083  if (amount == 0){
1084  for (int n = STEPS; n < TABLESIZE; n++) {
1085  mTable[n] = linVal;
1086  linVal += stepsize;
1087  }
1088  }
1089  else {
1090  for (int n = STEPS; n < TABLESIZE; n++) {
1091  mTable[n] = std::log(1 + (amount * linVal)) / std::log(1 + amount);
1092  linVal += stepsize;
1093  }
1094  }
1095  CopyHalfTable();
1096 }
1097 
1099 {
1100  int iter = std::floor(mParams.mParam1 / 20.0);
1101  double fractionalpart = (mParams.mParam1 / 20.0) - iter;
1102  double stepsize = 1.0 / STEPS;
1103  double linVal = 0;
1104 
1105  for (int n = STEPS; n < TABLESIZE; n++) {
1106  mTable[n] = linVal;
1107  for (int i = 0; i < iter; i++) {
1108  mTable[n] = std::sin(mTable[n] * M_PI_2);
1109  }
1110  mTable[n] += ((std::sin(mTable[n] * M_PI_2) - mTable[n]) * fractionalpart);
1111  linVal += stepsize;
1112  }
1113  CopyHalfTable();
1114 }
1115 
1117 {
1118  double amount = mParams.mParam1 * std::sqrt(3.0) / 100.0;
1119  double gain = 1.0;
1120  if (amount != 0.0)
1121  gain = 1.0 / Cubic(std::min(amount, 1.0));
1122 
1123  double stepsize = amount / STEPS;
1124  double x = -amount;
1125 
1126  if (amount == 0) {
1127  for (int i = 0; i < TABLESIZE; i++) {
1128  mTable[i] = (i / (double)STEPS) - 1.0;
1129  }
1130  }
1131  else {
1132  for (int i = 0; i < TABLESIZE; i++) {
1133  mTable[i] = gain * Cubic(x);
1134  for (int j = 0; j < mParams.mRepeats; j++) {
1135  mTable[i] = gain * Cubic(mTable[i] * amount);
1136  }
1137  x += stepsize;
1138  }
1139  }
1140 }
1141 
1142 double EffectDistortion::Cubic(double x)
1143 {
1144  if (mParams.mParam1 == 0.0)
1145  return x;
1146 
1147  return x - (std::pow(x, 3.0) / 3.0);
1148 }
1149 
1150 
1152 {
1153  double amount = mParams.mParam1 / -100.0;
1154  // double C = std::sin(std::max(0.001, mParams.mParam2) / 100.0) * 10.0;
1155  double C = std::max(0.001, mParams.mParam2) / 10.0;
1156 
1157  double step = 1.0 / STEPS;
1158  double xval = -1.0;
1159 
1160  for (int i = 0; i < TABLESIZE; i++) {
1161  mTable[i] = ((1 + amount) * xval) -
1162  (xval * (amount / std::tanh(C)) * std::tanh(C * xval));
1163  xval += step;
1164  }
1165 }
1166 
1168 {
1169  int iter = std::floor(mParams.mParam1 / 20.0);
1170  double fractionalpart = (mParams.mParam1 / 20.0) - iter;
1171  double stepsize = 1.0 / STEPS;
1172  double linVal = 0.0;
1173 
1174  for (int n = STEPS; n < TABLESIZE; n++) {
1175  mTable[n] = linVal;
1176  for (int i = 0; i < iter; i++) {
1177  mTable[n] = (1.0 + std::sin((mTable[n] * M_PI) - M_PI_2)) / 2.0;
1178  }
1179  mTable[n] += (((1.0 + std::sin((mTable[n] * M_PI) - M_PI_2)) / 2.0) - mTable[n]) * fractionalpart;
1180  linVal += stepsize;
1181  }
1182  CopyHalfTable();
1183 }
1184 
1186 {
1187  double noiseFloor = DB_TO_LINEAR(mParams.mNoiseFloor);
1188  int numPasses = mParams.mRepeats;
1189  double fractionalPass = mParams.mParam1 / 100.0;
1190 
1191  const int numPoints = 6;
1192  const double gainFactors[numPoints] = { 0.80, 1.00, 1.20, 1.20, 1.00, 0.80 };
1193  double gainLimits[numPoints] = { 0.0001, 0.0, 0.1, 0.3, 0.5, 1.0 };
1194  double addOnValues[numPoints];
1195 
1196  gainLimits[1] = noiseFloor;
1197  /* In the original Leveller effect, behaviour was undefined for threshold > 20 dB.
1198  * If we want to support > 20 dB we need to scale the points to keep them non-decreasing.
1199  *
1200  * if (noiseFloor > gainLimits[2]) {
1201  * for (int i = 3; i < numPoints; i++) {
1202  * gainLimits[i] = noiseFloor + ((1 - noiseFloor)*((gainLimits[i] - 0.1) / 0.9));
1203  * }
1204  * gainLimits[2] = noiseFloor;
1205  * }
1206  */
1207 
1208  // Calculate add-on values
1209  addOnValues[0] = 0.0;
1210  for (int i = 0; i < numPoints-1; i++) {
1211  addOnValues[i+1] = addOnValues[i] + (gainLimits[i] * (gainFactors[i] - gainFactors[1 + i]));
1212  }
1213 
1214  // Positive half of table.
1215  // The original effect increased the 'strength' of the effect by
1216  // repeated passes over the audio data.
1217  // Here we model that more efficiently by repeated passes over a linear table.
1218  for (int n = STEPS; n < TABLESIZE; n++) {
1219  mTable[n] = ((double) (n - STEPS) / (double) STEPS);
1220  for (int j = 0; j < numPasses; j++) {
1221  // Find the highest index for gain adjustment
1222  int index = numPoints - 1;
1223  for (int i = index; i >= 0 && mTable[n] < gainLimits[i]; i--) {
1224  index = i;
1225  }
1226  // the whole number of 'repeats'
1227  mTable[n] = (mTable[n] * gainFactors[index]) + addOnValues[index];
1228  }
1229  // Extrapolate for fine adjustment.
1230  // tiny fractions are not worth the processing time
1231  if (fractionalPass > 0.001) {
1232  int index = numPoints - 1;
1233  for (int i = index; i >= 0 && mTable[n] < gainLimits[i]; i--) {
1234  index = i;
1235  }
1236  mTable[n] += fractionalPass * ((mTable[n] * (gainFactors[index] - 1)) + addOnValues[index]);
1237  }
1238  }
1239  CopyHalfTable();
1240 }
1241 
1243 {
1244  double amount = (mParams.mParam1 / 50.0) - 1;
1245  double stepsize = 1.0 / STEPS;
1246  int index = STEPS;
1247 
1248  // positive half of waveform is passed unaltered.
1249  for (int n = 0; n <= STEPS; n++) {
1250  mTable[index] = n * stepsize;
1251  index += 1;
1252  }
1253 
1254  // negative half of table
1255  index = STEPS - 1;
1256  for (int n = 1; n <= STEPS; n++) {
1257  mTable[index] = n * stepsize * amount;
1258  index--;
1259  }
1260 }
1261 
1263 {
1264  // The LADSPA "hardLimiter 1413" is basically hard clipping,
1265  // but with a 'kind of' wet/dry mix:
1266  // out = ((wet-residual)*clipped) + (residual*in)
1267  HardClip();
1268 }
1269 
1270 
1271 // Helper functions for lookup tables
1272 
1274 {
1275  // Copy negative half of table from positive half
1276  int count = TABLESIZE - 1;
1277  for (int n = 0; n < STEPS; n++) {
1278  mTable[n] = -mTable[count];
1279  count--;
1280  }
1281 }
1282 
1283 
1284 float EffectDistortion::WaveShaper(float sample)
1285 {
1286  float out;
1287  int index;
1288  double xOffset;
1289  double amount = 1;
1290 
1291  switch (mParams.mTableChoiceIndx)
1292  {
1293  // Do any pre-processing here
1294  case kHardClip:
1295  // Pre-gain
1296  amount = mParams.mParam1 / 100.0;
1297  sample *= 1+amount;
1298  break;
1299  default: break;
1300  }
1301 
1302  index = std::floor(sample * STEPS) + STEPS;
1303  index = wxMax<int>(wxMin<int>(index, 2 * STEPS - 1), 0);
1304  xOffset = ((1 + sample) * STEPS) - index;
1305  xOffset = wxMin<double>(wxMax<double>(xOffset, 0.0), 1.0); // Clip at 0dB
1306 
1307  // linear interpolation: y = y0 + (y1-y0)*(x-x0)
1308  out = mTable[index] + (mTable[index + 1] - mTable[index]) * xOffset;
1309 
1310  return out;
1311 }
1312 
1313 
1315 {
1316  // Rolling average gives less offset at the start than an IIR filter.
1317  const unsigned int queueLength = std::floor(data.samplerate / 20.0);
1318 
1319  data.queuetotal += sample;
1320  data.queuesamples.push(sample);
1321 
1322  if (data.queuesamples.size() > queueLength) {
1323  data.queuetotal -= data.queuesamples.front();
1324  data.queuesamples.pop();
1325  }
1326 
1327  return sample - (data.queuetotal / data.queuesamples.size());
1328 }
EffectDistortion::ProcessBlock
size_t ProcessBlock(float **inBlock, float **outBlock, size_t blockLen) override
Called for destructive, non-realtime effect computation.
Definition: Distortion.cpp:236
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
EffectDistortion::SetAutomationParameters
bool SetAutomationParameters(CommandParameters &parms) override
Change settings to those stored in parms.
Definition: Distortion.cpp:302
CommandParameters
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
Definition: EffectAutomationParameters.h:67
EffectDistortion::mThresholdS
wxSlider * mThresholdS
Definition: Distortion.h:191
EffectDistortion::Params::mParam1
double mParam1
Definition: Distortion.h:59
EffectDistortion::mParam2S
wxSlider * mParam2S
Definition: Distortion.h:194
Effect::mUIDialog
wxWeakRef< wxDialog > mUIDialog
This weak pointer may be the same as the above, or null.
Definition: Effect.h:437
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:56
EffectDistortion::mMaster
EffectDistortionState mMaster
Definition: Distortion.h:171
DB_TO_LINEAR
const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB)
EffectDistortion::mParam1Txt
wxStaticText * mParam1Txt
Definition: Distortion.h:201
S
#define S(N)
Definition: ToChars.cpp:64
EffectDistortion::Params::mDCBlock
bool mDCBlock
Definition: Distortion.h:56
EffectDistortion::OnParam1Text
void OnParam1Text(wxCommandEvent &evt)
Definition: Distortion.cpp:665
EffectDistortion::CubicTable
void CubicTable()
Definition: Distortion.cpp:1116
kRectifier
@ kRectifier
Definition: Distortion.cpp:59
EffectDistortion::mDCBlockCheckBox
wxCheckBox * mDCBlockCheckBox
Definition: Distortion.h:197
kCubic
@ kCubic
Definition: Distortion.cpp:55
EffectDistortion::LogCurve
float LogCurve(double threshold, float value, double ratio)
Definition: Distortion.cpp:1059
EffectDistortion::UpdateUI
void UpdateUI()
Definition: Distortion.cpp:702
Distortion.h
EffectDistortion::Rectifier
void Rectifier()
Definition: Distortion.cpp:1242
EffectDistortionState::samplerate
float samplerate
Definition: Distortion.h:30
EffectDistortion::Params::mNoiseFloor
double mNoiseFloor
Definition: Distortion.h:58
EffectDistortionState::param2
double param2
Definition: Distortion.h:37
RegistryPaths
std::vector< RegistryPath > RegistryPaths
Definition: Identifier.h:219
EffectDistortion::mThresholdTxt
wxStaticText * mThresholdTxt
Definition: Distortion.h:199
EffectDistortion::GetFactoryPresets
RegistryPaths GetFactoryPresets() override
Report names of factory presets.
Definition: Distortion.cpp:323
EffectDistortionState::queuetotal
double queuetotal
Definition: Distortion.h:42
EffectDistortion::mRepeatsTxt
wxStaticText * mRepeatsTxt
Definition: Distortion.h:203
EffectDistortion::mTable
double mTable[TABLESIZE]
Definition: Distortion.h:174
EffectDistortion::OnRepeatsText
void OnRepeatsText(wxCommandEvent &evt)
Definition: Distortion.cpp:689
Validator
A Validator is an object which checks whether a wxVariant satisfies a certain criterion....
Definition: Validators.h:53
ID_Threshold
@ ID_Threshold
Definition: Compressor.cpp:53
EffectDistortion::ID_Repeats
@ ID_Repeats
Definition: Distortion.h:110
EffectDistortion::RealtimeInitialize
bool RealtimeInitialize() override
Definition: Distortion.cpp:241
XO
#define XO(s)
Definition: Internat.h:31
EffectDistortion::ManualPage
ManualPageID ManualPage() override
Name of a page in the Audacity alpha manual, default is empty.
Definition: Distortion.cpp:201
EffectDistortion::CopyHalfTable
void CopyHalfTable()
Definition: Distortion.cpp:1273
EffectDistortion::HalfSinTable
void HalfSinTable()
Definition: Distortion.cpp:1098
EffectDistortion::mbSavedFilterState
bool mbSavedFilterState
Definition: Distortion.h:176
ShuttleParams
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:61
EffectDistortion::InstanceInit
void InstanceInit(EffectDistortionState &data, float sampleRate)
Definition: Distortion.cpp:524
kSinCurve
@ kSinCurve
Definition: Distortion.cpp:57
kHalfSinCurve
@ kHalfSinCurve
Definition: Distortion.cpp:52
kHardClip
@ kHardClip
Definition: Distortion.cpp:50
EffectDistortion::mNoiseFloorS
wxSlider * mNoiseFloorS
Definition: Distortion.h:192
STEPS
#define STEPS
Definition: Distortion.h:24
EffectDistortion::ID_Type
@ ID_Type
Definition: Distortion.h:104
nTableTypes
@ nTableTypes
Definition: Distortion.cpp:61
Param
Param(TableTypeIndx, int, wxT("Type"), 0, 0, nTableTypes-1, 1)
EffectDistortion::mThresholdT
wxTextCtrl * mThresholdT
Definition: Distortion.h:185
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
EffectDistortion::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: Distortion.cpp:356
kLeveller
@ kLeveller
Definition: Distortion.cpp:58
EffectDistortionState::param1
double param1
Definition: Distortion.h:36
EffectDistortion::RealtimeAddProcessor
bool RealtimeAddProcessor(unsigned numChannels, float sampleRate) override
Definition: Distortion.cpp:250
EffectDistortion::mSlaves
std::vector< EffectDistortionState > mSlaves
Definition: Distortion.h:172
kEvenHarmonics
@ kEvenHarmonics
Definition: Distortion.cpp:56
EffectDistortion::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: Distortion.cpp:191
EffectDistortion::control
control
Definition: Distortion.h:103
EffectDistortion::mOldRepeatsTxt
wxString mOldRepeatsTxt
Definition: Distortion.h:209
EffectDistortion::OnRepeatsSlider
void OnRepeatsSlider(wxCommandEvent &evt)
Definition: Distortion.cpp:695
EffectDistortion::mRepeatsS
wxSlider * mRepeatsS
Definition: Distortion.h:195
EffectDistortion::mThreshold
double mThreshold
Definition: Distortion.h:175
EffectDistortion::LoadFactoryPreset
bool LoadFactoryPreset(int id) override
Change settings to the preset whose name is GetFactoryPresets()[id]
Definition: Distortion.cpp:335
ID_NoiseFloor
@ ID_NoiseFloor
Definition: Compressor.cpp:54
EffectDistortionState
Definition: Distortion.h:28
ReadAndVerifyEnum
#define ReadAndVerifyEnum(name, list, listSize)
Definition: Effect.h:580
ReadAndVerifyInt
#define ReadAndVerifyInt(name)
Definition: Effect.h:591
EffectDistortion::ID_NoiseFloor
@ ID_NoiseFloor
Definition: Distortion.h:107
EffectDistortion::GetDescription
TranslatableString GetDescription() override
Definition: Distortion.cpp:196
XXO
#define XXO(s)
Definition: Internat.h:44
EffectDistortion::Cubic
double Cubic(double x)
Definition: Distortion.cpp:1142
EffectDistortion::mParams
Params mParams
Definition: Distortion.h:211
EffectDistortion::~EffectDistortion
virtual ~EffectDistortion()
Definition: Distortion.cpp:185
EffectDistortion::Params::mTableChoiceIndx
int mTableChoiceIndx
Definition: Distortion.h:55
EffectDistortion::SineTable
void SineTable()
Definition: Distortion.cpp:1167
EffectDistortion::Params
Definition: Distortion.h:54
EffectDistortion::ExponentialTable
void ExponentialTable()
Definition: Distortion.cpp:1064
EffectDistortion::mOldThresholdTxt
wxString mOldThresholdTxt
Definition: Distortion.h:205
EffectDistortion::TransferDataToWindow
bool TransferDataToWindow() override
Definition: Distortion.cpp:491
EffectDistortion::GetType
EffectType GetType() override
Type determines how it behaves.
Definition: Distortion.cpp:208
name
const TranslatableString name
Definition: Distortion.cpp:98
EffectDistortion::MakeTable
void MakeTable()
Definition: Distortion.cpp:979
EffectDistortion::OnParam2Text
void OnParam2Text(wxCommandEvent &evt)
Definition: Distortion.cpp:677
EffectDistortion::ID_Threshold
@ ID_Threshold
Definition: Distortion.h:106
EffectDistortion::mMakeupGain
double mMakeupGain
Definition: Distortion.h:180
EffectDistortion::Params::mThreshold_dB
double mThreshold_dB
Definition: Distortion.h:57
EffectDistortion::LogarithmicTable
void LogarithmicTable()
Definition: Distortion.cpp:1077
EffectDistortion::mOldParam2Txt
wxString mOldParam2Txt
Definition: Distortion.h:208
ID_Type
@ ID_Type
Definition: ScienFilter.cpp:81
EffectDistortion::OnNoiseFloorText
void OnNoiseFloorText(wxCommandEvent &evt)
Definition: Distortion.cpp:652
EffectDistortion::HardClip
void HardClip()
Definition: Distortion.cpp:1024
EffectDistortion::OnDCBlockCheckbox
void OnDCBlockCheckbox(wxCommandEvent &evt)
Definition: Distortion.cpp:630
kSoftClip
@ kSoftClip
Definition: Distortion.cpp:51
defaultLabel
TranslatableString defaultLabel(int index)
Definition: Distortion.cpp:130
EffectDistortion::RealtimeFinalize
bool RealtimeFinalize() override
Definition: Distortion.cpp:261
EffectDistortion::OnParam2Slider
void OnParam2Slider(wxCommandEvent &evt)
Definition: Distortion.cpp:683
ChannelNames
enum ChannelName * ChannelNames
kExpCurve
@ kExpCurve
Definition: Distortion.cpp:53
Msgids
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
Definition: ShuttleGui.cpp:2523
names
static TranslatableStrings names
Definition: TagsEditor.cpp:151
EffectDistortion::mNoiseFloorT
wxTextCtrl * mNoiseFloorT
Definition: Distortion.h:186
ReadAndVerifyDouble
#define ReadAndVerifyDouble(name)
Definition: Effect.h:592
EffectDistortionState::noisefloor
double noisefloor
Definition: Distortion.h:35
EffectDistortion::UpdateControl
void UpdateControl(control id, bool enable, TranslatableString name)
Definition: Distortion.cpp:871
EffectDistortion::InstanceProcess
size_t InstanceProcess(EffectDistortionState &data, float **inBlock, float **outBlock, size_t blockLen)
Definition: Distortion.cpp:548
EffectDistortion::OnParam1Slider
void OnParam1Slider(wxCommandEvent &evt)
Definition: Distortion.cpp:671
EffectDistortionState::tablechoiceindx
int tablechoiceindx
Definition: Distortion.h:32
LoadEffects.h
EffectDistortion::DCFilter
float DCFilter(EffectDistortionState &data, float sample)
Definition: Distortion.cpp:1314
EffectDistortionState::skipcount
sampleCount skipcount
Definition: Distortion.h:31
EffectDistortion::OnThresholdText
void OnThresholdText(wxCommandEvent &evt)
Definition: Distortion.cpp:637
TABLESIZE
#define TABLESIZE
Definition: Distortion.h:25
id
int id
Definition: WaveTrackControls.cpp:577
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
EffectDistortion::GetAudioInCount
unsigned GetAudioInCount() override
Definition: Distortion.cpp:220
EffectDistortion::mRepeatsT
wxTextCtrl * mRepeatsT
Definition: Distortion.h:189
EffectDistortion::mOldmNoiseFloorTxt
wxString mOldmNoiseFloorTxt
Definition: Distortion.h:206
Effect::mSampleRate
double mSampleRate
Definition: Effect.h:418
EffectDistortion::SoftClip
void SoftClip()
Definition: Distortion.cpp:1041
EffectDistortionState::queuesamples
std::queue< float > queuesamples
Definition: Distortion.h:41
kHardLimiter
@ kHardLimiter
Definition: Distortion.cpp:60
EffectDistortion::GetAudioOutCount
unsigned GetAudioOutCount() override
Definition: Distortion.cpp:225
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
Effect::mUIParent
wxWindow * mUIParent
Definition: Effect.h:438
TaggedIdentifier< ManualPageIDTag >
EffectDistortion::DefineParams
bool DefineParams(ShuttleParams &S) override
Definition: Distortion.cpp:276
EffectDistortion::ProcessInitialize
bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap=NULL) override
Called for destructive, non-realtime effect computation.
Definition: Distortion.cpp:230
M_PI_2
#define M_PI_2
Definition: Distortion.cpp:32
EffectDistortion::OnTypeChoice
void OnTypeChoice(wxCommandEvent &evt)
Definition: Distortion.cpp:623
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
EffectDistortion::UpdateControlText
void UpdateControlText(wxTextCtrl *textCtrl, wxString &string, bool enabled)
Definition: Distortion.cpp:964
EffectDistortion::mParam2Txt
wxStaticText * mParam2Txt
Definition: Distortion.h:202
EffectDistortion::GetAutomationParameters
bool GetAutomationParameters(CommandParameters &parms) override
Save current settings into parms.
Definition: Distortion.cpp:288
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterfaceSymbol.h:55
FactoryPresets
static const struct @0 FactoryPresets[]
EffectDistortionState::dcblock
bool dcblock
Definition: Distortion.h:33
EffectDistortion::ID_DCBlock
@ ID_DCBlock
Definition: Distortion.h:105
LINEAR_TO_DB
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:503
kTableTypeStrings
static const EnumValueSymbol kTableTypeStrings[nTableTypes]
Definition: Distortion.cpp:64
EffectDistortion::Leveller
void Leveller()
Definition: Distortion.cpp:1185
M_PI
#define M_PI
Definition: Distortion.cpp:29
EffectDistortion::HardLimiter
void HardLimiter()
Definition: Distortion.cpp:1262
EffectDistortion::mTypeChoiceCtrl
wxChoice * mTypeChoiceCtrl
Definition: Distortion.h:184
EffectDistortion::ID_Param2
@ ID_Param2
Definition: Distortion.h:109
EffectDistortion::mOldParam1Txt
wxString mOldParam1Txt
Definition: Distortion.h:207
EffectDistortion::mNoiseFloorTxt
wxStaticText * mNoiseFloorTxt
Definition: Distortion.h:200
Prefs.h
params
EffectDistortion::Params params
Definition: Distortion.cpp:99
EffectDistortion
A WaveShaper distortion effect.
Definition: Distortion.h:46
TranslatableString::Translation
wxString Translation() const
Definition: TranslatableString.h:79
kTableType
kTableType
Definition: Distortion.cpp:49
TranslatableString::Join
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
Definition: TranslatableString.cpp:124
EffectDistortion::OnNoiseFloorSlider
void OnNoiseFloorSlider(wxCommandEvent &evt)
Definition: Distortion.cpp:658
EffectDistortionState::repeats
int repeats
Definition: Distortion.h:38
EffectType
EffectType
Definition: EffectInterface.h:52
kLogCurve
@ kLogCurve
Definition: Distortion.cpp:54
EffectDistortion::Params::mParam2
double mParam2
Definition: Distortion.h:60
EffectDistortion::mParam1S
wxSlider * mParam1S
Definition: Distortion.h:193
EffectDistortion::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: Distortion.h:48
EffectDistortion::mParam1T
wxTextCtrl * mParam1T
Definition: Distortion.h:187
skipsamples
#define skipsamples
Definition: Distortion.cpp:92
EffectDistortion::mParam2T
wxTextCtrl * mParam2T
Definition: Distortion.h:188
EffectDistortion::RealtimeProcess
size_t RealtimeProcess(int group, float **inbuf, float **outbuf, size_t numSamples) override
Definition: Distortion.cpp:268
Effect::SetBlockSize
size_t SetBlockSize(size_t maxBlockSize) override
Definition: Effect.cpp:294
EffectDistortion::SupportsRealtime
bool SupportsRealtime() override
Whether the effect supports realtime previewing (while audio is playing).
Definition: Distortion.cpp:213
END_EVENT_TABLE
END_EVENT_TABLE()
EffectDistortion::OnThresholdSlider
void OnThresholdSlider(wxCommandEvent &evt)
Definition: Distortion.cpp:644
EffectDistortion::Params::mRepeats
int mRepeats
Definition: Distortion.h:61
EffectDistortion::WaveShaper
float WaveShaper(float sample)
Definition: Distortion.cpp:1284
EffectDistortionState::threshold
double threshold
Definition: Distortion.h:34
ReadAndVerifyBool
#define ReadAndVerifyBool(name)
Definition: Effect.h:594
anonymous_namespace{Distortion.cpp}::reg
BuiltinEffectsModule::Registration< EffectDistortion > reg
Definition: Distortion.cpp:150
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
EffectDistortion::ID_Param1
@ ID_Param1
Definition: Distortion.h:108
EffectDistortion::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: Distortion.cpp:512
EffectDistortion::EvenHarmonicTable
void EvenHarmonicTable()
Definition: Distortion.cpp:1151