Audacity  3.2.0
NoiseReduction.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  NoiseReduction.cpp
6 
7  Dominic Mazzoni
8 
9  detailed rewriting by
10  Paul Licameli
11 
12 *******************************************************************//****************************************************************/
40 #include "NoiseReduction.h"
41 
42 #include "LoadEffects.h"
43 #include "EffectManager.h"
44 #include "EffectUI.h"
45 
46 #include "../ShuttleGui.h"
47 #include "../widgets/HelpSystem.h"
48 #include "FFT.h"
49 #include "Prefs.h"
50 #include "RealFFTf.h"
51 #include "../SpectrumTransformer.h"
52 
53 #include "../WaveTrack.h"
54 #include "../widgets/AudacityMessageBox.h"
55 #include "../widgets/valnum.h"
56 
57 #include <algorithm>
58 #include <vector>
59 #include <math.h>
60 
61 #if defined(__WXMSW__) && !defined(__CYGWIN__)
62 #include <float.h>
63 #define finite(x) _finite(x)
64 #endif
65 
66 #include <wx/button.h>
67 #include <wx/choice.h>
68 #include <wx/dialog.h>
69 #include <wx/radiobut.h>
70 #include <wx/slider.h>
71 #include <wx/valtext.h>
72 #include <wx/textctrl.h>
73 #include <wx/sizer.h>
74 
75 // SPECTRAL_SELECTION not to affect this effect for now, as there might be no indication that it does.
76 // [Discussed and agreed for v2.1 by Steve, Paul, Bill].
77 #undef EXPERIMENTAL_SPECTRAL_EDITING
78 
79 typedef std::vector<float> FloatVector;
80 
81 // Define both of these to make the radio button three-way
82 #define RESIDUE_CHOICE
83 //#define ISOLATE_CHOICE
84 
85 // Define for Attack and release controls.
86 // #define ATTACK_AND_RELEASE
87 
88 // Define to expose other advanced, experimental dialog controls
89 //#define ADVANCED_SETTINGS
90 
91 // Define to make the old statistical methods an available choice
92 //#define OLD_METHOD_AVAILABLE
93 
94 namespace {
95 
96 enum DiscriminationMethod : size_t {
100 
103 };
104 
108  // Experimental only, don't need translations
109  { XO("Median") },
110  { XO("Second greatest") },
111  { XO("Old") },
112 };
113 
114 // magic number used only in the old statistics
115 // and the old discrimination
116 const float minSignalTime = 0.05f;
117 
118 enum WindowTypes : unsigned {
119  WT_RECTANGULAR_HANN = 0, // 2.0.6 behavior, requires 1/2 step
120  WT_HANN_RECTANGULAR, // requires 1/2 step
121  WT_HANN_HANN, // requires 1/4 step
122  WT_BLACKMAN_HANN, // requires 1/4 step
123  WT_HAMMING_RECTANGULAR, // requires 1/2 step
124  WT_HAMMING_HANN, // requires 1/4 step
125  // WT_HAMMING_INV_HAMMING, // requires 1/2 step
126 
129 };
130 
131 const struct WindowTypesInfo {
133  unsigned minSteps;
135 
136  // Experimental only, don't need translations
137  { Verbatim("none, Hann (2.0.6 behavior)"), 2 },
138  /* i18n-hint: Hann is a proper name */
139  { Verbatim("Hann, none"), 2 },
140  /* i18n-hint: Hann is a proper name */
141  { Verbatim("Hann, Hann (default)"), 4 },
142  /* i18n-hint: Hann and Blackman are proper names */
143  { Verbatim("Blackman, Hann"), 4 },
144  /* i18n-hint: Hamming is a proper name */
145  { Verbatim("Hamming, none"), 2 },
146  /* i18n-hint: Hamming and Hann area proper names */
147  { Verbatim("Hamming, Hann"), 4 },
148  /* i18n-hint: Hamming is a proper name */
149  // { XO("Hamming, Reciprocal Hamming"), 2, }, // output window is special
150 };
151 
152 enum {
153  DEFAULT_WINDOW_SIZE_CHOICE = 8, // corresponds to 2048
154  DEFAULT_STEPS_PER_WINDOW_CHOICE = 1 // corresponds to 4, minimum for WT_HANN_HANN
155 };
156 
161 };
162 
163 } // namespace
164 
165 //----------------------------------------------------------------------------
166 // EffectNoiseReduction::Statistics
167 //----------------------------------------------------------------------------
168 
170 {
171 public:
172  Statistics(size_t spectrumSize, double rate, int windowTypes)
173  : mRate{ rate }
174  , mWindowSize{ (spectrumSize - 1) * 2 }
175  , mWindowTypes{ windowTypes }
176  , mTotalWindows{ 0 }
177  , mTrackWindows{ 0 }
178  , mSums( spectrumSize )
179  , mMeans (spectrumSize )
180 #ifdef OLD_METHOD_AVAILABLE
181  , mNoiseThreshold( spectrumSize )
182 #endif
183  {}
184 
185  // Noise profile statistics follow
186 
187  double mRate; // Rate of profile track(s) -- processed tracks must match
188  size_t mWindowSize;
190 
191  unsigned mTotalWindows;
192  unsigned mTrackWindows;
195 
196 #ifdef OLD_METHOD_AVAILABLE
197  // Old statistics:
198  FloatVector mNoiseThreshold;
199 #endif
200 };
201 
202 //----------------------------------------------------------------------------
203 // EffectNoiseReduction::Settings
204 //----------------------------------------------------------------------------
205 
206 // This object is the memory of the effect between uses
207 // (other than noise profile statistics)
209 {
210 public:
211  Settings();
213 
214  int PromptUser(EffectNoiseReduction *effect,
215  wxWindow &parent, bool bHasProfile, bool bAllowTwiddleSettings);
216  bool PrefsIO(bool read);
217  bool Validate(EffectNoiseReduction *effect) const;
218 
219  size_t WindowSize() const { return 1u << (3 + mWindowSizeChoice); }
220  unsigned StepsPerWindow() const { return 1u << (1 + mStepsPerWindowChoice); }
221 
223 
224  // Stored in preferences:
225 
226  // Basic:
227  double mNewSensitivity; // - log10 of a probability... yeah.
228  double mFreqSmoothingBands; // really an integer
229  double mNoiseGain; // in dB, positive
230  double mAttackTime; // in secs
231  double mReleaseTime; // in secs
232 
233  // Advanced:
234  double mOldSensitivity; // in dB, plus or minus
235 
236  // Basic:
238 
239  // Advanced:
243  int mMethod;
244 };
245 
247  : mDoProfile{ true }
248 {
249  PrefsIO(true);
250 }
251 
252 //----------------------------------------------------------------------------
253 // EffectNoiseReduction::Worker
254 //----------------------------------------------------------------------------
255 
256 // This object holds information needed only during effect calculation
258  : public TrackSpectrumTransformer
259 {
260 public:
263 
264  Worker(eWindowFunctions inWindowType, eWindowFunctions outWindowType,
265  EffectNoiseReduction &effect, const Settings &settings,
266  Statistics &statistics
267 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
268  , double f0, double f1
269 #endif
270  );
271  ~Worker();
272 
273  struct MyWindow : public Window
274  {
275  explicit MyWindow(size_t windowSize)
276  : Window{ windowSize }
277  , mSpectrums(windowSize / 2 + 1)
278  , mGains(windowSize / 2 + 1)
279  {}
280  ~MyWindow() override;
281 
284  };
285 
286  bool Process(TrackList &tracks, double mT0, double mT1);
287 
288 protected:
289  MyWindow &NthWindow(int nn) { return static_cast<MyWindow&>(Nth(nn)); }
290  std::unique_ptr<Window> NewWindow(size_t windowSize) override;
291  bool DoStart() override;
292  static bool Processor(SpectrumTransformer &transformer);
293  bool DoFinish() override;
294 
295 private:
296  void ApplyFreqSmoothing(FloatVector &gains);
297  void GatherStatistics();
298  inline bool Classify(unsigned nWindows, int band);
299  void ReduceNoise();
300  void FinishTrackStatistics();
301 
302 private:
303 
304  const bool mDoProfile;
305 
308 
310  const size_t mFreqSmoothingBins;
311  // When spectral selection limits the affected band:
312  size_t mBinLow; // inclusive lower bound
313  size_t mBinHigh; // exclusive upper bound
314 
316  const int mMethod;
317  const double mNewSensitivity;
318 
323 
325  unsigned mCenter;
326  unsigned mHistoryLen;
327 
328  // Following are for progress indicator only:
329  unsigned mProgressTrackCount = 0;
332 };
333 
334 /****************************************************************//*****************************************************************/
340 
341 //----------------------------------------------------------------------------
342 // EffectNoiseReduction::Dialog
343 //----------------------------------------------------------------------------
344 
346 {
347 public:
348  // constructors and destructors
349  Dialog
350  (EffectNoiseReduction *effect,
352  wxWindow *parent, bool bHasProfile,
353  bool bAllowTwiddleSettings);
354 
355  void PopulateOrExchange(ShuttleGui & S) override;
356  bool TransferDataToWindow() override;
357  bool TransferDataFromWindow() override;
358 
359  const Settings &GetTempSettings() const
360  { return mTempSettings; }
361 
362 private:
364 
365 #ifdef ADVANCED_SETTINGS
366  void EnableDisableSensitivityControls();
367 #endif
368 
369  // handlers
370  void OnGetProfile( wxCommandEvent &event );
371  void OnNoiseReductionChoice( wxCommandEvent &event );
372 #ifdef ADVANCED_SETTINGS
373  void OnMethodChoice(wxCommandEvent &);
374 #endif
375  void OnPreview(wxCommandEvent &event) override;
376  void OnReduceNoise( wxCommandEvent &event );
377  void OnCancel( wxCommandEvent &event );
378  void OnHelp( wxCommandEvent &event );
379 
380  void OnText(wxCommandEvent &event);
381  void OnSlider(wxCommandEvent &event);
382 
383  // data members
384 
388 
391 
392 
393  wxRadioButton *mKeepSignal;
394 #ifdef ISOLATE_CHOICE
395  wxRadioButton *mKeepNoise;
396 #endif
397 #ifdef RESIDUE_CHOICE
398  wxRadioButton *mResidue;
399 #endif
400 
401 private:
402  DECLARE_EVENT_TABLE()
403 };
404 
406 { XO("Noise Reduction") };
407 
409 
411 : mSettings(std::make_unique<EffectNoiseReduction::Settings>())
412 {
413  Init();
414 }
415 
417 {
418 }
419 
420 // ComponentInterface implementation
421 
423 {
424  return Symbol;
425 }
426 
428 {
429  return XO("Removes background noise such as fans, tape noise, or hums");
430 }
431 
432 // EffectDefinitionInterface implementation
433 
435 {
436  return EffectTypeProcess;
437 }
438 
440 {
441  return true;
442 }
443 
445 {
446  return false;
447 }
448 
450 
455  wxWindow &parent, const EffectDialogFactory &, bool forceModal)
456 {
457  // to do: use forceModal correctly
458 
459  // Doesn't use the factory but substitutes its own dialog
460 
461  // We may want to twiddle the levels if we are setting
462  // from an automation dialog
463  return mSettings->PromptUser(this, parent,
464  bool(mStatistics), forceModal);
465 }
466 
468 (EffectNoiseReduction *effect, wxWindow &parent,
469  bool bHasProfile, bool bAllowTwiddleSettings)
470 {
472  (effect, this, &parent, bHasProfile, bAllowTwiddleSettings);
473 
474  dlog.CentreOnParent();
475  dlog.ShowModal();
476 
477  const auto returnCode = dlog.GetReturnCode();
478  if (!returnCode)
479  return 0;
480 
481  *this = dlog.GetTempSettings();
482  mDoProfile = (returnCode == 1);
483 
484  if (!PrefsIO(false))
485  return 0;
486  return returnCode;
487 }
488 
489 namespace {
490  template <typename StructureType, typename FieldType>
492  typedef FieldType (StructureType::*MemberPointer);
493 
495  const wxChar *name;
496  FieldType defaultValue;
497  };
498 
499  template <typename StructureType, typename FieldType>
500  void readPrefs(
501  StructureType *structure, const wxString &prefix,
502  const PrefsTableEntry<StructureType, FieldType> *fields, size_t numFields)
503  {
504  for (size_t ii = 0; ii < numFields; ++ii) {
506  gPrefs->Read(prefix + entry.name, &(structure->*(entry.field)),
507  entry.defaultValue);
508  }
509  }
510 
511  template <typename StructureType, typename FieldType>
513  const StructureType *structure, const wxString &prefix,
514  const PrefsTableEntry<StructureType, FieldType> *fields, size_t numFields)
515  {
516  for (size_t ii = 0; ii < numFields; ++ii) {
518  gPrefs->Write(prefix + entry.name, structure->*(entry.field));
519  }
520  }
521 }
522 
524 {
525  static const double DEFAULT_OLD_SENSITIVITY = 0.0;
526 
527  static const PrefsTableEntry<Settings, double> doubleTable[] = {
528  { &Settings::mNewSensitivity, wxT("Sensitivity"), 6.0 },
529  { &Settings::mNoiseGain, wxT("Gain"), 12.0 },
530  { &Settings::mAttackTime, wxT("AttackTime"), 0.02 },
531  { &Settings::mReleaseTime, wxT("ReleaseTime"), 0.10 },
532  { &Settings::mFreqSmoothingBands, wxT("FreqSmoothing"), 3.0 },
533 
534  // Advanced settings
535  { &Settings::mOldSensitivity, wxT("OldSensitivity"), DEFAULT_OLD_SENSITIVITY },
536  };
537  static auto doubleTableSize = sizeof(doubleTable) / sizeof(doubleTable[0]);
538 
539  static const PrefsTableEntry<Settings, int> intTable[] = {
540  { &Settings::mNoiseReductionChoice, wxT("ReductionChoice"), NRC_REDUCE_NOISE },
541 
542  // Advanced settings
543  { &Settings::mWindowTypes, wxT("WindowTypes"), WT_DEFAULT_WINDOW_TYPES },
546  { &Settings::mMethod, wxT("Method"), DM_DEFAULT_METHOD },
547  };
548  static auto intTableSize = sizeof(intTable) / sizeof(intTable[0]);
549 
550  static const wxString prefix(wxT("/Effects/NoiseReduction/"));
551 
552  if (read) {
553  readPrefs(this, prefix, doubleTable, doubleTableSize);
554  readPrefs(this, prefix, intTable, intTableSize);
555 
556  // Ignore preferences for unavailable options.
557 #if !(defined(RESIDUE_CHOICE) || defined (ISOLATE_CHOICE))
558  mNoiseReductionChoice == NRC_REDUCE_NOISE;
559 #elif !(defined(RESIDUE_CHOICE))
560  if (mNoiseReductionChoice == NRC_LEAVE_RESIDUE)
561  mNoiseReductionChoice = NRC_ISOLATE_NOISE;
562 #elif !(defined(ISOLATE_CHOICE))
563  if (mNoiseReductionChoice == NRC_ISOLATE_NOISE)
564  mNoiseReductionChoice = NRC_LEAVE_RESIDUE;
565 #endif
566 
567 #ifndef ADVANCED_SETTINGS
568  // Initialize all hidden advanced settings to defaults.
569  mWindowTypes = WT_DEFAULT_WINDOW_TYPES;
570  mWindowSizeChoice = DEFAULT_WINDOW_SIZE_CHOICE;
571  mStepsPerWindowChoice = DEFAULT_STEPS_PER_WINDOW_CHOICE;
572  mMethod = DM_DEFAULT_METHOD;
573  mOldSensitivity = DEFAULT_OLD_SENSITIVITY;
574 #endif
575 
576 #ifndef OLD_METHOD_AVAILABLE
577  if (mMethod == DM_OLD_METHOD)
578  mMethod = DM_DEFAULT_METHOD;
579 #endif
580 
581  return true;
582  }
583  else {
584  writePrefs(this, prefix, doubleTable, doubleTableSize);
585  writePrefs(this, prefix, intTable, intTableSize);
586  return gPrefs->Flush();
587  }
588 }
589 
591 {
592  if (StepsPerWindow() < windowTypesInfo[mWindowTypes].minSteps) {
593  effect->Effect::MessageBox(
594  XO("Steps per block are too few for the window types.") );
595  return false;
596  }
597 
598  if (StepsPerWindow() > WindowSize()) {
599  effect->Effect::MessageBox(
600  XO("Steps per block cannot exceed the window size.") );
601  return false;
602  }
603 
604  if (mMethod == DM_MEDIAN && StepsPerWindow() > 4) {
605  effect->Effect::MessageBox(
606  XO(
607 "Median method is not implemented for more than four steps per window.") );
608  return false;
609  }
610 
611  return true;
612 }
613 
615  -> std::unique_ptr<Window>
616 {
617  return std::make_unique<MyWindow>(windowSize);
618 }
619 
621 {
622 }
623 
625 {
626  // This same code will either reduce noise or profile it
627 
628  this->CopyInputTracks(); // Set up mOutputTracks.
629 
630  auto track = * (mOutputTracks->Selected< const WaveTrack >()).begin();
631  if (!track)
632  return false;
633 
634  // Initialize statistics if gathering them, or check for mismatched (advanced)
635  // settings if reducing noise.
636  if (mSettings->mDoProfile) {
637  size_t spectrumSize = 1 + mSettings->WindowSize() / 2;
638  mStatistics = std::make_unique<Statistics>
639  (spectrumSize, track->GetRate(), mSettings->mWindowTypes);
640  }
641  else if (mStatistics->mWindowSize != mSettings->WindowSize()) {
642  // possible only with advanced settings
644  XO("You must specify the same window size for steps 1 and 2.") );
645  return false;
646  }
647  else if (mStatistics->mWindowTypes != mSettings->mWindowTypes) {
648  // A warning only
650  XO("Warning: window types are not the same as for profiling.") );
651  }
652 
653  eWindowFunctions inWindowType, outWindowType;
654  switch (mSettings->mWindowTypes) {
655  case WT_RECTANGULAR_HANN:
656  inWindowType = eWinFuncRectangular;
657  outWindowType = eWinFuncHann;
658  break;
659  case WT_HANN_RECTANGULAR:
660  inWindowType = eWinFuncHann;
661  outWindowType = eWinFuncRectangular;
662  break;
663  case WT_BLACKMAN_HANN:
664  inWindowType = eWinFuncBlackman;
665  outWindowType = eWinFuncHann;
666  break;
668  inWindowType = eWinFuncHamming;
669  outWindowType = eWinFuncRectangular;
670  break;
671  case WT_HAMMING_HANN:
672  inWindowType = eWinFuncHamming;
673  outWindowType = eWinFuncHann;
674  break;
675  default:
676  wxASSERT(false);
677  [[fallthrough]] ;
678  case WT_HANN_HANN:
679  inWindowType = outWindowType = eWinFuncHann;
680  break;
681  }
682  Worker worker{ inWindowType, outWindowType,
683  *this, *mSettings, *mStatistics
684 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
685  , mF0, mF1
686 #endif
687  };
688  bool bGoodResult = worker.Process(*mOutputTracks, mT0, mT1);
689  if (mSettings->mDoProfile) {
690  if (bGoodResult)
691  mSettings->mDoProfile = false; // So that "repeat last effect" will reduce noise
692  else
693  mStatistics.reset(); // So that profiling must be done again before noise reduction
694  }
695  this->ReplaceProcessedTracks(bGoodResult);
696  return bGoodResult;
697 }
698 
700 {
701 }
702 
704  TrackList &tracks, double inT0, double inT1)
705 {
706  mProgressTrackCount = 0;
707  for ( auto track : tracks.Selected< WaveTrack >() ) {
708  mProgressWindowCount = 0;
709  if (track->GetRate() != mStatistics.mRate) {
710  if (mDoProfile)
711  mEffect.Effect::MessageBox(
712  XO("All noise profile data must have the same sample rate.") );
713  else
714  mEffect.Effect::MessageBox(
715  XO(
716 "The sample rate of the noise profile must match that of the sound to be processed.") );
717  return false;
718  }
719 
720  double trackStart = track->GetStartTime();
721  double trackEnd = track->GetEndTime();
722  double t0 = std::max(trackStart, inT0);
723  double t1 = std::min(trackEnd, inT1);
724 
725  if (t1 > t0) {
726  auto start = track->TimeToLongSamples(t0);
727  auto end = track->TimeToLongSamples(t1);
728  const auto len = end - start;
729  mLen = len;
730  const auto extra = (mStepsPerWindow - 1) * mStepSize;
731  // Adjust denominator for presence or absence of padding,
732  // which makes the number of windows visited either more or less
733  // than the number of window steps in the data.
734  if (mDoProfile)
735  mLen -= extra;
736  else
737  mLen += extra;
738 
740  Processor, track, mHistoryLen, start, len ))
741  return false;
742  }
743  ++mProgressTrackCount;
744  }
745 
746  if (mDoProfile) {
747  if (mStatistics.mTotalWindows == 0) {
748  mEffect.Effect::MessageBox(XO("Selected noise profile is too short."));
749  return false;
750  }
751  }
752 
753  return true;
754 }
755 
757 {
758  // Given an array of gain mutipliers, average them
759  // GEOMETRICALLY. Don't multiply and take nth root --
760  // that may quickly cause underflows. Instead, average the logs.
761 
762  if (mFreqSmoothingBins == 0)
763  return;
764 
765  {
766  auto pScratch = mFreqSmoothingScratch.data();
767  std::fill(pScratch, pScratch + mSpectrumSize, 0.0f);
768  }
769 
770  for (size_t ii = 0; ii < mSpectrumSize; ++ii)
771  gains[ii] = log(gains[ii]);
772 
773  // ii must be signed
774  for (int ii = 0; ii < (int)mSpectrumSize; ++ii) {
775  const int j0 = std::max(0, ii - (int)mFreqSmoothingBins);
776  const int j1 = std::min(mSpectrumSize - 1, ii + mFreqSmoothingBins);
777  for(int jj = j0; jj <= j1; ++jj) {
778  mFreqSmoothingScratch[ii] += gains[jj];
779  }
780  mFreqSmoothingScratch[ii] /= (j1 - j0 + 1);
781  }
782 
783  for (size_t ii = 0; ii < mSpectrumSize; ++ii)
784  gains[ii] = exp(mFreqSmoothingScratch[ii]);
785 }
786 
788  eWindowFunctions outWindowType,
789  EffectNoiseReduction &effect,
790  const Settings &settings, Statistics &statistics
791 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
792  , double f0, double f1
793 #endif
794 )
795 : TrackSpectrumTransformer{ !settings.mDoProfile, inWindowType, outWindowType,
798 }
799 , mDoProfile{ settings.mDoProfile }
800 
801 , mEffect{ effect }
802 , mStatistics{ statistics }
803 
804 , mFreqSmoothingScratch( mSpectrumSize )
805 , mFreqSmoothingBins{ size_t(std::max(0.0, settings.mFreqSmoothingBands)) }
806 , mBinLow{ 0 }
807 , mBinHigh{ mSpectrumSize }
808 
809 , mNoiseReductionChoice{ settings.mNoiseReductionChoice }
810 , mMethod{ settings.mMethod }
811 
812 // Sensitivity setting is a base 10 log, turn it into a natural log
813 , mNewSensitivity{ settings.mNewSensitivity * log(10.0) }
814 {
815  const auto sampleRate = mStatistics.mRate;
816 
817 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
818  {
819  // mBinLow is inclusive, mBinHigh is exclusive, of
820  // the range of frequencies to affect. Include any
821  // bin that partly overlaps the selected range of frequencies.
822  const double bin = sampleRate / mWindowSize;
823  if (f0 >= 0.0 )
824  mBinLow = floor(f0 / bin);
825  if (f1 >= 0.0)
826  mBinHigh = ceil(f1 / bin);
827  }
828 #endif
829 
830  const double noiseGain = -settings.mNoiseGain;
831  const unsigned nAttackBlocks = 1 + (int)(settings.mAttackTime * sampleRate / mStepSize);
832  const unsigned nReleaseBlocks = 1 + (int)(settings.mReleaseTime * sampleRate / mStepSize);
833  // Applies to amplitudes, divide by 20:
834  mNoiseAttenFactor = DB_TO_LINEAR(noiseGain);
835  // Apply to gain factors which apply to amplitudes, divide by 20:
836  mOneBlockAttack = DB_TO_LINEAR(noiseGain / nAttackBlocks);
837  mOneBlockRelease = DB_TO_LINEAR(noiseGain / nReleaseBlocks);
838  // Applies to power, divide by 10:
839  mOldSensitivityFactor = pow(10.0, settings.mOldSensitivity / 10.0);
840 
841  mNWindowsToExamine = (mMethod == DM_OLD_METHOD)
842  ? std::max(2, (int)(minSignalTime * sampleRate / mStepSize))
843  : 1 + mStepsPerWindow;
844 
845  mCenter = mNWindowsToExamine / 2;
846  wxASSERT(mCenter >= 1); // release depends on this assumption
847 
848  if (mDoProfile)
849 #ifdef OLD_METHOD_AVAILABLE
850  mHistoryLen = mNWindowsToExamine;
851 #else
852  mHistoryLen = 1;
853 #endif
854  else {
855  // Allow long enough queue for sufficient inspection of the middle
856  // and for attack processing
857  // See ReduceNoise()
858  mHistoryLen = std::max(mNWindowsToExamine, mCenter + nAttackBlocks);
859  }
860 }
861 
863 {
864  for (size_t ii = 0, nn = TotalQueueSize(); ii < nn; ++ii) {
865  MyWindow &record = NthWindow(ii);
866  std::fill(record.mSpectrums.begin(), record.mSpectrums.end(), 0.0);
867  std::fill(record.mGains.begin(), record.mGains.end(), mNoiseAttenFactor);
868  }
870 }
871 
873 {
874  auto &worker = static_cast<Worker &>(transformer);
875  // Compute power spectrum in the newest window
876  {
877  MyWindow &record = worker.NthWindow(0);
878  float *pSpectrum = &record.mSpectrums[0];
879  const double dc = record.mRealFFTs[0];
880  *pSpectrum++ = dc * dc;
881  float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
882  for (size_t nn = worker.mSpectrumSize - 2; nn--;) {
883  const double re = *pReal++, im = *pImag++;
884  *pSpectrum++ = re * re + im * im;
885  }
886  const double nyquist = record.mImagFFTs[0];
887  *pSpectrum = nyquist * nyquist;
888  }
889 
890  if (worker.mDoProfile)
891  worker.GatherStatistics();
892  else
893  worker.ReduceNoise();
894 
895  // Update the Progress meter, let user cancel
896  return !worker.mEffect.TrackProgress(worker.mProgressTrackCount,
897  std::min(1.0,
898  ((++worker.mProgressWindowCount).as_double() * worker.mStepSize)
899  / worker.mLen.as_double()));
900 }
901 
903 {
904  const auto windows = mStatistics.mTrackWindows;
905 
906  // Combine averages in case of multiple profile tracks.
907  if (windows) {
908  const auto multiplier = mStatistics.mTotalWindows;
909  const auto denom = windows + multiplier;
910  for (size_t ii = 0, nn = mStatistics.mMeans.size(); ii < nn; ++ii) {
911  auto &mean = mStatistics.mMeans[ii];
912  auto &sum = mStatistics.mSums[ii];
913  mean = (mean * multiplier + sum) / denom;
914  // Reset for next track
915  sum = 0;
916  }
917  // Reset for next track
918  mStatistics.mTrackWindows = 0;
919  mStatistics.mTotalWindows = denom;
920  }
921 }
922 
924 {
925  ++mStatistics.mTrackWindows;
926 
927  {
928  // NEW statistics
929  auto pPower = NthWindow(0).mSpectrums.data();
930  auto pSum = mStatistics.mSums.data();
931  for (size_t jj = 0; jj < mSpectrumSize; ++jj) {
932  *pSum++ += *pPower++;
933  }
934  }
935 
936 #ifdef OLD_METHOD_AVAILABLE
937  // The noise threshold for each frequency is the maximum
938  // level achieved at that frequency for a minimum of
939  // mMinSignalBlocks blocks in a row - the max of a min.
940 
941  auto finish = mHistoryLen;
942 
943  {
944  // old statistics
945  auto pPower = NthWindow(0).mSpectrums.data();
946  auto pThreshold = mStatistics.mNoiseThreshold.data();
947  for (size_t jj = 0; jj < mSpectrumSize; ++jj) {
948  float min = *pPower++;
949  for (unsigned ii = 1; ii < finish; ++ii)
950  min = std::min(min, NthWindow(ii).mSpectrums[jj]);
951  *pThreshold = std::max(*pThreshold, min);
952  ++pThreshold;
953  }
954  }
955 #endif
956 }
957 
958 // Return true iff the given band of the "center" window looks like noise.
959 // Examine the band in a few neighboring windows to decide.
960 inline
961 bool EffectNoiseReduction::Worker::Classify(unsigned nWindows, int band)
962 {
963  switch (mMethod) {
964 #ifdef OLD_METHOD_AVAILABLE
965  case DM_OLD_METHOD:
966  {
967  float min = NthWindow(0).mSpectrums[band];
968  for (unsigned ii = 1; ii < nWindows; ++ii)
969  min = std::min(min, NthWindow(ii).mSpectrums[band]);
970  return
971  min <= mOldSensitivityFactor * mStatistics.mNoiseThreshold[band];
972  }
973 #endif
974  // New methods suppose an exponential distribution of power values
975  // in the noise; NEW sensitivity (which is nonnegative) is meant to be
976  // the negative of a log of probability (so the log is nonpositive)
977  // that noise strays above the threshold. Call that probability
978  // 1 - F. The quantile function of an exponential distribution is
979  // - log (1 - F) * mean. Thus simply multiply mean by sensitivity
980  // to get the threshold.
981  case DM_MEDIAN:
982  // This method examines the window and all other windows
983  // whose centers lie on or between its boundaries, and takes a median, to
984  // avoid being fooled by up and down excursions into
985  // either the mistake of classifying noise as not noise
986  // (leaving a musical noise chime), or the opposite
987  // (distorting the signal with a drop out).
988  if (nWindows <= 3)
989  // No different from second greatest.
990  goto secondGreatest;
991  else if (nWindows <= 5)
992  {
993  float greatest = 0.0, second = 0.0, third = 0.0;
994  for (unsigned ii = 0; ii < nWindows; ++ii) {
995  const float power = NthWindow(ii).mSpectrums[band];
996  if (power >= greatest)
997  third = second, second = greatest, greatest = power;
998  else if (power >= second)
999  third = second, second = power;
1000  else if (power >= third)
1001  third = power;
1002  }
1003  return third <= mNewSensitivity * mStatistics.mMeans[band];
1004  }
1005  else {
1006  // not implemented
1007  wxASSERT(false);
1008  return true;
1009  }
1010  secondGreatest:
1011  case DM_SECOND_GREATEST:
1012  {
1013  // This method just throws out the high outlier. It
1014  // should be less prone to distortions and more prone to
1015  // chimes.
1016  float greatest = 0.0, second = 0.0;
1017  for (unsigned ii = 0; ii < nWindows; ++ii) {
1018  const float power = NthWindow(ii).mSpectrums[band];
1019  if (power >= greatest)
1020  second = greatest, greatest = power;
1021  else if (power >= second)
1022  second = power;
1023  }
1024  return second <= mNewSensitivity * mStatistics.mMeans[band];
1025  }
1026  default:
1027  wxASSERT(false);
1028  return true;
1029  }
1030 }
1031 
1033 {
1034  auto historyLen = CurrentQueueSize();
1035  auto nWindows = std::min<unsigned>(mNWindowsToExamine, historyLen);
1036 
1037  if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
1038  {
1039  MyWindow &record = NthWindow(0);
1040  // Default all gains to the reduction factor,
1041  // until we decide to raise some of them later
1042  float *pGain = &record.mGains[0];
1043  std::fill(pGain, pGain + mSpectrumSize, mNoiseAttenFactor);
1044  }
1045 
1046  // Raise the gain for elements in the center of the sliding history
1047  // or, if isolating noise, zero out the non-noise
1048  if (nWindows > mCenter)
1049  {
1050  auto pGain = NthWindow(mCenter).mGains.data();
1051  if (mNoiseReductionChoice == NRC_ISOLATE_NOISE) {
1052  // All above or below the selected frequency range is non-noise
1053  std::fill(pGain, pGain + mBinLow, 0.0f);
1054  std::fill(pGain + mBinHigh, pGain + mSpectrumSize, 0.0f);
1055  pGain += mBinLow;
1056  for (size_t jj = mBinLow; jj < mBinHigh; ++jj) {
1057  const bool isNoise = Classify(nWindows, jj);
1058  *pGain++ = isNoise ? 1.0 : 0.0;
1059  }
1060  }
1061  else {
1062  // All above or below the selected frequency range is non-noise
1063  std::fill(pGain, pGain + mBinLow, 1.0f);
1064  std::fill(pGain + mBinHigh, pGain + mSpectrumSize, 1.0f);
1065  pGain += mBinLow;
1066  for (size_t jj = mBinLow; jj < mBinHigh; ++jj) {
1067  const bool isNoise = Classify(nWindows, jj);
1068  if (!isNoise)
1069  *pGain = 1.0;
1070  ++pGain;
1071  }
1072  }
1073  }
1074 
1075  if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
1076  {
1077  // In each direction, define an exponential decay of gain from the
1078  // center; make actual gains the maximum of mNoiseAttenFactor, and
1079  // the decay curve, and their prior values.
1080 
1081  // First, the attack, which goes backward in time, which is,
1082  // toward higher indices in the queue.
1083  for (size_t jj = 0; jj < mSpectrumSize; ++jj) {
1084  for (unsigned ii = mCenter + 1; ii < historyLen; ++ii) {
1085  const float minimum =
1086  std::max(mNoiseAttenFactor,
1087  NthWindow(ii - 1).mGains[jj] * mOneBlockAttack);
1088  float &gain = NthWindow(ii).mGains[jj];
1089  if (gain < minimum)
1090  gain = minimum;
1091  else
1092  // We can stop now, our attack curve is intersecting
1093  // the release curve of some window previously processed.
1094  break;
1095  }
1096  }
1097 
1098  // Now, release. We need only look one window ahead. This part will
1099  // be visited again when we examine the next window, and
1100  // carry the decay further.
1101  {
1102  auto pNextGain = NthWindow(mCenter - 1).mGains.data();
1103  auto pThisGain = NthWindow(mCenter).mGains.data();
1104  for (auto nn = mSpectrumSize; nn--;) {
1105  *pNextGain =
1106  std::max(*pNextGain,
1107  std::max(mNoiseAttenFactor,
1108  *pThisGain++ * mOneBlockRelease));
1109  ++pNextGain;
1110  }
1111  }
1112  }
1113 
1114 
1115  if (QueueIsFull()) {
1116  auto &record = NthWindow(historyLen - 1); // end of the queue
1117  const auto last = mSpectrumSize - 1;
1118 
1119  if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
1120  // Apply frequency smoothing to output gain
1121  // Gains are not less than mNoiseAttenFactor
1122  ApplyFreqSmoothing(record.mGains);
1123 
1124  // Apply gain to FFT
1125  {
1126  const float *pGain = &record.mGains[1];
1127  float *pReal = &record.mRealFFTs[1];
1128  float *pImag = &record.mImagFFTs[1];
1129  auto nn = mSpectrumSize - 2;
1130  if (mNoiseReductionChoice == NRC_LEAVE_RESIDUE) {
1131  for (; nn--;) {
1132  // Subtract the gain we would otherwise apply from 1, and
1133  // negate that to flip the phase.
1134  const double gain = *pGain++ - 1.0;
1135  *pReal++ *= gain;
1136  *pImag++ *= gain;
1137  }
1138  record.mRealFFTs[0] *= (record.mGains[0] - 1.0);
1139  // The Fs/2 component is stored as the imaginary part of the DC component
1140  record.mImagFFTs[0] *= (record.mGains[last] - 1.0);
1141  }
1142  else {
1143  for (; nn--;) {
1144  const double gain = *pGain++;
1145  *pReal++ *= gain;
1146  *pImag++ *= gain;
1147  }
1148  record.mRealFFTs[0] *= record.mGains[0];
1149  // The Fs/2 component is stored as the imaginary part of the DC component
1150  record.mImagFFTs[0] *= record.mGains[last];
1151  }
1152  }
1153  }
1154 }
1155 
1157 {
1158  if (mDoProfile)
1159  FinishTrackStatistics();
1161 }
1162 
1163 //----------------------------------------------------------------------------
1164 // EffectNoiseReduction::Dialog
1165 //----------------------------------------------------------------------------
1166 
1167 enum {
1170 #ifdef ISOLATE_CHOICE
1172 #endif
1173 #ifdef RESIDUE_CHOICE
1175 #endif
1176 
1177 #ifdef ADVANCED_SETTINGS
1178  ID_CHOICE_METHOD,
1179 #endif
1180 
1181  // Slider/text pairs
1184 
1187 
1188 #ifdef ATTACK_AND_RELEASE
1189  ID_ATTACK_TIME_SLIDER,
1190  ID_ATTACK_TIME_TEXT,
1191 
1192  ID_RELEASE_TIME_SLIDER,
1193  ID_RELEASE_TIME_TEXT,
1194 #endif
1195 
1198 
1200 
1201 #ifdef ADVANCED_SETTINGS
1202  ID_OLD_SENSITIVITY_SLIDER = END_OF_BASIC_SLIDERS,
1203  ID_OLD_SENSITIVITY_TEXT,
1204 
1205  END_OF_ADVANCED_SLIDERS,
1206  END_OF_SLIDERS = END_OF_ADVANCED_SLIDERS,
1207 #else
1209 #endif
1210 
1212 };
1213 
1214 namespace {
1215 
1216 struct ControlInfo {
1218 
1219  double Value(long sliderSetting) const
1220  {
1221  return
1222  valueMin +
1223  (double(sliderSetting) / sliderMax) * (valueMax - valueMin);
1224  }
1225 
1226  long SliderSetting(double value) const
1227  {
1228  return TrapLong(
1229  0.5 + sliderMax * (value - valueMin) / (valueMax - valueMin),
1230  0, sliderMax);
1231  }
1232 
1233  wxString Text(double value) const
1234  {
1235  if (formatAsInt)
1236  return wxString::Format(format, (int)(value));
1237  else
1238  return wxString::Format(format, value);
1239  }
1240 
1241  void CreateControls(int id, ShuttleGui &S) const
1242  {
1243  wxTextCtrl *const text = S.Id(id + 1)
1244  .Validator<FloatingPointValidator<double>>(
1245  formatAsInt ? 0 : 2,
1246  nullptr,
1247  NumValidatorStyle::DEFAULT,
1248  valueMin, valueMax
1249  )
1250  .AddTextBox(textBoxCaption, wxT(""), 0);
1251 
1252  wxSlider *const slider =
1253  S.Id(id)
1254  .Name( sliderName )
1255  .Style(wxSL_HORIZONTAL)
1256  .MinSize( { 150, -1 } )
1257  .AddSlider( {}, 0, sliderMax);
1258  }
1259 
1261  double valueMin;
1262  double valueMax;
1264  // (valueMin - valueMax) / sliderMax is the value increment of the slider
1265  const wxChar* format;
1269 
1270  ControlInfo(MemberPointer f, double vMin, double vMax, long sMax, const wxChar* fmt, bool fAsInt,
1271  const TranslatableString &caption, const TranslatableString &name)
1272  : field(f), valueMin(vMin), valueMax(vMax), sliderMax(sMax), format(fmt), formatAsInt(fAsInt)
1273  , textBoxCaption(caption), sliderName(name)
1274  {
1275  }
1276 };
1277 
1279  static const ControlInfo table[] = {
1281  0.0, 48.0, 48, wxT("%d"), true,
1282  XXO("&Noise reduction (dB):"), XO("Noise reduction")),
1284  0.0, 24.0, 48, wxT("%.2f"), false,
1285  XXO("&Sensitivity:"), XO("Sensitivity")),
1286 #ifdef ATTACK_AND_RELEASE
1288  0, 1.0, 100, wxT("%.2f"), false,
1289  XXO("Attac&k time (secs):"), XO("Attack time")),
1291  0, 1.0, 100, wxT("%.2f"), false,
1292  XXO("R&elease time (secs):"), XO("Release time")),
1293 #endif
1295  0, 12, 12, wxT("%d"), true,
1296  XXO("&Frequency smoothing (bands):"), XO("Frequency smoothing")),
1297 
1298 #ifdef ADVANCED_SETTINGS
1300  -20.0, 20.0, 4000, wxT("%.2f"), false,
1301  XXO("Sensiti&vity (dB):"), XO("Old Sensitivity")),
1302  // add here
1303 #endif
1304  };
1305 
1306 return table;
1307 }
1308 
1309 } // namespace
1310 
1311 
1318 
1320 #ifdef ISOLATE_CHOICE
1322 #endif
1323 #ifdef RESIDUE_CHOICE
1325 #endif
1326 
1327 #ifdef ADVANCED_SETTINGS
1328  EVT_CHOICE(ID_CHOICE_METHOD, EffectNoiseReduction::Dialog::OnMethodChoice)
1329 #endif
1330 
1333 
1336 
1339 
1340 #ifdef ATTACK_AND_RELEASE
1341  EVT_SLIDER(ID_ATTACK_TIME_SLIDER, EffectNoiseReduction::Dialog::OnSlider)
1342  EVT_TEXT(ID_ATTACK_TIME_TEXT, EffectNoiseReduction::Dialog::OnText)
1343 
1344  EVT_SLIDER(ID_RELEASE_TIME_SLIDER, EffectNoiseReduction::Dialog::OnSlider)
1345  EVT_TEXT(ID_RELEASE_TIME_TEXT, EffectNoiseReduction::Dialog::OnText)
1346 #endif
1347 
1348 
1349 #ifdef ADVANCED_SETTINGS
1350  EVT_SLIDER(ID_OLD_SENSITIVITY_SLIDER, EffectNoiseReduction::Dialog::OnSlider)
1351  EVT_TEXT(ID_OLD_SENSITIVITY_TEXT, EffectNoiseReduction::Dialog::OnText)
1352 #endif
1354 
1356 (EffectNoiseReduction *effect,
1358  wxWindow *parent, bool bHasProfile, bool bAllowTwiddleSettings)
1359  : EffectDialog( parent, XO("Noise Reduction"), EffectTypeProcess,wxDEFAULT_DIALOG_STYLE, eHelpButton )
1360  , m_pEffect(effect)
1361  , m_pSettings(settings) // point to
1362  , mTempSettings(*settings) // copy
1363  , mbHasProfile(bHasProfile)
1364  , mbAllowTwiddleSettings(bAllowTwiddleSettings)
1365  // NULL out the control members until the controls are created.
1366  , mKeepSignal(NULL)
1367 #ifdef ISOLATE_CHOICE
1368  , mKeepNoise(NULL)
1369 #endif
1370 #ifdef RESIDUE_CHOICE
1371  , mResidue(NULL)
1372 #endif
1373 {
1375 
1376  wxButton *const pButtonPreview =
1377  (wxButton *)wxWindow::FindWindowById(ID_EFFECT_PREVIEW, this);
1378  wxButton *const pButtonReduceNoise =
1379  (wxButton *)wxWindow::FindWindowById(wxID_OK, this);
1380 
1381  if (mbHasProfile || mbAllowTwiddleSettings) {
1382  pButtonPreview->Enable(!mbAllowTwiddleSettings);
1383  pButtonReduceNoise->SetFocus();
1384  }
1385  else {
1386  pButtonPreview->Enable(false);
1387  pButtonReduceNoise->Enable(false);
1388  }
1389 }
1390 
1392 {
1393  // If Isolate is chosen, disable controls that define
1394  // "what to do with noise" rather than "what is noise."
1395  // Else, enable them.
1396  // This does NOT include sensitivity, NEW or old, nor
1397  // the choice of window functions, size, or step.
1398  // The method choice is not included, because it affects
1399  // which sensitivity slider is operative, and that is part
1400  // of what defines noise.
1401 
1402  static const int toDisable[] = {
1404  ID_GAIN_TEXT,
1405 
1407  ID_FREQ_TEXT,
1408 
1409 #ifdef ATTACK_AND_RELEASE
1410  ID_ATTACK_TIME_SLIDER,
1411  ID_ATTACK_TIME_TEXT,
1412 
1413  ID_RELEASE_TIME_SLIDER,
1414  ID_RELEASE_TIME_TEXT,
1415 #endif
1416  };
1417  static const auto nToDisable = sizeof(toDisable) / sizeof(toDisable[0]);
1418 
1419  bool bIsolating =
1420 #ifdef ISOLATE_CHOICE
1421  mKeepNoise->GetValue();
1422 #else
1423  false;
1424 #endif
1425  for (auto ii = nToDisable; ii--;)
1426  wxWindow::FindWindowById(toDisable[ii], this)->Enable(!bIsolating);
1427 }
1428 
1429 #ifdef ADVANCED_SETTINGS
1430 void EffectNoiseReduction::Dialog::EnableDisableSensitivityControls()
1431 {
1432  wxChoice *const pChoice =
1433  static_cast<wxChoice*>(wxWindow::FindWindowById(ID_CHOICE_METHOD, this));
1434  const bool bOldMethod =
1435  pChoice->GetSelection() == DM_OLD_METHOD;
1436  wxWindow::FindWindowById(ID_OLD_SENSITIVITY_SLIDER, this)->Enable(bOldMethod);
1437  wxWindow::FindWindowById(ID_OLD_SENSITIVITY_TEXT, this)->Enable(bOldMethod);
1438  wxWindow::FindWindowById(ID_NEW_SENSITIVITY_SLIDER, this)->Enable(!bOldMethod);
1439  wxWindow::FindWindowById(ID_NEW_SENSITIVITY_TEXT, this)->Enable(!bOldMethod);
1440 }
1441 #endif
1442 
1443 void EffectNoiseReduction::Dialog::OnGetProfile(wxCommandEvent & WXUNUSED(event))
1444 {
1445  // Project has not be changed so skip pushing state
1447 
1448  if (!TransferDataFromWindow())
1449  return;
1450 
1451  // Return code distinguishes this first step from the actual effect
1452  EndModal(1);
1453 }
1454 
1455 // This handles the whole radio group
1456 void EffectNoiseReduction::Dialog::OnNoiseReductionChoice( wxCommandEvent & WXUNUSED(event))
1457 {
1458  if (mKeepSignal->GetValue())
1459  mTempSettings.mNoiseReductionChoice = NRC_REDUCE_NOISE;
1460 #ifdef ISOLATE_CHOICE
1461  else if (mKeepNoise->GetValue())
1462  mTempSettings.mNoiseReductionChoice = NRC_ISOLATE_NOISE;
1463 #endif
1464 #ifdef RESIDUE_CHOICE
1465  else
1466  mTempSettings.mNoiseReductionChoice = NRC_LEAVE_RESIDUE;
1467 #endif
1468  DisableControlsIfIsolating();
1469 }
1470 
1471 #ifdef ADVANCED_SETTINGS
1472 void EffectNoiseReduction::Dialog::OnMethodChoice(wxCommandEvent &)
1473 {
1474  EnableDisableSensitivityControls();
1475 }
1476 #endif
1477 
1478 void EffectNoiseReduction::Dialog::OnPreview(wxCommandEvent & WXUNUSED(event))
1479 {
1480  if (!TransferDataFromWindow())
1481  return;
1482 
1483  // Save & restore parameters around Preview, because we didn't do OK.
1484  auto cleanup = valueRestorer( *m_pSettings );
1485  *m_pSettings = mTempSettings;
1486  m_pSettings->mDoProfile = false;
1487 
1488  m_pEffect->Preview( false );
1489 }
1490 
1491 void EffectNoiseReduction::Dialog::OnReduceNoise( wxCommandEvent & WXUNUSED(event))
1492 {
1493  if (!TransferDataFromWindow())
1494  return;
1495 
1496  EndModal(2);
1497 }
1498 
1499 void EffectNoiseReduction::Dialog::OnCancel(wxCommandEvent & WXUNUSED(event))
1500 {
1501  EndModal(0);
1502 }
1503 
1504 void EffectNoiseReduction::Dialog::OnHelp(wxCommandEvent & WXUNUSED(event))
1505 {
1506  HelpSystem::ShowHelp(this, "Noise_Reduction", true);
1507 }
1508 
1510 {
1511  S.StartStatic(XO("Step 1"));
1512  {
1513  S.AddVariableText(XO(
1514 "Select a few seconds of just noise so Audacity knows what to filter out,\nthen click Get Noise Profile:"));
1515  //m_pButton_GetProfile =
1516  S.Id(ID_BUTTON_GETPROFILE).AddButton(XXO("&Get Noise Profile"));
1517  }
1518  S.EndStatic();
1519 
1520  S.StartStatic(XO("Step 2"));
1521  {
1522  S.AddVariableText(XO(
1523 "Select all of the audio you want filtered, choose how much noise you want\nfiltered out, and then click 'OK' to reduce noise.\n"));
1524 
1525  S.StartMultiColumn(3, wxEXPAND);
1526  S.SetStretchyCol(2);
1527  {
1528  for (int id = FIRST_SLIDER; id < END_OF_BASIC_SLIDERS; id += 2) {
1529  const ControlInfo &info = controlInfo()[(id - FIRST_SLIDER) / 2];
1530  info.CreateControls(id, S);
1531  }
1532  }
1533  S.EndMultiColumn();
1534 
1535  S.StartMultiColumn(
1536  2
1537 #ifdef RESIDUE_CHOICE
1538  +1
1539 #endif
1540 #ifdef ISOLATE_CHOICE
1541  +1
1542 #endif
1543  ,
1544  wxALIGN_CENTER_HORIZONTAL);
1545  {
1546  S.AddPrompt(XXO("Noise:"));
1547  mKeepSignal = S.Id(ID_RADIOBUTTON_KEEPSIGNAL)
1548  /* i18n-hint: Translate differently from "Residue" ! */
1549  .AddRadioButton(XXO("Re&duce"));
1550 #ifdef ISOLATE_CHOICE
1551  mKeepNoise = S.Id(ID_RADIOBUTTON_KEEPNOISE)
1552  .AddRadioButtonToGroup(XXO("&Isolate"));
1553 #endif
1554 #ifdef RESIDUE_CHOICE
1555  mResidue = S.Id(ID_RADIOBUTTON_RESIDUE)
1556  /* i18n-hint: Means the difference between effect and original sound. Translate differently from "Reduce" ! */
1557  .AddRadioButtonToGroup(XXO("Resid&ue"));
1558 #endif
1559  }
1560  S.EndMultiColumn();
1561  }
1562  S.EndStatic();
1563 
1564 
1565 #ifdef ADVANCED_SETTINGS
1566  S.StartStatic(XO("Advanced Settings"));
1567  {
1568  S.StartMultiColumn(2);
1569  {
1570  S.TieChoice(XXO("&Window types:"),
1571  mTempSettings.mWindowTypes,
1572  []{
1573  TranslatableStrings windowTypeChoices;
1574  for (size_t ii = 0; ii < WT_N_WINDOW_TYPES; ++ii)
1575  windowTypeChoices.push_back(windowTypesInfo[ii].name);
1576  return windowTypeChoices;
1577  }()
1578  );
1579 
1580  S.TieChoice(XXO("Window si&ze:"),
1581  mTempSettings.mWindowSizeChoice,
1582  {
1583  XO("8") ,
1584  XO("16") ,
1585  XO("32") ,
1586  XO("64") ,
1587  XO("128") ,
1588  XO("256") ,
1589  XO("512") ,
1590  XO("1024") ,
1591  XO("2048 (default)") ,
1592  XO("4096") ,
1593  XO("8192") ,
1594  XO("16384") ,
1595  }
1596  );
1597 
1598  S.TieChoice(XXO("S&teps per window:"),
1599  mTempSettings.mStepsPerWindowChoice,
1600  {
1601  XO("2") ,
1602  XO("4 (default)") ,
1603  XO("8") ,
1604  XO("16") ,
1605  XO("32") ,
1606  XO("64") ,
1607  }
1608  );
1609 
1610  S.Id(ID_CHOICE_METHOD)
1611  .TieChoice(XXO("Discrimination &method:"),
1612  mTempSettings.mMethod,
1613  []{
1614  TranslatableStrings methodChoices;
1615  auto nn = DM_N_METHODS;
1616 #ifndef OLD_METHOD_AVAILABLE
1617  --nn;
1618 #endif
1619  for (auto ii = 0; ii < nn; ++ii)
1620  methodChoices.push_back(discriminationMethodInfo[ii].name);
1621  return methodChoices;
1622  }());
1623  }
1624  S.EndMultiColumn();
1625 
1626  S.StartMultiColumn(3, wxEXPAND);
1627  S.SetStretchyCol(2);
1628  {
1629  for (int id = END_OF_BASIC_SLIDERS; id < END_OF_ADVANCED_SLIDERS; id += 2) {
1630  const ControlInfo &info = controlInfo()[(id - FIRST_SLIDER) / 2];
1631  info.CreateControls(id, S);
1632  }
1633  }
1634  S.EndMultiColumn();
1635  }
1636  S.EndStatic();
1637 #endif
1638 }
1639 
1641 {
1642  // Do the choice controls:
1644  return false;
1645 
1646  for (int id = FIRST_SLIDER; id < END_OF_SLIDERS; id += 2) {
1647  wxSlider* slider =
1648  static_cast<wxSlider*>(wxWindow::FindWindowById(id, this));
1649  wxTextCtrl* text =
1650  static_cast<wxTextCtrl*>(wxWindow::FindWindowById(id + 1, this));
1651  const ControlInfo &info = controlInfo()[(id - FIRST_SLIDER) / 2];
1652  const double field = mTempSettings.*(info.field);
1653  text->SetValue(info.Text(field));
1654  slider->SetValue(info.SliderSetting(field));
1655  }
1656 
1657  mKeepSignal->SetValue(mTempSettings.mNoiseReductionChoice == NRC_REDUCE_NOISE);
1658 #ifdef ISOLATE_CHOICE
1659  mKeepNoise->SetValue(mTempSettings.mNoiseReductionChoice == NRC_ISOLATE_NOISE);
1660 #endif
1661 #ifdef RESIDUE_CHOICE
1662  mResidue->SetValue(mTempSettings.mNoiseReductionChoice == NRC_LEAVE_RESIDUE);
1663 #endif
1664 
1665  // Set the enabled states of controls
1666  DisableControlsIfIsolating();
1667 #ifdef ADVANCED_SETTINGS
1668  EnableDisableSensitivityControls();
1669 #endif
1670 
1671  return true;
1672 }
1673 
1675 {
1676  if( !wxWindow::Validate() )
1677  return false;
1678  // Do the choice controls:
1680  return false;
1681 
1682  wxCommandEvent dummy;
1683  OnNoiseReductionChoice(dummy);
1684 
1685  return mTempSettings.Validate(m_pEffect);
1686 }
1687 
1688 void EffectNoiseReduction::Dialog::OnText(wxCommandEvent &event)
1689 {
1690  int id = event.GetId();
1691  int idx = (id - FIRST_SLIDER - 1) / 2;
1692  const ControlInfo &info = controlInfo()[idx];
1693  wxTextCtrl* text =
1694  static_cast<wxTextCtrl*>(wxWindow::FindWindowById(id, this));
1695  wxSlider* slider =
1696  static_cast<wxSlider*>(wxWindow::FindWindowById(id - 1, this));
1697  double &field = mTempSettings.*(info.field);
1698 
1699  text->GetValue().ToDouble(&field);
1700  slider->SetValue(info.SliderSetting(field));
1701 }
1702 
1703 void EffectNoiseReduction::Dialog::OnSlider(wxCommandEvent &event)
1704 {
1705  int id = event.GetId();
1706  int idx = (id - FIRST_SLIDER) / 2;
1707  const ControlInfo &info = controlInfo()[idx];
1708  wxSlider* slider =
1709  static_cast<wxSlider*>(wxWindow::FindWindowById(id, this));
1710  wxTextCtrl* text =
1711  static_cast<wxTextCtrl*>(wxWindow::FindWindowById(id + 1, this));
1712  double &field = mTempSettings.*(info.field);
1713 
1714  field = info.Value(slider->GetValue());
1715  text->SetValue(info.Text(field));
1716 }
EffectNoiseReduction::Statistics
Definition: NoiseReduction.cpp:170
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::Text
wxString Text(double value) const
Definition: NoiseReduction.cpp:1233
END_OF_BASIC_SLIDERS
@ END_OF_BASIC_SLIDERS
Definition: NoiseReduction.cpp:1199
EffectNoiseReduction::Worker::FinishTrackStatistics
void FinishTrackStatistics()
Definition: NoiseReduction.cpp:902
EffectNoiseReduction::Settings::Settings
Settings()
Definition: NoiseReduction.cpp:246
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::MemberPointer
doubleEffectNoiseReduction::Settings::* MemberPointer
Definition: NoiseReduction.cpp:1217
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
EffectNoiseReduction
A two-pass effect to reduce background noise.
Definition: NoiseReduction.h:18
TrackSpectrumTransformer::DoStart
bool DoStart() override
Called before any calls to ProcessWindow.
Definition: SpectrumTransformer.cpp:404
EffectNoiseReduction::CheckWhetherSkipEffect
bool CheckWhetherSkipEffect() override
Definition: NoiseReduction.cpp:444
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
anonymous_namespace{NoiseReduction.cpp}::NRC_REDUCE_NOISE
@ NRC_REDUCE_NOISE
Definition: NoiseReduction.cpp:158
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::format
const wxChar * format
Definition: NoiseReduction.cpp:1265
field
#define field(n, t)
Definition: ImportAUP.cpp:167
EffectNoiseReduction::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: NoiseReduction.cpp:422
anonymous_namespace{NoiseReduction.cpp}::DiscriminationMethod
DiscriminationMethod
Definition: NoiseReduction.cpp:96
anonymous_namespace{NoiseReduction.cpp}::NRC_LEAVE_RESIDUE
@ NRC_LEAVE_RESIDUE
Definition: NoiseReduction.cpp:160
anonymous_namespace{NoiseReduction.cpp}::DiscriminationMethodInfo::name
const TranslatableString name
Definition: NoiseReduction.cpp:106
valueRestorer
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:226
EffectNoiseReduction::Settings::mDoProfile
bool mDoProfile
Definition: NoiseReduction.cpp:222
EffectNoiseReduction::Dialog::OnHelp
void OnHelp(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1504
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:75
fast_float::detail::power
constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept
Definition: fast_float.h:1454
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:56
EffectDialogFactory
std::function< wxDialog *(wxWindow &parent, EffectHostInterface &, EffectUIClientInterface &) > EffectDialogFactory
Definition: EffectHostInterface.h:55
DB_TO_LINEAR
const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB)
EffectNoiseReduction::Worker::mCenter
unsigned mCenter
Definition: NoiseReduction.cpp:325
EffectNoiseReduction::Settings::StepsPerWindow
unsigned StepsPerWindow() const
Definition: NoiseReduction.cpp:220
EffectNoiseReduction::Worker::mEffect
EffectNoiseReduction & mEffect
Definition: NoiseReduction.cpp:306
S
#define S(N)
Definition: ToChars.cpp:64
EffectNoiseReduction::Worker::mProgressWindowCount
sampleCount mProgressWindowCount
Definition: NoiseReduction.cpp:331
EffectNoiseReduction::Dialog::OnGetProfile
void OnGetProfile(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1443
EffectNoiseReduction::Settings::mNoiseReductionChoice
int mNoiseReductionChoice
Definition: NoiseReduction.cpp:237
EffectDialog::Init
void Init()
Definition: EffectUI.cpp:1411
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::formatAsInt
bool formatAsInt
Definition: NoiseReduction.cpp:1266
ID_GAIN_TEXT
@ ID_GAIN_TEXT
Definition: NoiseReduction.cpp:1183
anonymous_namespace{NoiseReduction.cpp}::WT_HAMMING_HANN
@ WT_HAMMING_HANN
Definition: NoiseReduction.cpp:124
eWinFuncBlackman
@ eWinFuncBlackman
Definition: FFT.h:115
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:71
EffectNoiseReduction::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: NoiseReduction.h:20
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
Effect::MessageBox
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
Definition: Effect.cpp:2238
anonymous_namespace{NoiseReduction.cpp}::writePrefs
void writePrefs(const StructureType *structure, const wxString &prefix, const PrefsTableEntry< StructureType, FieldType > *fields, size_t numFields)
Definition: NoiseReduction.cpp:512
SpectrumTransformer::Nth
Window & Nth(int n)
Access the queue, so you can inspect and modify any window in it.
Definition: SpectrumTransformer.h:140
eHelpButton
@ eHelpButton
Definition: ShuttleGui.h:604
Effect::CopyInputTracks
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:1834
anonymous_namespace{NoiseReduction.cpp}::windowTypesInfo
const struct anonymous_namespace{NoiseReduction.cpp}::WindowTypesInfo windowTypesInfo[WT_N_WINDOW_TYPES]
EffectNoiseReduction::Dialog::OnNoiseReductionChoice
void OnNoiseReductionChoice(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1456
EffectNoiseReduction::Worker::MyWindow::mGains
FloatVector mGains
Definition: NoiseReduction.cpp:283
entry
static ProjectFileIORegistry::AttributeWriterEntry entry
Definition: ProjectSettings.cpp:198
EffectNoiseReduction::Worker::GatherStatistics
void GatherStatistics()
Definition: NoiseReduction.cpp:923
EffectNoiseReduction::Settings::mWindowSizeChoice
int mWindowSizeChoice
Definition: NoiseReduction.cpp:241
eWinFuncRectangular
@ eWinFuncRectangular
Definition: FFT.h:111
ID_RADIOBUTTON_KEEPSIGNAL
@ ID_RADIOBUTTON_KEEPSIGNAL
Definition: NoiseReduction.cpp:1169
EffectNoiseReduction::Worker::DoStart
bool DoStart() override
Called before any calls to ProcessWindow.
Definition: NoiseReduction.cpp:862
TrackList
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1288
anonymous_namespace{NoiseReduction.cpp}::NoiseReductionChoice
NoiseReductionChoice
Definition: NoiseReduction.cpp:157
EffectNoiseReduction::Dialog::OnSlider
void OnSlider(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1703
Effect::mT1
double mT1
Definition: Effect.h:424
eWindowFunctions
eWindowFunctions
Definition: FFT.h:110
EffectNoiseReduction::Statistics::mWindowTypes
int mWindowTypes
Definition: NoiseReduction.cpp:189
EffectNoiseReduction::Statistics::Statistics
Statistics(size_t spectrumSize, double rate, int windowTypes)
Definition: NoiseReduction.cpp:172
EffectNoiseReduction::Worker::Worker
Worker(eWindowFunctions inWindowType, eWindowFunctions outWindowType, EffectNoiseReduction &effect, const Settings &settings, Statistics &statistics)
Definition: NoiseReduction.cpp:787
anonymous_namespace{NoiseReduction.cpp}::minSignalTime
const float minSignalTime
Definition: NoiseReduction.cpp:116
SpectrumTransformer::FloatVector
std::vector< float > FloatVector
Definition: SpectrumTransformer.h:37
EffectNoiseReduction::Worker::mLen
sampleCount mLen
Definition: NoiseReduction.cpp:330
EffectNoiseReduction::GetDescription
TranslatableString GetDescription() override
Definition: NoiseReduction.cpp:427
XO
#define XO(s)
Definition: Internat.h:31
anonymous_namespace{NoiseReduction.cpp}::ControlInfo
Definition: NoiseReduction.cpp:1216
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::valueMin
double valueMin
Definition: NoiseReduction.cpp:1261
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry::MemberPointer
FieldTypeStructureType::* MemberPointer
Definition: NoiseReduction.cpp:492
EffectNoiseReduction::Dialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: NoiseReduction.cpp:1674
RealFFTf.h
anonymous_namespace{NoiseReduction.cpp}::DEFAULT_STEPS_PER_WINDOW_CHOICE
@ DEFAULT_STEPS_PER_WINDOW_CHOICE
Definition: NoiseReduction.cpp:154
EffectDialog::TransferDataToWindow
bool TransferDataToWindow() override
Definition: EffectUI.cpp:1447
anonymous_namespace{NoiseReduction.cpp}::DM_OLD_METHOD
@ DM_OLD_METHOD
Definition: NoiseReduction.cpp:99
EffectNoiseReduction::Worker::NewWindow
std::unique_ptr< Window > NewWindow(size_t windowSize) override
Allocates a window to place in the queue.
Definition: NoiseReduction.cpp:614
EffectManager::Get
static EffectManager & Get()
Definition: EffectManager.cpp:42
ID_EFFECT_PREVIEW
#define ID_EFFECT_PREVIEW
Definition: Effect.h:508
EffectNoiseReduction::Dialog::OnText
void OnText(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1688
EffectNoiseReduction::Dialog::GetTempSettings
const Settings & GetTempSettings() const
Definition: NoiseReduction.cpp:359
EffectNoiseReduction::Worker::mNoiseAttenFactor
float mNoiseAttenFactor
Definition: NoiseReduction.cpp:321
HelpSystem::ShowHelp
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:237
EffectNoiseReduction::Worker::NthWindow
MyWindow & NthWindow(int nn)
Definition: NoiseReduction.cpp:289
EffectNoiseReduction::Statistics::mTotalWindows
unsigned mTotalWindows
Definition: NoiseReduction.cpp:191
EffectNoiseReduction::Dialog::m_pSettings
EffectNoiseReduction::Settings * m_pSettings
Definition: NoiseReduction.cpp:386
anonymous_namespace{NoiseReduction.cpp}::WindowTypesInfo::name
const TranslatableString name
Definition: NoiseReduction.cpp:132
Effect::TransferDataFromWindow
virtual bool TransferDataFromWindow()
Definition: Effect.cpp:1689
EffectNoiseReduction::Worker::mMethod
const int mMethod
Definition: NoiseReduction.cpp:316
EffectNoiseReduction::Statistics::mTrackWindows
unsigned mTrackWindows
Definition: NoiseReduction.cpp:192
EffectNoiseReduction::Settings::mAttackTime
double mAttackTime
Definition: NoiseReduction.cpp:230
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry::field
MemberPointer field
Definition: NoiseReduction.cpp:494
ID_FREQ_TEXT
@ ID_FREQ_TEXT
Definition: NoiseReduction.cpp:1197
EffectNoiseReduction::Dialog::mResidue
wxRadioButton * mResidue
Definition: NoiseReduction.cpp:398
END_OF_SLIDERS
@ END_OF_SLIDERS
Definition: NoiseReduction.cpp:1208
ID_BUTTON_GETPROFILE
@ ID_BUTTON_GETPROFILE
Definition: NoiseReduction.cpp:1168
EffectManager::SetSkipStateFlag
void SetSkipStateFlag(bool flag)
Definition: EffectManager.cpp:214
EffectNoiseReduction::ShowHostInterface
int ShowHostInterface(wxWindow &parent, const EffectDialogFactory &factory, bool forceModal=false) override
An override still here for historical reasons, ignoring the factory.
Definition: NoiseReduction.cpp:454
anonymous_namespace{NoiseReduction.cpp}::DiscriminationMethodInfo
Definition: NoiseReduction.cpp:105
EffectNoiseReduction::Worker::mOldSensitivityFactor
float mOldSensitivityFactor
Definition: NoiseReduction.cpp:322
EffectNoiseReduction::Dialog::TransferDataToWindow
bool TransferDataToWindow() override
Definition: NoiseReduction.cpp:1640
EffectNoiseReduction::Dialog::Dialog
Dialog(EffectNoiseReduction *effect, Settings *settings, wxWindow *parent, bool bHasProfile, bool bAllowTwiddleSettings)
Definition: NoiseReduction.cpp:1356
EffectUI.h
EffectNoiseReduction::Worker::Settings
EffectNoiseReduction::Settings Settings
Definition: NoiseReduction.cpp:261
eWinFuncHamming
@ eWinFuncHamming
Definition: FFT.h:113
FFT.h
EffectNoiseReduction::Settings::mReleaseTime
double mReleaseTime
Definition: NoiseReduction.cpp:231
XXO
#define XXO(s)
Definition: Internat.h:44
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::CreateControls
void CreateControls(int id, ShuttleGui &S) const
Definition: NoiseReduction.cpp:1241
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::sliderMax
long sliderMax
Definition: NoiseReduction.cpp:1263
EffectNoiseReduction::Worker::ApplyFreqSmoothing
void ApplyFreqSmoothing(FloatVector &gains)
Definition: NoiseReduction.cpp:756
EffectNoiseReduction::GetType
EffectType GetType() override
Type determines how it behaves.
Definition: NoiseReduction.cpp:434
Effect::mT0
double mT0
Definition: Effect.h:423
EffectNoiseReduction::Statistics::mMeans
FloatVector mMeans
Definition: NoiseReduction.cpp:194
anonymous_namespace{NoiseReduction.cpp}::WT_N_WINDOW_TYPES
@ WT_N_WINDOW_TYPES
Definition: NoiseReduction.cpp:127
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry::defaultValue
FieldType defaultValue
Definition: NoiseReduction.cpp:496
ID_NEW_SENSITIVITY_TEXT
@ ID_NEW_SENSITIVITY_TEXT
Definition: NoiseReduction.cpp:1186
EffectNoiseReduction::Settings::mOldSensitivity
double mOldSensitivity
Definition: NoiseReduction.cpp:234
ID_NEW_SENSITIVITY_SLIDER
@ ID_NEW_SENSITIVITY_SLIDER
Definition: NoiseReduction.cpp:1185
EffectNoiseReduction::Settings::PromptUser
int PromptUser(EffectNoiseReduction *effect, wxWindow &parent, bool bHasProfile, bool bAllowTwiddleSettings)
Definition: NoiseReduction.cpp:468
EffectNoiseReduction::Settings::mMethod
int mMethod
Definition: NoiseReduction.cpp:243
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::valueMax
double valueMax
Definition: NoiseReduction.cpp:1262
EffectNoiseReduction::Dialog::DisableControlsIfIsolating
void DisableControlsIfIsolating()
Definition: NoiseReduction.cpp:1391
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::Value
double Value(long sliderSetting) const
Definition: NoiseReduction.cpp:1219
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:1956
EffectNoiseReduction::Worker::MyWindow
Definition: NoiseReduction.cpp:274
EffectNoiseReduction::Worker::MyWindow::~MyWindow
~MyWindow() override
Definition: NoiseReduction.cpp:620
name
const TranslatableString name
Definition: Distortion.cpp:98
EffectNoiseReduction::Worker::mNewSensitivity
const double mNewSensitivity
Definition: NoiseReduction.cpp:317
FloatVector
std::vector< float > FloatVector
Definition: NoiseReduction.cpp:79
eWinFuncHann
@ eWinFuncHann
Definition: FFT.h:114
anonymous_namespace{NoiseReduction.cpp}::DM_SECOND_GREATEST
@ DM_SECOND_GREATEST
Definition: NoiseReduction.cpp:98
format
int format
Definition: ExportPCM.cpp:56
EffectNoiseReduction::Worker::ReduceNoise
void ReduceNoise()
Definition: NoiseReduction.cpp:1032
EffectNoiseReduction::Worker::MyWindow::mSpectrums
FloatVector mSpectrums
Definition: NoiseReduction.cpp:282
EffectDialog
Definition: EffectUI.h:162
ID_RADIOBUTTON_KEEPNOISE
@ ID_RADIOBUTTON_KEEPNOISE
Definition: NoiseRemoval.cpp:603
anonymous_namespace{NoiseReduction.cpp}::NRC_ISOLATE_NOISE
@ NRC_ISOLATE_NOISE
Definition: NoiseReduction.cpp:159
anonymous_namespace{NoiseReduction.cpp}::reg
BuiltinEffectsModule::Registration< EffectNoiseReduction > reg
Definition: NoiseReduction.cpp:408
EffectNoiseReduction::Worker::mProgressTrackCount
unsigned mProgressTrackCount
Definition: NoiseReduction.cpp:329
EffectNoiseReduction::Settings::mStepsPerWindowChoice
int mStepsPerWindowChoice
Definition: NoiseReduction.cpp:242
EffectNoiseReduction::Statistics::mSums
FloatVector mSums
Definition: NoiseReduction.cpp:193
EffectNoiseReduction::Worker::Statistics
EffectNoiseReduction::Statistics Statistics
Definition: NoiseReduction.cpp:262
EffectNoiseReduction::Process
bool Process() override
Definition: NoiseReduction.cpp:624
EffectNoiseReduction::Worker::mOneBlockAttack
float mOneBlockAttack
Definition: NoiseReduction.cpp:319
EffectNoiseReduction::Dialog::OnReduceNoise
void OnReduceNoise(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1491
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:422
EffectNoiseReduction::Worker::mBinHigh
size_t mBinHigh
Definition: NoiseReduction.cpp:313
NoiseReduction.h
anonymous_namespace{NoiseReduction.cpp}::DM_N_METHODS
@ DM_N_METHODS
Definition: NoiseReduction.cpp:101
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry
Definition: NoiseReduction.cpp:491
anonymous_namespace{NoiseReduction.cpp}::DM_DEFAULT_METHOD
@ DM_DEFAULT_METHOD
Definition: NoiseReduction.cpp:102
EffectNoiseReduction::EffectNoiseReduction
EffectNoiseReduction()
Definition: NoiseReduction.cpp:410
EffectNoiseReduction::Worker::mDoProfile
const bool mDoProfile
Definition: NoiseReduction.cpp:304
ID_FREQ_SLIDER
@ ID_FREQ_SLIDER
Definition: NoiseReduction.cpp:1196
TrackSpectrumTransformer::DoFinish
bool DoFinish() override
Called after the last call to ProcessWindow().
Definition: SpectrumTransformer.cpp:378
EffectNoiseReduction::Worker::Processor
static bool Processor(SpectrumTransformer &transformer)
Definition: NoiseReduction.cpp:872
EffectNoiseReduction::Worker::Classify
bool Classify(unsigned nWindows, int band)
Definition: NoiseReduction.cpp:961
LoadEffects.h
EffectNoiseReduction::Statistics::mRate
double mRate
Definition: NoiseReduction.cpp:187
EffectNoiseReduction::Settings::WindowSize
size_t WindowSize() const
Definition: NoiseReduction.cpp:219
ID_RADIOBUTTON_RESIDUE
@ ID_RADIOBUTTON_RESIDUE
Definition: NoiseReduction.cpp:1174
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry::name
const wxChar * name
Definition: NoiseReduction.cpp:495
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
EffectNoiseReduction::Worker
Definition: NoiseReduction.cpp:259
wxDialogWrapper
Definition: wxPanelWrapper.h:81
EffectNoiseReduction::Worker::mFreqSmoothingBins
const size_t mFreqSmoothingBins
Definition: NoiseReduction.cpp:310
RESIDUE_CHOICE
#define RESIDUE_CHOICE
Definition: NoiseReduction.cpp:82
EffectNoiseReduction::Statistics::mWindowSize
size_t mWindowSize
Definition: NoiseReduction.cpp:188
anonymous_namespace{NoiseReduction.cpp}::WT_HAMMING_RECTANGULAR
@ WT_HAMMING_RECTANGULAR
Definition: NoiseReduction.cpp:123
EffectNoiseReduction::Worker::mNoiseReductionChoice
const int mNoiseReductionChoice
Definition: NoiseReduction.cpp:315
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
EffectNoiseReduction::Worker::DoFinish
bool DoFinish() override
Called after the last call to ProcessWindow().
Definition: NoiseReduction.cpp:1156
anonymous_namespace{NoiseReduction.cpp}::discriminationMethodInfo
const struct anonymous_namespace{NoiseReduction.cpp}::DiscriminationMethodInfo discriminationMethodInfo[DM_N_METHODS]
anonymous_namespace{NoiseReduction.cpp}::WT_DEFAULT_WINDOW_TYPES
@ WT_DEFAULT_WINDOW_TYPES
Definition: NoiseReduction.cpp:128
EffectNoiseReduction::Worker::mStatistics
Statistics & mStatistics
Definition: NoiseReduction.cpp:307
EffectNoiseReduction::Settings::PrefsIO
bool PrefsIO(bool read)
Definition: NoiseReduction.cpp:523
anonymous_namespace{NoiseReduction.cpp}::controlInfo
const ControlInfo * controlInfo()
Definition: NoiseReduction.cpp:1278
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
EffectNoiseReduction::Worker::mFreqSmoothingScratch
FloatVector mFreqSmoothingScratch
Definition: NoiseReduction.cpp:309
EffectNoiseReduction::Settings::mWindowTypes
int mWindowTypes
Definition: NoiseReduction.cpp:240
EffectNoiseReduction::Worker::mHistoryLen
unsigned mHistoryLen
Definition: NoiseReduction.cpp:326
EffectNoiseReduction::Dialog::OnCancel
void OnCancel(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1499
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
EffectNoiseReduction::Settings::mNoiseGain
double mNoiseGain
Definition: NoiseReduction.cpp:229
anonymous_namespace{NoiseReduction.cpp}::WindowTypesInfo::minSteps
unsigned minSteps
Definition: NoiseReduction.cpp:133
anonymous_namespace{NoiseReduction.cpp}::WT_RECTANGULAR_HANN
@ WT_RECTANGULAR_HANN
Definition: NoiseReduction.cpp:119
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::sliderName
const TranslatableString sliderName
Definition: NoiseReduction.cpp:1268
EffectNoiseReduction::Worker::mNWindowsToExamine
unsigned mNWindowsToExamine
Definition: NoiseReduction.cpp:324
EffectNoiseReduction::Settings::~Settings
~Settings()
Definition: NoiseReduction.cpp:212
Verbatim
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Definition: TranslatableString.h:321
anonymous_namespace{NoiseReduction.cpp}::DM_MEDIAN
@ DM_MEDIAN
Definition: NoiseReduction.cpp:97
EffectNoiseReduction::Settings::Validate
bool Validate(EffectNoiseReduction *effect) const
Definition: NoiseReduction.cpp:590
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::textBoxCaption
const TranslatableString textBoxCaption
Definition: NoiseReduction.cpp:1267
TrapLong
long TrapLong(long x, long min, long max)
Definition: Effect.h:534
anonymous_namespace{NoiseReduction.cpp}::WT_HANN_HANN
@ WT_HANN_HANN
Definition: NoiseReduction.cpp:121
anonymous_namespace{NoiseReduction.cpp}::WindowTypesInfo
Definition: NoiseReduction.cpp:131
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::field
MemberPointer field
Definition: NoiseReduction.cpp:1260
EffectNoiseReduction::Dialog
Dialog used with EffectNoiseReduction.
Definition: NoiseReduction.cpp:346
EffectNoiseReduction::Dialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: NoiseReduction.cpp:1509
Prefs.h
EffectNoiseReduction::Settings::mNewSensitivity
double mNewSensitivity
Definition: NoiseReduction.cpp:227
EffectNoiseReduction::Worker::mBinLow
size_t mBinLow
Definition: NoiseReduction.cpp:312
EffectNoiseReduction::~EffectNoiseReduction
virtual ~EffectNoiseReduction()
Definition: NoiseReduction.cpp:416
EffectNoiseReduction::Settings::mFreqSmoothingBands
double mFreqSmoothingBands
Definition: NoiseReduction.cpp:228
EffectNoiseReduction::Dialog::mbAllowTwiddleSettings
bool mbAllowTwiddleSettings
Definition: NoiseReduction.cpp:390
anonymous_namespace{NoiseReduction.cpp}::WT_HANN_RECTANGULAR
@ WT_HANN_RECTANGULAR
Definition: NoiseReduction.cpp:120
EffectNoiseReduction::Worker::~Worker
~Worker()
Definition: NoiseReduction.cpp:699
anonymous_namespace{NoiseReduction.cpp}::WindowTypes
WindowTypes
Definition: NoiseReduction.cpp:118
EffectNoiseReduction::Dialog::OnPreview
void OnPreview(wxCommandEvent &event) override
Definition: NoiseReduction.cpp:1478
EffectNoiseReduction::mSettings
std::unique_ptr< Settings > mSettings
Definition: NoiseReduction.h:55
EffectType
EffectType
Definition: EffectInterface.h:52
EffectManager.h
settings
static Settings & settings()
Definition: TrackInfo.cpp:87
anonymous_namespace{NoiseReduction.cpp}::WT_BLACKMAN_HANN
@ WT_BLACKMAN_HANN
Definition: NoiseReduction.cpp:122
EffectNoiseReduction::mStatistics
std::unique_ptr< Statistics > mStatistics
Definition: NoiseReduction.h:56
EffectDialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: EffectUI.cpp:1455
EffectNoiseReduction::Dialog::mKeepSignal
wxRadioButton * mKeepSignal
Definition: NoiseReduction.cpp:393
EffectNoiseReduction::Worker::mOneBlockRelease
float mOneBlockRelease
Definition: NoiseReduction.cpp:320
TrackList::Selected
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1396
EffectNoiseReduction::Settings
Definition: NoiseReduction.cpp:209
END_EVENT_TABLE
END_EVENT_TABLE()
EffectNoiseReduction::Dialog::mbHasProfile
bool mbHasProfile
Definition: NoiseReduction.cpp:389
ID_GAIN_SLIDER
@ ID_GAIN_SLIDER
Definition: NoiseReduction.cpp:1182
EffectNoiseReduction::Dialog::m_pEffect
EffectNoiseReduction * m_pEffect
Definition: NoiseReduction.cpp:385
TrackSpectrumTransformer
Subclass of SpectrumTransformer that rewrites a track.
Definition: SpectrumTransformer.h:183
EffectNoiseReduction::Worker::Process
bool Process(TrackList &tracks, double mT0, double mT1)
Definition: NoiseReduction.cpp:703
EffectNoiseReduction::Worker::MyWindow::MyWindow
MyWindow(size_t windowSize)
Definition: NoiseReduction.cpp:275
TrackSpectrumTransformer::Process
bool Process(const WindowProcessor &processor, WaveTrack *track, size_t queueLength, sampleCount start, sampleCount len)
Invokes Start(), ProcessSamples(), and Finish()
Definition: SpectrumTransformer.cpp:341
SpectrumTransformer
Transformer of sample sequences by FFT, coefficient changes, inverse FFT, overlap-add.
Definition: SpectrumTransformer.h:34
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
anonymous_namespace{NoiseReduction.cpp}::readPrefs
void readPrefs(StructureType *structure, const wxString &prefix, const PrefsTableEntry< StructureType, FieldType > *fields, size_t numFields)
Definition: NoiseReduction.cpp:500
EffectNoiseReduction::Dialog::mTempSettings
EffectNoiseReduction::Settings mTempSettings
Definition: NoiseReduction.cpp:387
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::SliderSetting
long SliderSetting(double value) const
Definition: NoiseReduction.cpp:1226
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::ControlInfo
ControlInfo(MemberPointer f, double vMin, double vMax, long sMax, const wxChar *fmt, bool fAsInt, const TranslatableString &caption, const TranslatableString &name)
Definition: NoiseReduction.cpp:1270
FIRST_SLIDER
@ FIRST_SLIDER
Definition: NoiseReduction.cpp:1211
anonymous_namespace{NoiseReduction.cpp}::DEFAULT_WINDOW_SIZE_CHOICE
@ DEFAULT_WINDOW_SIZE_CHOICE
Definition: NoiseReduction.cpp:153
EffectNoiseReduction::Init
bool Init() override
Definition: NoiseReduction.cpp:439