Audacity  3.0.3
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  bool 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  wxWindow &parent, const EffectDialogFactory &, bool forceModal)
451 {
452  // to do: use forceModal correctly
453 
454  // Doesn't use the factory but substitutes its own dialog
455 
456  // We may want to twiddle the levels if we are setting
457  // from an automation dialog
458  return mSettings->PromptUser(this, parent,
459  bool(mStatistics), forceModal);
460 }
461 
463 (EffectNoiseReduction *effect, wxWindow &parent,
464  bool bHasProfile, bool bAllowTwiddleSettings)
465 {
467  (effect, this, &parent, bHasProfile, bAllowTwiddleSettings);
468 
469  dlog.CentreOnParent();
470  dlog.ShowModal();
471 
472  if (dlog.GetReturnCode() == 0)
473  return false;
474 
475  *this = dlog.GetTempSettings();
476  mDoProfile = (dlog.GetReturnCode() == 1);
477 
478  return PrefsIO(false);
479 }
480 
481 namespace {
482  template <typename StructureType, typename FieldType>
484  typedef FieldType (StructureType::*MemberPointer);
485 
487  const wxChar *name;
488  FieldType defaultValue;
489  };
490 
491  template <typename StructureType, typename FieldType>
492  void readPrefs(
493  StructureType *structure, const wxString &prefix,
494  const PrefsTableEntry<StructureType, FieldType> *fields, size_t numFields)
495  {
496  for (size_t ii = 0; ii < numFields; ++ii) {
498  gPrefs->Read(prefix + entry.name, &(structure->*(entry.field)),
499  entry.defaultValue);
500  }
501  }
502 
503  template <typename StructureType, typename FieldType>
505  const StructureType *structure, const wxString &prefix,
506  const PrefsTableEntry<StructureType, FieldType> *fields, size_t numFields)
507  {
508  for (size_t ii = 0; ii < numFields; ++ii) {
510  gPrefs->Write(prefix + entry.name, structure->*(entry.field));
511  }
512  }
513 }
514 
516 {
517  static const double DEFAULT_OLD_SENSITIVITY = 0.0;
518 
519  static const PrefsTableEntry<Settings, double> doubleTable[] = {
520  { &Settings::mNewSensitivity, wxT("Sensitivity"), 6.0 },
521  { &Settings::mNoiseGain, wxT("Gain"), 12.0 },
522  { &Settings::mAttackTime, wxT("AttackTime"), 0.02 },
523  { &Settings::mReleaseTime, wxT("ReleaseTime"), 0.10 },
524  { &Settings::mFreqSmoothingBands, wxT("FreqSmoothing"), 3.0 },
525 
526  // Advanced settings
527  { &Settings::mOldSensitivity, wxT("OldSensitivity"), DEFAULT_OLD_SENSITIVITY },
528  };
529  static auto doubleTableSize = sizeof(doubleTable) / sizeof(doubleTable[0]);
530 
531  static const PrefsTableEntry<Settings, int> intTable[] = {
532  { &Settings::mNoiseReductionChoice, wxT("ReductionChoice"), NRC_REDUCE_NOISE },
533 
534  // Advanced settings
535  { &Settings::mWindowTypes, wxT("WindowTypes"), WT_DEFAULT_WINDOW_TYPES },
538  { &Settings::mMethod, wxT("Method"), DM_DEFAULT_METHOD },
539  };
540  static auto intTableSize = sizeof(intTable) / sizeof(intTable[0]);
541 
542  static const wxString prefix(wxT("/Effects/NoiseReduction/"));
543 
544  if (read) {
545  readPrefs(this, prefix, doubleTable, doubleTableSize);
546  readPrefs(this, prefix, intTable, intTableSize);
547 
548  // Ignore preferences for unavailable options.
549 #if !(defined(RESIDUE_CHOICE) || defined (ISOLATE_CHOICE))
550  mNoiseReductionChoice == NRC_REDUCE_NOISE;
551 #elif !(defined(RESIDUE_CHOICE))
552  if (mNoiseReductionChoice == NRC_LEAVE_RESIDUE)
553  mNoiseReductionChoice = NRC_ISOLATE_NOISE;
554 #elif !(defined(ISOLATE_CHOICE))
555  if (mNoiseReductionChoice == NRC_ISOLATE_NOISE)
556  mNoiseReductionChoice = NRC_LEAVE_RESIDUE;
557 #endif
558 
559 #ifndef ADVANCED_SETTINGS
560  // Initialize all hidden advanced settings to defaults.
561  mWindowTypes = WT_DEFAULT_WINDOW_TYPES;
562  mWindowSizeChoice = DEFAULT_WINDOW_SIZE_CHOICE;
563  mStepsPerWindowChoice = DEFAULT_STEPS_PER_WINDOW_CHOICE;
564  mMethod = DM_DEFAULT_METHOD;
565  mOldSensitivity = DEFAULT_OLD_SENSITIVITY;
566 #endif
567 
568 #ifndef OLD_METHOD_AVAILABLE
569  if (mMethod == DM_OLD_METHOD)
570  mMethod = DM_DEFAULT_METHOD;
571 #endif
572 
573  return true;
574  }
575  else {
576  writePrefs(this, prefix, doubleTable, doubleTableSize);
577  writePrefs(this, prefix, intTable, intTableSize);
578  return gPrefs->Flush();
579  }
580 }
581 
583 {
584  if (StepsPerWindow() < windowTypesInfo[mWindowTypes].minSteps) {
585  effect->Effect::MessageBox(
586  XO("Steps per block are too few for the window types.") );
587  return false;
588  }
589 
590  if (StepsPerWindow() > WindowSize()) {
591  effect->Effect::MessageBox(
592  XO("Steps per block cannot exceed the window size.") );
593  return false;
594  }
595 
596  if (mMethod == DM_MEDIAN && StepsPerWindow() > 4) {
597  effect->Effect::MessageBox(
598  XO(
599 "Median method is not implemented for more than four steps per window.") );
600  return false;
601  }
602 
603  return true;
604 }
605 
607  -> std::unique_ptr<Window>
608 {
609  return std::make_unique<MyWindow>(windowSize);
610 }
611 
613 {
614 }
615 
617 {
618  // This same code will either reduce noise or profile it
619 
620  this->CopyInputTracks(); // Set up mOutputTracks.
621 
622  auto track = * (mOutputTracks->Selected< const WaveTrack >()).begin();
623  if (!track)
624  return false;
625 
626  // Initialize statistics if gathering them, or check for mismatched (advanced)
627  // settings if reducing noise.
628  if (mSettings->mDoProfile) {
629  size_t spectrumSize = 1 + mSettings->WindowSize() / 2;
630  mStatistics = std::make_unique<Statistics>
631  (spectrumSize, track->GetRate(), mSettings->mWindowTypes);
632  }
633  else if (mStatistics->mWindowSize != mSettings->WindowSize()) {
634  // possible only with advanced settings
636  XO("You must specify the same window size for steps 1 and 2.") );
637  return false;
638  }
639  else if (mStatistics->mWindowTypes != mSettings->mWindowTypes) {
640  // A warning only
642  XO("Warning: window types are not the same as for profiling.") );
643  }
644 
645  eWindowFunctions inWindowType, outWindowType;
646  switch (mSettings->mWindowTypes) {
647  case WT_RECTANGULAR_HANN:
648  inWindowType = eWinFuncRectangular;
649  outWindowType = eWinFuncHann;
650  break;
651  case WT_HANN_RECTANGULAR:
652  inWindowType = eWinFuncHann;
653  outWindowType = eWinFuncRectangular;
654  break;
655  case WT_BLACKMAN_HANN:
656  inWindowType = eWinFuncBlackman;
657  outWindowType = eWinFuncHann;
658  break;
660  inWindowType = eWinFuncHamming;
661  outWindowType = eWinFuncRectangular;
662  break;
663  case WT_HAMMING_HANN:
664  inWindowType = eWinFuncHamming;
665  outWindowType = eWinFuncHann;
666  break;
667  default:
668  wxASSERT(false);
669  [[fallthrough]] ;
670  case WT_HANN_HANN:
671  inWindowType = outWindowType = eWinFuncHann;
672  break;
673  }
674  Worker worker{ inWindowType, outWindowType,
675  *this, *mSettings, *mStatistics
676 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
677  , mF0, mF1
678 #endif
679  };
680  bool bGoodResult = worker.Process(*mOutputTracks, mT0, mT1);
681  if (mSettings->mDoProfile) {
682  if (bGoodResult)
683  mSettings->mDoProfile = false; // So that "repeat last effect" will reduce noise
684  else
685  mStatistics.reset(); // So that profiling must be done again before noise reduction
686  }
687  this->ReplaceProcessedTracks(bGoodResult);
688  return bGoodResult;
689 }
690 
692 {
693 }
694 
696  TrackList &tracks, double inT0, double inT1)
697 {
698  mProgressTrackCount = 0;
699  for ( auto track : tracks.Selected< WaveTrack >() ) {
700  mProgressWindowCount = 0;
701  if (track->GetRate() != mStatistics.mRate) {
702  if (mDoProfile)
703  mEffect.Effect::MessageBox(
704  XO("All noise profile data must have the same sample rate.") );
705  else
706  mEffect.Effect::MessageBox(
707  XO(
708 "The sample rate of the noise profile must match that of the sound to be processed.") );
709  return false;
710  }
711 
712  double trackStart = track->GetStartTime();
713  double trackEnd = track->GetEndTime();
714  double t0 = std::max(trackStart, inT0);
715  double t1 = std::min(trackEnd, inT1);
716 
717  if (t1 > t0) {
718  auto start = track->TimeToLongSamples(t0);
719  auto end = track->TimeToLongSamples(t1);
720  const auto len = end - start;
721  mLen = len;
722  const auto extra = (mStepsPerWindow - 1) * mStepSize;
723  // Adjust denominator for presence or absence of padding,
724  // which makes the number of windows visited either more or less
725  // than the number of window steps in the data.
726  if (mDoProfile)
727  mLen -= extra;
728  else
729  mLen += extra;
730 
732  Processor, track, mHistoryLen, start, len ))
733  return false;
734  }
735  ++mProgressTrackCount;
736  }
737 
738  if (mDoProfile) {
739  if (mStatistics.mTotalWindows == 0) {
740  mEffect.Effect::MessageBox(XO("Selected noise profile is too short."));
741  return false;
742  }
743  }
744 
745  return true;
746 }
747 
749 {
750  // Given an array of gain mutipliers, average them
751  // GEOMETRICALLY. Don't multiply and take nth root --
752  // that may quickly cause underflows. Instead, average the logs.
753 
754  if (mFreqSmoothingBins == 0)
755  return;
756 
757  {
758  auto pScratch = mFreqSmoothingScratch.data();
759  std::fill(pScratch, pScratch + mSpectrumSize, 0.0f);
760  }
761 
762  for (size_t ii = 0; ii < mSpectrumSize; ++ii)
763  gains[ii] = log(gains[ii]);
764 
765  // ii must be signed
766  for (int ii = 0; ii < (int)mSpectrumSize; ++ii) {
767  const int j0 = std::max(0, ii - (int)mFreqSmoothingBins);
768  const int j1 = std::min(mSpectrumSize - 1, ii + mFreqSmoothingBins);
769  for(int jj = j0; jj <= j1; ++jj) {
770  mFreqSmoothingScratch[ii] += gains[jj];
771  }
772  mFreqSmoothingScratch[ii] /= (j1 - j0 + 1);
773  }
774 
775  for (size_t ii = 0; ii < mSpectrumSize; ++ii)
776  gains[ii] = exp(mFreqSmoothingScratch[ii]);
777 }
778 
780  eWindowFunctions outWindowType,
781  EffectNoiseReduction &effect,
782  const Settings &settings, Statistics &statistics
783 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
784  , double f0, double f1
785 #endif
786 )
787 : TrackSpectrumTransformer{ !settings.mDoProfile, inWindowType, outWindowType,
790 }
791 , mDoProfile{ settings.mDoProfile }
792 
793 , mEffect{ effect }
794 , mStatistics{ statistics }
795 
796 , mFreqSmoothingScratch( mSpectrumSize )
797 , mFreqSmoothingBins{ size_t(std::max(0.0, settings.mFreqSmoothingBands)) }
798 , mBinLow{ 0 }
799 , mBinHigh{ mSpectrumSize }
800 
801 , mNoiseReductionChoice{ settings.mNoiseReductionChoice }
802 , mMethod{ settings.mMethod }
803 
804 // Sensitivity setting is a base 10 log, turn it into a natural log
805 , mNewSensitivity{ settings.mNewSensitivity * log(10.0) }
806 {
807  const auto sampleRate = mStatistics.mRate;
808 
809 #ifdef EXPERIMENTAL_SPECTRAL_EDITING
810  {
811  // mBinLow is inclusive, mBinHigh is exclusive, of
812  // the range of frequencies to affect. Include any
813  // bin that partly overlaps the selected range of frequencies.
814  const double bin = sampleRate / mWindowSize;
815  if (f0 >= 0.0 )
816  mBinLow = floor(f0 / bin);
817  if (f1 >= 0.0)
818  mBinHigh = ceil(f1 / bin);
819  }
820 #endif
821 
822  const double noiseGain = -settings.mNoiseGain;
823  const unsigned nAttackBlocks = 1 + (int)(settings.mAttackTime * sampleRate / mStepSize);
824  const unsigned nReleaseBlocks = 1 + (int)(settings.mReleaseTime * sampleRate / mStepSize);
825  // Applies to amplitudes, divide by 20:
826  mNoiseAttenFactor = DB_TO_LINEAR(noiseGain);
827  // Apply to gain factors which apply to amplitudes, divide by 20:
828  mOneBlockAttack = DB_TO_LINEAR(noiseGain / nAttackBlocks);
829  mOneBlockRelease = DB_TO_LINEAR(noiseGain / nReleaseBlocks);
830  // Applies to power, divide by 10:
831  mOldSensitivityFactor = pow(10.0, settings.mOldSensitivity / 10.0);
832 
833  mNWindowsToExamine = (mMethod == DM_OLD_METHOD)
834  ? std::max(2, (int)(minSignalTime * sampleRate / mStepSize))
835  : 1 + mStepsPerWindow;
836 
837  mCenter = mNWindowsToExamine / 2;
838  wxASSERT(mCenter >= 1); // release depends on this assumption
839 
840  if (mDoProfile)
841 #ifdef OLD_METHOD_AVAILABLE
842  mHistoryLen = mNWindowsToExamine;
843 #else
844  mHistoryLen = 1;
845 #endif
846  else {
847  // Allow long enough queue for sufficient inspection of the middle
848  // and for attack processing
849  // See ReduceNoise()
850  mHistoryLen = std::max(mNWindowsToExamine, mCenter + nAttackBlocks);
851  }
852 }
853 
855 {
856  for (size_t ii = 0, nn = TotalQueueSize(); ii < nn; ++ii) {
857  MyWindow &record = NthWindow(ii);
858  std::fill(record.mSpectrums.begin(), record.mSpectrums.end(), 0.0);
859  std::fill(record.mGains.begin(), record.mGains.end(), mNoiseAttenFactor);
860  }
862 }
863 
865 {
866  auto &worker = static_cast<Worker &>(transformer);
867  // Compute power spectrum in the newest window
868  {
869  MyWindow &record = worker.NthWindow(0);
870  float *pSpectrum = &record.mSpectrums[0];
871  const double dc = record.mRealFFTs[0];
872  *pSpectrum++ = dc * dc;
873  float *pReal = &record.mRealFFTs[1], *pImag = &record.mImagFFTs[1];
874  for (size_t nn = worker.mSpectrumSize - 2; nn--;) {
875  const double re = *pReal++, im = *pImag++;
876  *pSpectrum++ = re * re + im * im;
877  }
878  const double nyquist = record.mImagFFTs[0];
879  *pSpectrum = nyquist * nyquist;
880  }
881 
882  if (worker.mDoProfile)
883  worker.GatherStatistics();
884  else
885  worker.ReduceNoise();
886 
887  // Update the Progress meter, let user cancel
888  return !worker.mEffect.TrackProgress(worker.mProgressTrackCount,
889  std::min(1.0,
890  ((++worker.mProgressWindowCount).as_double() * worker.mStepSize)
891  / worker.mLen.as_double()));
892 }
893 
895 {
896  const auto windows = mStatistics.mTrackWindows;
897 
898  // Combine averages in case of multiple profile tracks.
899  if (windows) {
900  const auto multiplier = mStatistics.mTotalWindows;
901  const auto denom = windows + multiplier;
902  for (size_t ii = 0, nn = mStatistics.mMeans.size(); ii < nn; ++ii) {
903  auto &mean = mStatistics.mMeans[ii];
904  auto &sum = mStatistics.mSums[ii];
905  mean = (mean * multiplier + sum) / denom;
906  // Reset for next track
907  sum = 0;
908  }
909  // Reset for next track
910  mStatistics.mTrackWindows = 0;
911  mStatistics.mTotalWindows = denom;
912  }
913 }
914 
916 {
917  ++mStatistics.mTrackWindows;
918 
919  {
920  // NEW statistics
921  auto pPower = NthWindow(0).mSpectrums.data();
922  auto pSum = mStatistics.mSums.data();
923  for (size_t jj = 0; jj < mSpectrumSize; ++jj) {
924  *pSum++ += *pPower++;
925  }
926  }
927 
928 #ifdef OLD_METHOD_AVAILABLE
929  // The noise threshold for each frequency is the maximum
930  // level achieved at that frequency for a minimum of
931  // mMinSignalBlocks blocks in a row - the max of a min.
932 
933  auto finish = mHistoryLen;
934 
935  {
936  // old statistics
937  auto pPower = NthWindow(0).mSpectrums.data();
938  auto pThreshold = mStatistics.mNoiseThreshold.data();
939  for (size_t jj = 0; jj < mSpectrumSize; ++jj) {
940  float min = *pPower++;
941  for (unsigned ii = 1; ii < finish; ++ii)
942  min = std::min(min, NthWindow(ii).mSpectrums[jj]);
943  *pThreshold = std::max(*pThreshold, min);
944  ++pThreshold;
945  }
946  }
947 #endif
948 }
949 
950 // Return true iff the given band of the "center" window looks like noise.
951 // Examine the band in a few neighboring windows to decide.
952 inline
953 bool EffectNoiseReduction::Worker::Classify(unsigned nWindows, int band)
954 {
955  switch (mMethod) {
956 #ifdef OLD_METHOD_AVAILABLE
957  case DM_OLD_METHOD:
958  {
959  float min = NthWindow(0).mSpectrums[band];
960  for (unsigned ii = 1; ii < nWindows; ++ii)
961  min = std::min(min, NthWindow(ii).mSpectrums[band]);
962  return
963  min <= mOldSensitivityFactor * mStatistics.mNoiseThreshold[band];
964  }
965 #endif
966  // New methods suppose an exponential distribution of power values
967  // in the noise; NEW sensitivity (which is nonnegative) is meant to be
968  // the negative of a log of probability (so the log is nonpositive)
969  // that noise strays above the threshold. Call that probability
970  // 1 - F. The quantile function of an exponential distribution is
971  // - log (1 - F) * mean. Thus simply multiply mean by sensitivity
972  // to get the threshold.
973  case DM_MEDIAN:
974  // This method examines the window and all other windows
975  // whose centers lie on or between its boundaries, and takes a median, to
976  // avoid being fooled by up and down excursions into
977  // either the mistake of classifying noise as not noise
978  // (leaving a musical noise chime), or the opposite
979  // (distorting the signal with a drop out).
980  if (nWindows <= 3)
981  // No different from second greatest.
982  goto secondGreatest;
983  else if (nWindows <= 5)
984  {
985  float greatest = 0.0, second = 0.0, third = 0.0;
986  for (unsigned ii = 0; ii < nWindows; ++ii) {
987  const float power = NthWindow(ii).mSpectrums[band];
988  if (power >= greatest)
989  third = second, second = greatest, greatest = power;
990  else if (power >= second)
991  third = second, second = power;
992  else if (power >= third)
993  third = power;
994  }
995  return third <= mNewSensitivity * mStatistics.mMeans[band];
996  }
997  else {
998  // not implemented
999  wxASSERT(false);
1000  return true;
1001  }
1002  secondGreatest:
1003  case DM_SECOND_GREATEST:
1004  {
1005  // This method just throws out the high outlier. It
1006  // should be less prone to distortions and more prone to
1007  // chimes.
1008  float greatest = 0.0, second = 0.0;
1009  for (unsigned ii = 0; ii < nWindows; ++ii) {
1010  const float power = NthWindow(ii).mSpectrums[band];
1011  if (power >= greatest)
1012  second = greatest, greatest = power;
1013  else if (power >= second)
1014  second = power;
1015  }
1016  return second <= mNewSensitivity * mStatistics.mMeans[band];
1017  }
1018  default:
1019  wxASSERT(false);
1020  return true;
1021  }
1022 }
1023 
1025 {
1026  auto historyLen = CurrentQueueSize();
1027  auto nWindows = std::min<unsigned>(mNWindowsToExamine, historyLen);
1028 
1029  if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
1030  {
1031  MyWindow &record = NthWindow(0);
1032  // Default all gains to the reduction factor,
1033  // until we decide to raise some of them later
1034  float *pGain = &record.mGains[0];
1035  std::fill(pGain, pGain + mSpectrumSize, mNoiseAttenFactor);
1036  }
1037 
1038  // Raise the gain for elements in the center of the sliding history
1039  // or, if isolating noise, zero out the non-noise
1040  if (nWindows > mCenter)
1041  {
1042  auto pGain = NthWindow(mCenter).mGains.data();
1043  if (mNoiseReductionChoice == NRC_ISOLATE_NOISE) {
1044  // All above or below the selected frequency range is non-noise
1045  std::fill(pGain, pGain + mBinLow, 0.0f);
1046  std::fill(pGain + mBinHigh, pGain + mSpectrumSize, 0.0f);
1047  pGain += mBinLow;
1048  for (size_t jj = mBinLow; jj < mBinHigh; ++jj) {
1049  const bool isNoise = Classify(nWindows, jj);
1050  *pGain++ = isNoise ? 1.0 : 0.0;
1051  }
1052  }
1053  else {
1054  // All above or below the selected frequency range is non-noise
1055  std::fill(pGain, pGain + mBinLow, 1.0f);
1056  std::fill(pGain + mBinHigh, pGain + mSpectrumSize, 1.0f);
1057  pGain += mBinLow;
1058  for (size_t jj = mBinLow; jj < mBinHigh; ++jj) {
1059  const bool isNoise = Classify(nWindows, jj);
1060  if (!isNoise)
1061  *pGain = 1.0;
1062  ++pGain;
1063  }
1064  }
1065  }
1066 
1067  if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
1068  {
1069  // In each direction, define an exponential decay of gain from the
1070  // center; make actual gains the maximum of mNoiseAttenFactor, and
1071  // the decay curve, and their prior values.
1072 
1073  // First, the attack, which goes backward in time, which is,
1074  // toward higher indices in the queue.
1075  for (size_t jj = 0; jj < mSpectrumSize; ++jj) {
1076  for (unsigned ii = mCenter + 1; ii < historyLen; ++ii) {
1077  const float minimum =
1078  std::max(mNoiseAttenFactor,
1079  NthWindow(ii - 1).mGains[jj] * mOneBlockAttack);
1080  float &gain = NthWindow(ii).mGains[jj];
1081  if (gain < minimum)
1082  gain = minimum;
1083  else
1084  // We can stop now, our attack curve is intersecting
1085  // the release curve of some window previously processed.
1086  break;
1087  }
1088  }
1089 
1090  // Now, release. We need only look one window ahead. This part will
1091  // be visited again when we examine the next window, and
1092  // carry the decay further.
1093  {
1094  auto pNextGain = NthWindow(mCenter - 1).mGains.data();
1095  auto pThisGain = NthWindow(mCenter).mGains.data();
1096  for (auto nn = mSpectrumSize; nn--;) {
1097  *pNextGain =
1098  std::max(*pNextGain,
1099  std::max(mNoiseAttenFactor,
1100  *pThisGain++ * mOneBlockRelease));
1101  ++pNextGain;
1102  }
1103  }
1104  }
1105 
1106 
1107  if (QueueIsFull()) {
1108  auto &record = NthWindow(historyLen - 1); // end of the queue
1109  const auto last = mSpectrumSize - 1;
1110 
1111  if (mNoiseReductionChoice != NRC_ISOLATE_NOISE)
1112  // Apply frequency smoothing to output gain
1113  // Gains are not less than mNoiseAttenFactor
1114  ApplyFreqSmoothing(record.mGains);
1115 
1116  // Apply gain to FFT
1117  {
1118  const float *pGain = &record.mGains[1];
1119  float *pReal = &record.mRealFFTs[1];
1120  float *pImag = &record.mImagFFTs[1];
1121  auto nn = mSpectrumSize - 2;
1122  if (mNoiseReductionChoice == NRC_LEAVE_RESIDUE) {
1123  for (; nn--;) {
1124  // Subtract the gain we would otherwise apply from 1, and
1125  // negate that to flip the phase.
1126  const double gain = *pGain++ - 1.0;
1127  *pReal++ *= gain;
1128  *pImag++ *= gain;
1129  }
1130  record.mRealFFTs[0] *= (record.mGains[0] - 1.0);
1131  // The Fs/2 component is stored as the imaginary part of the DC component
1132  record.mImagFFTs[0] *= (record.mGains[last] - 1.0);
1133  }
1134  else {
1135  for (; nn--;) {
1136  const double gain = *pGain++;
1137  *pReal++ *= gain;
1138  *pImag++ *= gain;
1139  }
1140  record.mRealFFTs[0] *= record.mGains[0];
1141  // The Fs/2 component is stored as the imaginary part of the DC component
1142  record.mImagFFTs[0] *= record.mGains[last];
1143  }
1144  }
1145  }
1146 }
1147 
1149 {
1150  if (mDoProfile)
1151  FinishTrackStatistics();
1153 }
1154 
1155 //----------------------------------------------------------------------------
1156 // EffectNoiseReduction::Dialog
1157 //----------------------------------------------------------------------------
1158 
1159 enum {
1162 #ifdef ISOLATE_CHOICE
1164 #endif
1165 #ifdef RESIDUE_CHOICE
1167 #endif
1168 
1169 #ifdef ADVANCED_SETTINGS
1170  ID_CHOICE_METHOD,
1171 #endif
1172 
1173  // Slider/text pairs
1176 
1179 
1180 #ifdef ATTACK_AND_RELEASE
1181  ID_ATTACK_TIME_SLIDER,
1182  ID_ATTACK_TIME_TEXT,
1183 
1184  ID_RELEASE_TIME_SLIDER,
1185  ID_RELEASE_TIME_TEXT,
1186 #endif
1187 
1190 
1192 
1193 #ifdef ADVANCED_SETTINGS
1194  ID_OLD_SENSITIVITY_SLIDER = END_OF_BASIC_SLIDERS,
1195  ID_OLD_SENSITIVITY_TEXT,
1196 
1197  END_OF_ADVANCED_SLIDERS,
1198  END_OF_SLIDERS = END_OF_ADVANCED_SLIDERS,
1199 #else
1201 #endif
1202 
1204 };
1205 
1206 namespace {
1207 
1208 struct ControlInfo {
1210 
1211  double Value(long sliderSetting) const
1212  {
1213  return
1214  valueMin +
1215  (double(sliderSetting) / sliderMax) * (valueMax - valueMin);
1216  }
1217 
1218  long SliderSetting(double value) const
1219  {
1220  return TrapLong(
1221  0.5 + sliderMax * (value - valueMin) / (valueMax - valueMin),
1222  0, sliderMax);
1223  }
1224 
1225  wxString Text(double value) const
1226  {
1227  if (formatAsInt)
1228  return wxString::Format(format, (int)(value));
1229  else
1230  return wxString::Format(format, value);
1231  }
1232 
1233  void CreateControls(int id, ShuttleGui &S) const
1234  {
1235  wxTextCtrl *const text = S.Id(id + 1)
1236  .Validator<FloatingPointValidator<double>>(
1237  formatAsInt ? 0 : 2,
1238  nullptr,
1239  NumValidatorStyle::DEFAULT,
1240  valueMin, valueMax
1241  )
1242  .AddTextBox(textBoxCaption, wxT(""), 0);
1243 
1244  wxSlider *const slider =
1245  S.Id(id)
1246  .Name( sliderName )
1247  .Style(wxSL_HORIZONTAL)
1248  .MinSize( { 150, -1 } )
1249  .AddSlider( {}, 0, sliderMax);
1250  }
1251 
1253  double valueMin;
1254  double valueMax;
1256  // (valueMin - valueMax) / sliderMax is the value increment of the slider
1257  const wxChar* format;
1261 
1262  ControlInfo(MemberPointer f, double vMin, double vMax, long sMax, const wxChar* fmt, bool fAsInt,
1263  const TranslatableString &caption, const TranslatableString &name)
1264  : field(f), valueMin(vMin), valueMax(vMax), sliderMax(sMax), format(fmt), formatAsInt(fAsInt)
1265  , textBoxCaption(caption), sliderName(name)
1266  {
1267  }
1268 };
1269 
1271  static const ControlInfo table[] = {
1273  0.0, 48.0, 48, wxT("%d"), true,
1274  XXO("&Noise reduction (dB):"), XO("Noise reduction")),
1276  0.0, 24.0, 48, wxT("%.2f"), false,
1277  XXO("&Sensitivity:"), XO("Sensitivity")),
1278 #ifdef ATTACK_AND_RELEASE
1280  0, 1.0, 100, wxT("%.2f"), false,
1281  XXO("Attac&k time (secs):"), XO("Attack time")),
1283  0, 1.0, 100, wxT("%.2f"), false,
1284  XXO("R&elease time (secs):"), XO("Release time")),
1285 #endif
1287  0, 12, 12, wxT("%d"), true,
1288  XXO("&Frequency smoothing (bands):"), XO("Frequency smoothing")),
1289 
1290 #ifdef ADVANCED_SETTINGS
1292  -20.0, 20.0, 4000, wxT("%.2f"), false,
1293  XXO("Sensiti&vity (dB):"), XO("Old Sensitivity")),
1294  // add here
1295 #endif
1296  };
1297 
1298 return table;
1299 }
1300 
1301 } // namespace
1302 
1303 
1310 
1312 #ifdef ISOLATE_CHOICE
1314 #endif
1315 #ifdef RESIDUE_CHOICE
1317 #endif
1318 
1319 #ifdef ADVANCED_SETTINGS
1320  EVT_CHOICE(ID_CHOICE_METHOD, EffectNoiseReduction::Dialog::OnMethodChoice)
1321 #endif
1322 
1325 
1328 
1331 
1332 #ifdef ATTACK_AND_RELEASE
1333  EVT_SLIDER(ID_ATTACK_TIME_SLIDER, EffectNoiseReduction::Dialog::OnSlider)
1334  EVT_TEXT(ID_ATTACK_TIME_TEXT, EffectNoiseReduction::Dialog::OnText)
1335 
1336  EVT_SLIDER(ID_RELEASE_TIME_SLIDER, EffectNoiseReduction::Dialog::OnSlider)
1337  EVT_TEXT(ID_RELEASE_TIME_TEXT, EffectNoiseReduction::Dialog::OnText)
1338 #endif
1339 
1340 
1341 #ifdef ADVANCED_SETTINGS
1342  EVT_SLIDER(ID_OLD_SENSITIVITY_SLIDER, EffectNoiseReduction::Dialog::OnSlider)
1343  EVT_TEXT(ID_OLD_SENSITIVITY_TEXT, EffectNoiseReduction::Dialog::OnText)
1344 #endif
1346 
1348 (EffectNoiseReduction *effect,
1350  wxWindow *parent, bool bHasProfile, bool bAllowTwiddleSettings)
1351  : EffectDialog( parent, XO("Noise Reduction"), EffectTypeProcess,wxDEFAULT_DIALOG_STYLE, eHelpButton )
1352  , m_pEffect(effect)
1353  , m_pSettings(settings) // point to
1354  , mTempSettings(*settings) // copy
1355  , mbHasProfile(bHasProfile)
1356  , mbAllowTwiddleSettings(bAllowTwiddleSettings)
1357  // NULL out the control members until the controls are created.
1358  , mKeepSignal(NULL)
1359 #ifdef ISOLATE_CHOICE
1360  , mKeepNoise(NULL)
1361 #endif
1362 #ifdef RESIDUE_CHOICE
1363  , mResidue(NULL)
1364 #endif
1365 {
1367 
1368  wxButton *const pButtonPreview =
1369  (wxButton *)wxWindow::FindWindowById(ID_EFFECT_PREVIEW, this);
1370  wxButton *const pButtonReduceNoise =
1371  (wxButton *)wxWindow::FindWindowById(wxID_OK, this);
1372 
1373  if (mbHasProfile || mbAllowTwiddleSettings) {
1374  pButtonPreview->Enable(!mbAllowTwiddleSettings);
1375  pButtonReduceNoise->SetFocus();
1376  }
1377  else {
1378  pButtonPreview->Enable(false);
1379  pButtonReduceNoise->Enable(false);
1380  }
1381 }
1382 
1384 {
1385  // If Isolate is chosen, disable controls that define
1386  // "what to do with noise" rather than "what is noise."
1387  // Else, enable them.
1388  // This does NOT include sensitivity, NEW or old, nor
1389  // the choice of window functions, size, or step.
1390  // The method choice is not included, because it affects
1391  // which sensitivity slider is operative, and that is part
1392  // of what defines noise.
1393 
1394  static const int toDisable[] = {
1396  ID_GAIN_TEXT,
1397 
1399  ID_FREQ_TEXT,
1400 
1401 #ifdef ATTACK_AND_RELEASE
1402  ID_ATTACK_TIME_SLIDER,
1403  ID_ATTACK_TIME_TEXT,
1404 
1405  ID_RELEASE_TIME_SLIDER,
1406  ID_RELEASE_TIME_TEXT,
1407 #endif
1408  };
1409  static const auto nToDisable = sizeof(toDisable) / sizeof(toDisable[0]);
1410 
1411  bool bIsolating =
1412 #ifdef ISOLATE_CHOICE
1413  mKeepNoise->GetValue();
1414 #else
1415  false;
1416 #endif
1417  for (auto ii = nToDisable; ii--;)
1418  wxWindow::FindWindowById(toDisable[ii], this)->Enable(!bIsolating);
1419 }
1420 
1421 #ifdef ADVANCED_SETTINGS
1422 void EffectNoiseReduction::Dialog::EnableDisableSensitivityControls()
1423 {
1424  wxChoice *const pChoice =
1425  static_cast<wxChoice*>(wxWindow::FindWindowById(ID_CHOICE_METHOD, this));
1426  const bool bOldMethod =
1427  pChoice->GetSelection() == DM_OLD_METHOD;
1428  wxWindow::FindWindowById(ID_OLD_SENSITIVITY_SLIDER, this)->Enable(bOldMethod);
1429  wxWindow::FindWindowById(ID_OLD_SENSITIVITY_TEXT, this)->Enable(bOldMethod);
1430  wxWindow::FindWindowById(ID_NEW_SENSITIVITY_SLIDER, this)->Enable(!bOldMethod);
1431  wxWindow::FindWindowById(ID_NEW_SENSITIVITY_TEXT, this)->Enable(!bOldMethod);
1432 }
1433 #endif
1434 
1435 void EffectNoiseReduction::Dialog::OnGetProfile(wxCommandEvent & WXUNUSED(event))
1436 {
1437  // Project has not be changed so skip pushing state
1439 
1440  if (!TransferDataFromWindow())
1441  return;
1442 
1443  // Return code distinguishes this first step from the actual effect
1444  EndModal(1);
1445 }
1446 
1447 // This handles the whole radio group
1448 void EffectNoiseReduction::Dialog::OnNoiseReductionChoice( wxCommandEvent & WXUNUSED(event))
1449 {
1450  if (mKeepSignal->GetValue())
1451  mTempSettings.mNoiseReductionChoice = NRC_REDUCE_NOISE;
1452 #ifdef ISOLATE_CHOICE
1453  else if (mKeepNoise->GetValue())
1454  mTempSettings.mNoiseReductionChoice = NRC_ISOLATE_NOISE;
1455 #endif
1456 #ifdef RESIDUE_CHOICE
1457  else
1458  mTempSettings.mNoiseReductionChoice = NRC_LEAVE_RESIDUE;
1459 #endif
1460  DisableControlsIfIsolating();
1461 }
1462 
1463 #ifdef ADVANCED_SETTINGS
1464 void EffectNoiseReduction::Dialog::OnMethodChoice(wxCommandEvent &)
1465 {
1466  EnableDisableSensitivityControls();
1467 }
1468 #endif
1469 
1470 void EffectNoiseReduction::Dialog::OnPreview(wxCommandEvent & WXUNUSED(event))
1471 {
1472  if (!TransferDataFromWindow())
1473  return;
1474 
1475  // Save & restore parameters around Preview, because we didn't do OK.
1476  auto cleanup = valueRestorer( *m_pSettings );
1477  *m_pSettings = mTempSettings;
1478  m_pSettings->mDoProfile = false;
1479 
1480  m_pEffect->Preview( false );
1481 }
1482 
1483 void EffectNoiseReduction::Dialog::OnReduceNoise( wxCommandEvent & WXUNUSED(event))
1484 {
1485  if (!TransferDataFromWindow())
1486  return;
1487 
1488  EndModal(2);
1489 }
1490 
1491 void EffectNoiseReduction::Dialog::OnCancel(wxCommandEvent & WXUNUSED(event))
1492 {
1493  EndModal(0);
1494 }
1495 
1496 void EffectNoiseReduction::Dialog::OnHelp(wxCommandEvent & WXUNUSED(event))
1497 {
1498  HelpSystem::ShowHelp(this, "Noise_Reduction", true);
1499 }
1500 
1502 {
1503  S.StartStatic(XO("Step 1"));
1504  {
1505  S.AddVariableText(XO(
1506 "Select a few seconds of just noise so Audacity knows what to filter out,\nthen click Get Noise Profile:"));
1507  //m_pButton_GetProfile =
1508  S.Id(ID_BUTTON_GETPROFILE).AddButton(XXO("&Get Noise Profile"));
1509  }
1510  S.EndStatic();
1511 
1512  S.StartStatic(XO("Step 2"));
1513  {
1514  S.AddVariableText(XO(
1515 "Select all of the audio you want filtered, choose how much noise you want\nfiltered out, and then click 'OK' to reduce noise.\n"));
1516 
1517  S.StartMultiColumn(3, wxEXPAND);
1518  S.SetStretchyCol(2);
1519  {
1520  for (int id = FIRST_SLIDER; id < END_OF_BASIC_SLIDERS; id += 2) {
1521  const ControlInfo &info = controlInfo()[(id - FIRST_SLIDER) / 2];
1522  info.CreateControls(id, S);
1523  }
1524  }
1525  S.EndMultiColumn();
1526 
1527  S.StartMultiColumn(
1528  2
1529 #ifdef RESIDUE_CHOICE
1530  +1
1531 #endif
1532 #ifdef ISOLATE_CHOICE
1533  +1
1534 #endif
1535  ,
1536  wxALIGN_CENTER_HORIZONTAL);
1537  {
1538  S.AddPrompt(XXO("Noise:"));
1539  mKeepSignal = S.Id(ID_RADIOBUTTON_KEEPSIGNAL)
1540  /* i18n-hint: Translate differently from "Residue" ! */
1541  .AddRadioButton(XXO("Re&duce"));
1542 #ifdef ISOLATE_CHOICE
1543  mKeepNoise = S.Id(ID_RADIOBUTTON_KEEPNOISE)
1544  .AddRadioButtonToGroup(XXO("&Isolate"));
1545 #endif
1546 #ifdef RESIDUE_CHOICE
1547  mResidue = S.Id(ID_RADIOBUTTON_RESIDUE)
1548  /* i18n-hint: Means the difference between effect and original sound. Translate differently from "Reduce" ! */
1549  .AddRadioButtonToGroup(XXO("Resid&ue"));
1550 #endif
1551  }
1552  S.EndMultiColumn();
1553  }
1554  S.EndStatic();
1555 
1556 
1557 #ifdef ADVANCED_SETTINGS
1558  S.StartStatic(XO("Advanced Settings"));
1559  {
1560  S.StartMultiColumn(2);
1561  {
1562  S.TieChoice(XXO("&Window types:"),
1563  mTempSettings.mWindowTypes,
1564  []{
1565  TranslatableStrings windowTypeChoices;
1566  for (size_t ii = 0; ii < WT_N_WINDOW_TYPES; ++ii)
1567  windowTypeChoices.push_back(windowTypesInfo[ii].name);
1568  return windowTypeChoices;
1569  }()
1570  );
1571 
1572  S.TieChoice(XXO("Window si&ze:"),
1573  mTempSettings.mWindowSizeChoice,
1574  {
1575  XO("8") ,
1576  XO("16") ,
1577  XO("32") ,
1578  XO("64") ,
1579  XO("128") ,
1580  XO("256") ,
1581  XO("512") ,
1582  XO("1024") ,
1583  XO("2048 (default)") ,
1584  XO("4096") ,
1585  XO("8192") ,
1586  XO("16384") ,
1587  }
1588  );
1589 
1590  S.TieChoice(XXO("S&teps per window:"),
1591  mTempSettings.mStepsPerWindowChoice,
1592  {
1593  XO("2") ,
1594  XO("4 (default)") ,
1595  XO("8") ,
1596  XO("16") ,
1597  XO("32") ,
1598  XO("64") ,
1599  }
1600  );
1601 
1602  S.Id(ID_CHOICE_METHOD)
1603  .TieChoice(XXO("Discrimination &method:"),
1604  mTempSettings.mMethod,
1605  []{
1606  TranslatableStrings methodChoices;
1607  auto nn = DM_N_METHODS;
1608 #ifndef OLD_METHOD_AVAILABLE
1609  --nn;
1610 #endif
1611  for (auto ii = 0; ii < nn; ++ii)
1612  methodChoices.push_back(discriminationMethodInfo[ii].name);
1613  return methodChoices;
1614  }());
1615  }
1616  S.EndMultiColumn();
1617 
1618  S.StartMultiColumn(3, wxEXPAND);
1619  S.SetStretchyCol(2);
1620  {
1621  for (int id = END_OF_BASIC_SLIDERS; id < END_OF_ADVANCED_SLIDERS; id += 2) {
1622  const ControlInfo &info = controlInfo()[(id - FIRST_SLIDER) / 2];
1623  info.CreateControls(id, S);
1624  }
1625  }
1626  S.EndMultiColumn();
1627  }
1628  S.EndStatic();
1629 #endif
1630 }
1631 
1633 {
1634  // Do the choice controls:
1636  return false;
1637 
1638  for (int id = FIRST_SLIDER; id < END_OF_SLIDERS; id += 2) {
1639  wxSlider* slider =
1640  static_cast<wxSlider*>(wxWindow::FindWindowById(id, this));
1641  wxTextCtrl* text =
1642  static_cast<wxTextCtrl*>(wxWindow::FindWindowById(id + 1, this));
1643  const ControlInfo &info = controlInfo()[(id - FIRST_SLIDER) / 2];
1644  const double field = mTempSettings.*(info.field);
1645  text->SetValue(info.Text(field));
1646  slider->SetValue(info.SliderSetting(field));
1647  }
1648 
1649  mKeepSignal->SetValue(mTempSettings.mNoiseReductionChoice == NRC_REDUCE_NOISE);
1650 #ifdef ISOLATE_CHOICE
1651  mKeepNoise->SetValue(mTempSettings.mNoiseReductionChoice == NRC_ISOLATE_NOISE);
1652 #endif
1653 #ifdef RESIDUE_CHOICE
1654  mResidue->SetValue(mTempSettings.mNoiseReductionChoice == NRC_LEAVE_RESIDUE);
1655 #endif
1656 
1657  // Set the enabled states of controls
1658  DisableControlsIfIsolating();
1659 #ifdef ADVANCED_SETTINGS
1660  EnableDisableSensitivityControls();
1661 #endif
1662 
1663  return true;
1664 }
1665 
1667 {
1668  if( !wxWindow::Validate() )
1669  return false;
1670  // Do the choice controls:
1672  return false;
1673 
1674  wxCommandEvent dummy;
1675  OnNoiseReductionChoice(dummy);
1676 
1677  return mTempSettings.Validate(m_pEffect);
1678 }
1679 
1680 void EffectNoiseReduction::Dialog::OnText(wxCommandEvent &event)
1681 {
1682  int id = event.GetId();
1683  int idx = (id - FIRST_SLIDER - 1) / 2;
1684  const ControlInfo &info = controlInfo()[idx];
1685  wxTextCtrl* text =
1686  static_cast<wxTextCtrl*>(wxWindow::FindWindowById(id, this));
1687  wxSlider* slider =
1688  static_cast<wxSlider*>(wxWindow::FindWindowById(id - 1, this));
1689  double &field = mTempSettings.*(info.field);
1690 
1691  text->GetValue().ToDouble(&field);
1692  slider->SetValue(info.SliderSetting(field));
1693 }
1694 
1695 void EffectNoiseReduction::Dialog::OnSlider(wxCommandEvent &event)
1696 {
1697  int id = event.GetId();
1698  int idx = (id - FIRST_SLIDER) / 2;
1699  const ControlInfo &info = controlInfo()[idx];
1700  wxSlider* slider =
1701  static_cast<wxSlider*>(wxWindow::FindWindowById(id, this));
1702  wxTextCtrl* text =
1703  static_cast<wxTextCtrl*>(wxWindow::FindWindowById(id + 1, this));
1704  double &field = mTempSettings.*(info.field);
1705 
1706  field = info.Value(slider->GetValue());
1707  text->SetValue(info.Text(field));
1708 }
EffectNoiseReduction::Statistics
Definition: NoiseReduction.cpp:170
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::Text
wxString Text(double value) const
Definition: NoiseReduction.cpp:1225
END_OF_BASIC_SLIDERS
@ END_OF_BASIC_SLIDERS
Definition: NoiseReduction.cpp:1191
EffectNoiseReduction::Worker::FinishTrackStatistics
void FinishTrackStatistics()
Definition: NoiseReduction.cpp:894
EffectNoiseReduction::Settings::Settings
Settings()
Definition: NoiseReduction.cpp:246
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::MemberPointer
doubleEffectNoiseReduction::Settings::* MemberPointer
Definition: NoiseReduction.cpp:1209
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:1257
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:354
EffectNoiseReduction::Settings::mDoProfile
bool mDoProfile
Definition: NoiseReduction.cpp:222
EffectNoiseReduction::Dialog::OnHelp
void OnHelp(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1496
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
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
EffectNoiseReduction::Worker::mProgressWindowCount
sampleCount mProgressWindowCount
Definition: NoiseReduction.cpp:331
EffectNoiseReduction::Dialog::OnGetProfile
void OnGetProfile(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1435
EffectNoiseReduction::Settings::mNoiseReductionChoice
int mNoiseReductionChoice
Definition: NoiseReduction.cpp:237
EffectDialog::Init
void Init()
Definition: EffectUI.cpp:2055
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::formatAsInt
bool formatAsInt
Definition: NoiseReduction.cpp:1258
ID_GAIN_TEXT
@ ID_GAIN_TEXT
Definition: NoiseReduction.cpp:1175
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:70
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:2482
anonymous_namespace{NoiseReduction.cpp}::writePrefs
void writePrefs(const StructureType *structure, const wxString &prefix, const PrefsTableEntry< StructureType, FieldType > *fields, size_t numFields)
Definition: NoiseReduction.cpp:504
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:2071
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:1448
EffectNoiseReduction::Worker::MyWindow::mGains
FloatVector mGains
Definition: NoiseReduction.cpp:283
EffectNoiseReduction::Worker::GatherStatistics
void GatherStatistics()
Definition: NoiseReduction.cpp:915
EffectNoiseReduction::Settings::mWindowSizeChoice
int mWindowSizeChoice
Definition: NoiseReduction.cpp:241
eWinFuncRectangular
@ eWinFuncRectangular
Definition: FFT.h:111
ID_RADIOBUTTON_KEEPSIGNAL
@ ID_RADIOBUTTON_KEEPSIGNAL
Definition: NoiseReduction.cpp:1161
EffectNoiseReduction::Worker::DoStart
bool DoStart() override
Called before any calls to ProcessWindow.
Definition: NoiseReduction.cpp:854
TrackList
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1280
ShuttleGuiBase::AddRadioButtonToGroup
wxRadioButton * AddRadioButtonToGroup(const TranslatableString &Prompt, int selector=1, int initValue=0)
Definition: ShuttleGui.cpp:574
anonymous_namespace{NoiseReduction.cpp}::NoiseReductionChoice
NoiseReductionChoice
Definition: NoiseReduction.cpp:157
entry
static ProjectFileIORegistry::WriterEntry entry
Definition: ProjectSettings.cpp:197
EffectNoiseReduction::ShowInterface
bool ShowInterface(wxWindow &parent, const EffectDialogFactory &factory, bool forceModal=false) override
Definition: NoiseReduction.cpp:449
EffectNoiseReduction::Dialog::OnSlider
void OnSlider(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1695
Effect::mT1
double mT1
Definition: Effect.h:467
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:779
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
ShuttleGui::MinSize
ShuttleGui & MinSize()
Definition: ShuttleGui.h:733
XO
#define XO(s)
Definition: Internat.h:31
anonymous_namespace{NoiseReduction.cpp}::ControlInfo
Definition: NoiseReduction.cpp:1208
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::valueMin
double valueMin
Definition: NoiseReduction.cpp:1253
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry::MemberPointer
FieldTypeStructureType::* MemberPointer
Definition: NoiseReduction.cpp:484
EffectNoiseReduction::Dialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: NoiseReduction.cpp:1666
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:2091
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
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:606
EffectManager::Get
static EffectManager & Get()
Definition: EffectManager.cpp:42
ID_EFFECT_PREVIEW
#define ID_EFFECT_PREVIEW
Definition: Effect.h:549
EffectNoiseReduction::Dialog::OnText
void OnText(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1680
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:1921
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:486
ID_FREQ_TEXT
@ ID_FREQ_TEXT
Definition: NoiseReduction.cpp:1189
EffectNoiseReduction::Dialog::mResidue
wxRadioButton * mResidue
Definition: NoiseReduction.cpp:398
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2274
END_OF_SLIDERS
@ END_OF_SLIDERS
Definition: NoiseReduction.cpp:1200
ID_BUTTON_GETPROFILE
@ ID_BUTTON_GETPROFILE
Definition: NoiseReduction.cpp:1160
EffectManager::SetSkipStateFlag
void SetSkipStateFlag(bool flag)
Definition: EffectManager.cpp:214
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:1632
ShuttleGui::Style
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:727
EffectNoiseReduction::Dialog::Dialog
Dialog(EffectNoiseReduction *effect, Settings *settings, wxWindow *parent, bool bHasProfile, bool bAllowTwiddleSettings)
Definition: NoiseReduction.cpp:1348
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:1233
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::sliderMax
long sliderMax
Definition: NoiseReduction.cpp:1255
EffectNoiseReduction::Worker::ApplyFreqSmoothing
void ApplyFreqSmoothing(FloatVector &gains)
Definition: NoiseReduction.cpp:748
EffectNoiseReduction::GetType
EffectType GetType() override
Definition: NoiseReduction.cpp:434
Effect::mT0
double mT0
Definition: Effect.h:466
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:488
ID_NEW_SENSITIVITY_TEXT
@ ID_NEW_SENSITIVITY_TEXT
Definition: NoiseReduction.cpp:1178
EffectNoiseReduction::Settings::mOldSensitivity
double mOldSensitivity
Definition: NoiseReduction.cpp:234
ID_NEW_SENSITIVITY_SLIDER
@ ID_NEW_SENSITIVITY_SLIDER
Definition: NoiseReduction.cpp:1177
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
EffectNoiseReduction::Settings::mMethod
int mMethod
Definition: NoiseReduction.cpp:243
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::valueMax
double valueMax
Definition: NoiseReduction.cpp:1254
EffectNoiseReduction::Dialog::DisableControlsIfIsolating
void DisableControlsIfIsolating()
Definition: NoiseReduction.cpp:1383
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::Value
double Value(long sliderSetting) const
Definition: NoiseReduction.cpp:1211
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2193
EffectNoiseReduction::Worker::MyWindow
Definition: NoiseReduction.cpp:274
EffectNoiseReduction::Worker::MyWindow::~MyWindow
~MyWindow() override
Definition: NoiseReduction.cpp:612
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:1024
EffectNoiseReduction::Worker::MyWindow::mSpectrums
FloatVector mSpectrums
Definition: NoiseReduction.cpp:282
EffectDialog
Definition: EffectUI.h:243
ShuttleGui::Validator
ShuttleGui & Validator(const Factory &f)
Definition: ShuttleGui.h:678
ID_RADIOBUTTON_KEEPNOISE
@ ID_RADIOBUTTON_KEEPNOISE
Definition: NoiseRemoval.cpp:596
anonymous_namespace{NoiseReduction.cpp}::NRC_ISOLATE_NOISE
@ NRC_ISOLATE_NOISE
Definition: NoiseReduction.cpp:159
EffectNoiseReduction::Settings::PromptUser
bool PromptUser(EffectNoiseReduction *effect, wxWindow &parent, bool bHasProfile, bool bAllowTwiddleSettings)
Definition: NoiseReduction.cpp:463
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
EffectClientInterface::EffectDialogFactory
std::function< wxDialog *(wxWindow &parent, EffectHostInterface *, EffectUIClientInterface *) > EffectDialogFactory
Definition: EffectInterface.h:190
ShuttleGuiBase::AddRadioButton
wxRadioButton * AddRadioButton(const TranslatableString &Prompt, int selector=0, int initValue=0)
Definition: ShuttleGui.cpp:568
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:616
EffectNoiseReduction::Worker::mOneBlockAttack
float mOneBlockAttack
Definition: NoiseReduction.cpp:319
EffectNoiseReduction::Dialog::OnReduceNoise
void OnReduceNoise(wxCommandEvent &event)
Definition: NoiseReduction.cpp:1483
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:465
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:483
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
ShuttleGuiBase::AddButton
wxButton * AddButton(const TranslatableString &Text, int PositionFlags=wxALIGN_CENTRE, bool setDefault=false)
Definition: ShuttleGui.cpp:360
ID_FREQ_SLIDER
@ ID_FREQ_SLIDER
Definition: NoiseReduction.cpp:1188
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:864
EffectNoiseReduction::Worker::Classify
bool Classify(unsigned nWindows, int band)
Definition: NoiseReduction.cpp:953
LoadEffects.h
EffectNoiseReduction::Statistics::mRate
double mRate
Definition: NoiseReduction.cpp:187
ShuttleGuiBase::StartStatic
wxStaticBox * StartStatic(const TranslatableString &Str, int iProp=0)
Definition: ShuttleGui.cpp:893
EffectNoiseReduction::Settings::WindowSize
size_t WindowSize() const
Definition: NoiseReduction.cpp:219
ID_RADIOBUTTON_RESIDUE
@ ID_RADIOBUTTON_RESIDUE
Definition: NoiseReduction.cpp:1166
anonymous_namespace{NoiseReduction.cpp}::PrefsTableEntry::name
const wxChar * name
Definition: NoiseReduction.cpp:487
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
EffectNoiseReduction::Worker
Definition: NoiseReduction.cpp:259
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
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:1148
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:515
anonymous_namespace{NoiseReduction.cpp}::controlInfo
const ControlInfo * controlInfo()
Definition: NoiseReduction.cpp:1270
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:1491
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:1260
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:582
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::textBoxCaption
const TranslatableString textBoxCaption
Definition: NoiseReduction.cpp:1259
TrapLong
long TrapLong(long x, long min, long max)
Definition: Effect.h:575
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:1252
EffectNoiseReduction::Dialog
Dialog used with EffectNoiseReduction.
Definition: NoiseReduction.cpp:346
EffectNoiseReduction::Dialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: NoiseReduction.cpp:1501
Prefs.h
EffectNoiseReduction::Settings::mNewSensitivity
double mNewSensitivity
Definition: NoiseReduction.cpp:227
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:238
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
ShuttleGuiBase::AddVariableText
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:463
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:691
ShuttleGuiBase::EndStatic
void EndStatic()
Definition: ShuttleGui.cpp:922
anonymous_namespace{NoiseReduction.cpp}::WindowTypes
WindowTypes
Definition: NoiseReduction.cpp:118
EffectNoiseReduction::Dialog::OnPreview
void OnPreview(wxCommandEvent &event) override
Definition: NoiseReduction.cpp:1470
EffectNoiseReduction::mSettings
std::unique_ptr< Settings > mSettings
Definition: NoiseReduction.h:55
EffectType
EffectType
Definition: EffectInterface.h:55
EffectManager.h
settings
static Settings & settings()
Definition: TrackInfo.cpp:86
anonymous_namespace{NoiseReduction.cpp}::WT_BLACKMAN_HANN
@ WT_BLACKMAN_HANN
Definition: NoiseReduction.cpp:122
ShuttleGuiBase::SetStretchyCol
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:202
EffectNoiseReduction::mStatistics
std::unique_ptr< Statistics > mStatistics
Definition: NoiseReduction.h:56
EffectDialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: EffectUI.cpp:2099
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:1388
EffectNoiseReduction::Settings
Definition: NoiseReduction.cpp:209
END_EVENT_TABLE
END_EVENT_TABLE()
ShuttleGuiBase::TieChoice
wxChoice * TieChoice(const TranslatableString &Prompt, TranslatableString &Selected, const TranslatableStrings &choices)
Definition: ShuttleGui.cpp:1727
EffectNoiseReduction::Dialog::mbHasProfile
bool mbHasProfile
Definition: NoiseReduction.cpp:389
ID_GAIN_SLIDER
@ ID_GAIN_SLIDER
Definition: NoiseReduction.cpp:1174
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:695
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:492
EffectNoiseReduction::Dialog::mTempSettings
EffectNoiseReduction::Settings mTempSettings
Definition: NoiseReduction.cpp:387
anonymous_namespace{NoiseReduction.cpp}::ControlInfo::SliderSetting
long SliderSetting(double value) const
Definition: NoiseReduction.cpp:1218
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:1262
FIRST_SLIDER
@ FIRST_SLIDER
Definition: NoiseReduction.cpp:1203
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