Audacity  3.0.3
NoiseRemoval.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  NoiseRemoval.cpp
6 
7  Dominic Mazzoni
8 
9 *******************************************************************//****************************************************************//*******************************************************************/
40 
41 
42 #include "NoiseRemoval.h"
43 
44 #if !defined(EXPERIMENTAL_NOISE_REDUCTION)
45 
46 #include "LoadEffects.h"
47 
48 #include "../WaveTrack.h"
49 #include "../Prefs.h"
50 #include "../FileNames.h"
51 #include "../ShuttleGui.h"
52 
53 #include <math.h>
54 
55 #if defined(__WXMSW__) && !defined(__CYGWIN__)
56 #include <float.h>
57 #define finite(x) _finite(x)
58 #endif
59 
60 #include <wx/file.h>
61 #include <wx/ffile.h>
62 #include <wx/bitmap.h>
63 #include <wx/brush.h>
64 #include <wx/button.h>
65 #include <wx/choice.h>
66 #include <wx/radiobut.h>
67 #include <wx/image.h>
68 #include <wx/intl.h>
69 #include <wx/sizer.h>
70 #include <wx/statbox.h>
71 #include <wx/stattext.h>
72 #include <wx/textctrl.h>
73 #include <wx/valtext.h>
74 
75 
76 #include "../PlatformCompatibility.h"
77 
79 { XO("Noise Removal") };
80 
82 
84 {
85  mWindowSize = 2048;
86  mSpectrumSize = 1 + mWindowSize / 2;
87 
88  gPrefs->Read(wxT("/Effects/NoiseRemoval/NoiseSensitivity"),
89  &mSensitivity, 0.0);
90  gPrefs->Read(wxT("/Effects/NoiseRemoval/NoiseGain"),
91  &mNoiseGain, -24.0);
92  gPrefs->Read(wxT("/Effects/NoiseRemoval/NoiseFreqSmoothing"),
93  &mFreqSmoothingHz, 150.0);
94  gPrefs->Read(wxT("/Effects/NoiseRemoval/NoiseAttackDecayTime"),
95  &mAttackDecayTime, 0.15);
96  gPrefs->Read(wxT("/Effects/NoiseRemoval/NoiseLeaveNoise"),
97  &mbLeaveNoise, false);
98 // mbLeaveNoise = false;
99 
100 
101  mMinSignalTime = 0.05f;
102  mHasProfile = false;
103  mDoProfile = true;
104 
106 
107  Init();
108 }
109 
111 {
112 }
113 
114 // ComponentInterface implementation
115 
117 {
118  return Symbol;
119 }
120 
122 {
123  return XO("Removes constant background noise such as fans, tape noise, or hums");
124 }
125 
126 // EffectDefinitionInterface implementation
127 
129 {
130  return EffectTypeProcess;
131 }
132 
134 {
135  return false;
136 }
137 
138 // Effect implementation
139 
140 #define MAX_NOISE_LEVEL 30
142 {
143  mLevel = gPrefs->Read(wxT("/Effects/NoiseRemoval/Noise_Level"), 3L);
144  if ((mLevel < 0) || (mLevel > MAX_NOISE_LEVEL)) { // corrupted Prefs?
145  mLevel = 0; //Off-skip
146  gPrefs->Write(wxT("/Effects/NoiseRemoval/Noise_Level"), mLevel);
147  }
148  return gPrefs->Flush();
149 }
150 
152 {
153  return (mLevel == 0);
154 }
155 
157  wxWindow &parent, const EffectDialogFactory &, bool forceModal )
158 {
159  // to do: use forceModal correctly
160  NoiseRemovalDialog dlog(this, &parent);
161  dlog.mSensitivity = mSensitivity;
162  dlog.mGain = -mNoiseGain;
163  dlog.mFreq = mFreqSmoothingHz;
164  dlog.mTime = mAttackDecayTime;
165  dlog.mbLeaveNoise = mbLeaveNoise;
166  dlog.mKeepSignal->SetValue(!mbLeaveNoise);
167  dlog.mKeepNoise->SetValue(mbLeaveNoise);
168 
169  // We may want to twiddle the levels if we are setting
170  // from an automation dialog
171  bool bAllowTwiddleSettings = forceModal;
172 
173  if (mHasProfile || bAllowTwiddleSettings) {
174  dlog.m_pButton_Preview->Enable(GetNumWaveTracks() != 0);
175  dlog.m_pButton_RemoveNoise->SetDefault();
176  } else {
177  dlog.m_pButton_Preview->Enable(false);
178  dlog.m_pButton_RemoveNoise->Enable(false);
179  }
180 
181  dlog.TransferDataToWindow();
182  dlog.mKeepNoise->SetValue(dlog.mbLeaveNoise);
183  dlog.CentreOnParent();
184  dlog.ShowModal();
185 
186  if (dlog.GetReturnCode() == 0) {
187  return false;
188  }
189 
190  mSensitivity = dlog.mSensitivity;
191  mNoiseGain = -dlog.mGain;
192  mFreqSmoothingHz = dlog.mFreq;
193  mAttackDecayTime = dlog.mTime;
194  mbLeaveNoise = dlog.mbLeaveNoise;
195 
196  gPrefs->Write(wxT("/Effects/NoiseRemoval/NoiseSensitivity"), mSensitivity);
197  gPrefs->Write(wxT("/Effects/NoiseRemoval/NoiseGain"), mNoiseGain);
198  gPrefs->Write(wxT("/Effects/NoiseRemoval/NoiseFreqSmoothing"), mFreqSmoothingHz);
199  gPrefs->Write(wxT("/Effects/NoiseRemoval/NoiseAttackDecayTime"), mAttackDecayTime);
200  gPrefs->Write(wxT("/Effects/NoiseRemoval/NoiseLeaveNoise"), mbLeaveNoise);
201 
202  mDoProfile = (dlog.GetReturnCode() == 1);
203  return gPrefs->Flush();
204 }
205 
207 {
208  Initialize();
209 
210  // This same code will both remove noise and profile it,
211  // depending on 'mDoProfile'
212  this->CopyInputTracks(); // Set up mOutputTracks.
213  bool bGoodResult = true;
214 
215  int count = 0;
216  for( auto track : mOutputTracks->Selected< WaveTrack >() ) {
217  double trackStart = track->GetStartTime();
218  double trackEnd = track->GetEndTime();
219  double t0 = mT0 < trackStart? trackStart: mT0;
220  double t1 = mT1 > trackEnd? trackEnd: mT1;
221 
222  if (t1 > t0) {
223  auto start = track->TimeToLongSamples(t0);
224  auto end = track->TimeToLongSamples(t1);
225  auto len = end - start;
226 
227  if (!ProcessOne(count, track, start, len)) {
228  bGoodResult = false;
229  break;
230  }
231  }
232  count++;
233  }
234 
235  if (bGoodResult && mDoProfile) {
236  mHasProfile = true;
237  mDoProfile = false;
238  }
239 
240  this->ReplaceProcessedTracks(bGoodResult);
241  return bGoodResult;
242 }
243 
245 {
246  Floats tmp{ mSpectrumSize };
247  int j, j0, j1;
248 
249  for(int i = 0; i < mSpectrumSize; i++) {
250  j0 = wxMax(0, i - mFreqSmoothingBins);
251  j1 = wxMin(mSpectrumSize-1, i + mFreqSmoothingBins);
252  tmp[i] = 0.0;
253  for(j = j0; j <= j1; j++) {
254  tmp[i] += spec[j];
255  }
256  tmp[i] /= (j1 - j0 + 1);
257  }
258 
259  for(size_t i = 0; i < mSpectrumSize; i++)
260  spec[i] = tmp[i];
261 }
262 
264 {
267  mAttackDecayBlocks = 1 +
268  (int)(mAttackDecayTime * mSampleRate / (mWindowSize / 2));
271  // Applies to power, divide by 10:
272  mSensitivityFactor = pow(10.0, mSensitivity/10.0);
274  (int)(mMinSignalTime * mSampleRate / (mWindowSize / 2));
275  if( mMinSignalBlocks < 1 )
276  mMinSignalBlocks = 1;
277  mHistoryLen = (2 * mAttackDecayBlocks) - 1;
278 
281 
286 
287  // Initialize the FFT
289 
294 
295  // Create a Hann window function
296  for(size_t i=0; i<mWindowSize; i++)
297  mWindow[i] = 0.5 - 0.5 * cos((2.0*M_PI*i) / mWindowSize);
298 
299  if (mDoProfile) {
300  for (size_t i = 0; i < mSpectrumSize; i++)
301  mNoiseThreshold[i] = float(0);
302  }
303 }
304 
306 {
307  hFFT.reset();
308 
309  if (mDoProfile) {
311  }
312 
313  mSpectrums.reset();
314  mGains.reset();
315  mRealFFTs.reset();
316  mImagFFTs.reset();
317 
318  mFFTBuffer.reset();
319  mInWaveBuffer.reset();
320  mWindow.reset();
321  mOutOverlapBuffer.reset();
322 
323  mOutputTrack.reset();
324 }
325 
327 {
328  for(size_t i = 0; i < mHistoryLen; i++) {
329  for(size_t j = 0; j < mSpectrumSize; j++) {
330  mSpectrums[i][j] = 0;
331  mGains[i][j] = mNoiseAttenFactor;
332  mRealFFTs[i][j] = 0.0;
333  mImagFFTs[i][j] = 0.0;
334  }
335  }
336 
337  for(size_t j = 0; j < mWindowSize; j++)
338  mOutOverlapBuffer[j] = 0.0;
339 
340  mInputPos = 0;
341  mInSampleCount = 0;
342  mOutSampleCount = -(int)((mWindowSize / 2) * (mHistoryLen - 1));
343 }
344 
345 void EffectNoiseRemoval::ProcessSamples(size_t len, float *buffer)
346 {
347  while(len && mOutSampleCount < mInSampleCount) {
348  size_t avail = wxMin(len, mWindowSize - mInputPos);
349  for(size_t i = 0; i < avail; i++)
350  mInWaveBuffer[mInputPos + i] = buffer[i];
351  buffer += avail;
352  len -= avail;
353  mInputPos += avail;
354 
355  if (mInputPos == int(mWindowSize)) {
357  if (mDoProfile)
358  GetProfile();
359  else
360  RemoveNoise();
362 
363  // Rotate halfway for overlap-add
364  for(size_t i = 0; i < mWindowSize / 2; i++) {
366  }
367  mInputPos = mWindowSize / 2;
368  }
369  }
370 }
371 
373 {
374  for(size_t i = 0; i < mWindowSize; i++)
375  mFFTBuffer[i] = mInWaveBuffer[i];
376  RealFFTf(mFFTBuffer.get(), hFFT.get());
377  for(size_t i = 1; i + 1 < mSpectrumSize; i++) {
378  mRealFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i] ];
379  mImagFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i]+1];
380  mSpectrums[0][i] = mRealFFTs[0][i]*mRealFFTs[0][i] + mImagFFTs[0][i]*mImagFFTs[0][i];
381  mGains[0][i] = mNoiseAttenFactor;
382  }
383  // DC and Fs/2 bins need to be handled specially
384  mSpectrums[0][0] = mFFTBuffer[0]*mFFTBuffer[0];
386  mGains[0][0] = mNoiseAttenFactor;
388 }
389 
390 namespace {
391  inline void Rotate(ArraysOf<float> &arrays, size_t historyLen)
392  {
393  Floats temp = std::move( arrays[ historyLen - 1 ] );
394 
395  for ( size_t nn = historyLen - 1; nn--; )
396  arrays[ nn + 1 ] = std::move( arrays[ nn ] );
397  arrays[0] = std::move( temp );
398  }
399 }
400 
402 {
403  // Remember the last window so we can reuse it
408 }
409 
411 {
412  // Keep flushing empty input buffers through the history
413  // windows until we've output exactly as many samples as
414  // were input.
415  // Well, not exactly, but not more than mWindowSize/2 extra samples at the end.
416  // We'll DELETE them later in ProcessOne.
417 
418  Floats empty{ mWindowSize / 2 };
419  for(size_t i = 0; i < mWindowSize / 2; i++)
420  empty[i] = 0.0;
421 
422  while (mOutSampleCount < mInSampleCount) {
423  ProcessSamples(mWindowSize / 2, empty.get());
424  }
425 }
426 
428 {
429  // The noise threshold for each frequency is the maximum
430  // level achieved at that frequency for a minimum of
431  // mMinSignalBlocks blocks in a row - the max of a min.
432 
433  int start = mHistoryLen - mMinSignalBlocks;
434  int finish = mHistoryLen;
435  int i;
436 
437  for (size_t j = 0; j < mSpectrumSize; j++) {
438  float min = mSpectrums[start][j];
439  for (i = start+1; i < finish; i++) {
440  if (mSpectrums[i][j] < min)
441  min = mSpectrums[i][j];
442  }
443  if (min > mNoiseThreshold[j])
444  mNoiseThreshold[j] = min;
445  }
446 
447  mOutSampleCount += mWindowSize / 2; // what is this for? Not used when we are getting the profile?
448 }
449 
451 {
452  size_t center = mHistoryLen / 2;
453  size_t start = center - mMinSignalBlocks/2;
454  size_t finish = start + mMinSignalBlocks;
455 
456  // Raise the gain for elements in the center of the sliding history
457  for (size_t j = 0; j < mSpectrumSize; j++) {
458  float min = mSpectrums[start][j];
459  for (size_t i = start+1; i < finish; i++) {
460  if (mSpectrums[i][j] < min)
461  min = mSpectrums[i][j];
462  }
463  if (min > mSensitivityFactor * mNoiseThreshold[j] && mGains[center][j] < 1.0) {
464  if (mbLeaveNoise) mGains[center][j] = 0.0;
465  else mGains[center][j] = 1.0;
466  } else {
467  if (mbLeaveNoise) mGains[center][j] = 1.0;
468  }
469  }
470 
471  // Decay the gain in both directions;
472  // note that mOneBlockAttackDecay is less than 1.0
473  // of linear attenuation per block
474  for (size_t j = 0; j < mSpectrumSize; j++) {
475  for (size_t i = center + 1; i < mHistoryLen; i++) {
476  if (mGains[i][j] < mGains[i - 1][j] * mOneBlockAttackDecay)
477  mGains[i][j] = mGains[i - 1][j] * mOneBlockAttackDecay;
478  if (mGains[i][j] < mNoiseAttenFactor)
479  mGains[i][j] = mNoiseAttenFactor;
480  }
481  for (size_t i = center; i--;) {
482  if (mGains[i][j] < mGains[i + 1][j] * mOneBlockAttackDecay)
483  mGains[i][j] = mGains[i + 1][j] * mOneBlockAttackDecay;
484  if (mGains[i][j] < mNoiseAttenFactor)
485  mGains[i][j] = mNoiseAttenFactor;
486  }
487  }
488 
489 
490  // Apply frequency smoothing to output gain
491  int out = mHistoryLen - 1; // end of the queue
492 
493  ApplyFreqSmoothing(mGains[out].get());
494 
495  // Apply gain to FFT
496  for (size_t j = 0; j < (mSpectrumSize-1); j++) {
497  mFFTBuffer[j*2 ] = mRealFFTs[out][j] * mGains[out][j];
498  mFFTBuffer[j*2+1] = mImagFFTs[out][j] * mGains[out][j];
499  }
500  // The Fs/2 component is stored as the imaginary part of the DC component
501  mFFTBuffer[1] = mRealFFTs[out][mSpectrumSize-1] * mGains[out][mSpectrumSize-1];
502 
503  // Invert the FFT into the output buffer
504  InverseRealFFTf(mFFTBuffer.get(), hFFT.get());
505 
506  // Overlap-add
507  for(size_t j = 0; j < (mSpectrumSize-1); j++) {
508  mOutOverlapBuffer[j*2 ] += mFFTBuffer[hFFT->BitReversed[j] ] * mWindow[j*2 ];
509  mOutOverlapBuffer[j*2+1] += mFFTBuffer[hFFT->BitReversed[j]+1] * mWindow[j*2+1];
510  }
511 
512  // Output the first half of the overlap buffer, they're done -
513  // and then shift the next half over.
514  if (mOutSampleCount >= 0) { // ...but not if it's the first half-window
516  mWindowSize / 2);
517  }
519  for(size_t j = 0; j < mWindowSize / 2; j++) {
521  mOutOverlapBuffer[j + (mWindowSize / 2)] = 0.0;
522  }
523 }
524 
526  sampleCount start, sampleCount len)
527 {
528  if (track == NULL)
529  return false;
530 
531  StartNewTrack();
532 
533  if (!mDoProfile)
534  mOutputTrack = track->EmptyCopy();
535 
536  auto bufferSize = track->GetMaxBlockSize();
537  Floats buffer{ bufferSize };
538 
539  bool bLoopSuccess = true;
540  auto samplePos = start;
541  while (samplePos < start + len) {
542  //Get a blockSize of samples (smaller than the size of the buffer)
543  //Adjust the block size if it is the final block in the track
544  const auto blockSize = limitSampleBufferSize(
545  track->GetBestBlockSize(samplePos),
546  start + len - samplePos
547  );
548 
549  //Get the samples from the track and put them in the buffer
550  track->Get((samplePtr)buffer.get(), floatSample, samplePos, blockSize);
551 
552  mInSampleCount += blockSize;
553  ProcessSamples(blockSize, buffer.get());
554 
555  samplePos += blockSize;
556 
557  // Update the Progress meter
558  if (TrackProgress(count, (samplePos - start).as_double() / len.as_double())) {
559  bLoopSuccess = false;
560  break;
561  }
562  }
563 
564  FinishTrack();
565 
566  if (!mDoProfile) {
567  // Flush the output WaveTrack (since it's buffered)
568  mOutputTrack->Flush();
569 
570  // Take the output track and insert it in place of the original
571  // sample data (as operated on -- this may not match mT0/mT1)
572  if (bLoopSuccess) {
573  double t0 = mOutputTrack->LongSamplesToTime(start);
574  double tLen = mOutputTrack->LongSamplesToTime(len);
575  // Filtering effects always end up with more data than they started with. Delete this 'tail'.
576  mOutputTrack->HandleClear(tLen, mOutputTrack->GetEndTime(), false, false);
577  track->ClearAndPaste(t0, t0 + tLen, mOutputTrack.get(), true, false);
578  }
579  }
580 
581  return bLoopSuccess;
582 }
583 
584 // WDR: class implementations
585 
586 //----------------------------------------------------------------------------
587 // NoiseRemovalDialog
588 //----------------------------------------------------------------------------
589 
590 // WDR: event table for NoiseRemovalDialog
591 
592 enum {
605 };
606 
607 #define SENSITIVITY_MIN 0 // Corresponds to -20 dB
608 #define SENSITIVITY_MAX 4000 // Corresponds to 20 dB
609 
610 #define GAIN_MIN 0
611 #define GAIN_MAX 48 // Corresponds to -48 dB
612 
613 #define FREQ_MIN 0
614 #define FREQ_MAX 100 // Corresponds to 1000 Hz
615 
616 #define TIME_MIN 0
617 #define TIME_MAX 100 // Corresponds to 1.000 seconds
618 
619 
620 BEGIN_EVENT_TABLE(NoiseRemovalDialog,wxDialogWrapper)
636 
638  wxWindow *parent)
639  : EffectDialog( parent, XO("Noise Removal"), EffectTypeProcess)
640 {
641  m_pEffect = effect;
642 
643  // NULL out the control members until the controls are created.
644  m_pButton_GetProfile = NULL;
645  m_pButton_Preview = NULL;
646  m_pButton_RemoveNoise = NULL;
647 
648  Init();
649 
650  m_pButton_Preview =
651  (wxButton *)wxWindow::FindWindowById(ID_EFFECT_PREVIEW, this);
652  m_pButton_RemoveNoise =
653  (wxButton *)wxWindow::FindWindowById(wxID_OK, this);
654 }
655 
656 void NoiseRemovalDialog::OnGetProfile( wxCommandEvent & WXUNUSED(event))
657 {
658  EndModal(1);
659 }
660 
661 void NoiseRemovalDialog::OnKeepNoise( wxCommandEvent & WXUNUSED(event))
662 {
663  mbLeaveNoise = mKeepNoise->GetValue();
664 }
665 
666 void NoiseRemovalDialog::OnPreview(wxCommandEvent & WXUNUSED(event))
667 {
668  // Save & restore parameters around Preview, because we didn't do OK.
669  bool oldDoProfile = m_pEffect->mDoProfile;
670  bool oldLeaveNoise = m_pEffect->mbLeaveNoise;
671  double oldSensitivity = m_pEffect->mSensitivity;
672  double oldGain = m_pEffect->mNoiseGain;
673  double oldFreq = m_pEffect->mFreqSmoothingHz;
674  double oldTime = m_pEffect->mAttackDecayTime;
675 
677 
678  m_pEffect->mDoProfile = false;
684 
685  auto cleanup = finally( [&] {
686  m_pEffect->mSensitivity = oldSensitivity;
687  m_pEffect->mNoiseGain = oldGain;
688  m_pEffect->mFreqSmoothingHz = oldFreq;
689  m_pEffect->mAttackDecayTime = oldTime;
690  m_pEffect->mbLeaveNoise = oldLeaveNoise;
691  m_pEffect->mDoProfile = oldDoProfile;
692  } );
693 
694  m_pEffect->Preview( false );
695 }
696 
697 void NoiseRemovalDialog::OnRemoveNoise( wxCommandEvent & WXUNUSED(event))
698 {
699  mbLeaveNoise = mKeepNoise->GetValue();
700  EndModal(2);
701 }
702 
703 void NoiseRemovalDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
704 {
705  EndModal(0);
706 }
707 
709 {
710  S.StartStatic(XO("Step 1"));
711  {
713 "Select a few seconds of just noise so Audacity knows what to filter out,\nthen click Get Noise Profile:"));
714  m_pButton_GetProfile = S.Id(ID_BUTTON_GETPROFILE).AddButton(XXO("&Get Noise Profile"));
715  }
716  S.EndStatic();
717 
718  S.StartStatic(XO("Step 2"));
719  {
721 "Select all of the audio you want filtered, choose how much noise you want\nfiltered out, and then click 'OK' to remove noise.\n"));
722 
723  S.StartMultiColumn(3, wxEXPAND);
724  S.SetStretchyCol(2);
725  {
726  mGainT = S.Id(ID_GAIN_TEXT)
727  .Validator<wxTextValidator>(wxFILTER_NUMERIC)
728  .AddTextBox(XXO("Noise re&duction (dB):"), wxT(""), 0);
729 
731  .Name(XO("Noise reduction"))
732  .Style(wxSL_HORIZONTAL)
733  .MinSize( { 150, -1 } )
734  .AddSlider( {}, 0, GAIN_MAX, GAIN_MIN);
735 
737  .Validator<wxTextValidator>(wxFILTER_NUMERIC)
738  .AddTextBox(XXO("&Sensitivity (dB):"), wxT(""), 0);
740  .Name(XO("Sensitivity"))
741  .Style(wxSL_HORIZONTAL)
742  .MinSize( { 150, -1 } )
743  .AddSlider( {}, 0, SENSITIVITY_MAX, SENSITIVITY_MIN);
744 
745  mFreqT = S.Id(ID_FREQ_TEXT)
746  .Validator<wxTextValidator>(wxFILTER_NUMERIC)
747  .AddTextBox(XXO("Fr&equency smoothing (Hz):"), wxT(""), 0);
749  .Name(XO("Frequency smoothing"))
750  .Style(wxSL_HORIZONTAL)
751  .MinSize( { 150, -1 } )
752  .AddSlider( {}, 0, FREQ_MAX, FREQ_MIN);
753 
754  mTimeT = S.Id(ID_TIME_TEXT)
755  .Validator<wxTextValidator>(wxFILTER_NUMERIC)
756  .AddTextBox(XXO("Attac&k/decay time (secs):"), wxT(""), 0);
758  .Name(XO("Attack/decay time"))
759  .Style(wxSL_HORIZONTAL)
760  .MinSize( { 150, -1 } )
761  .AddSlider( {}, 0, TIME_MAX, TIME_MIN);
762 
763  S.AddPrompt(XXO("Noise:"));
765  .AddRadioButton(XXO("Re&move"));
767  .AddRadioButtonToGroup(XXO("&Isolate"));
768  }
769  S.EndMultiColumn();
770  }
771  S.EndStatic();
772 }
773 
775 {
776  mSensitivityT->SetValue(wxString::Format(wxT("%.2f"), mSensitivity));
777  mGainT->SetValue(wxString::Format(wxT("%d"), (int)mGain));
778  mFreqT->SetValue(wxString::Format(wxT("%d"), (int)mFreq));
779  mTimeT->SetValue(wxString::Format(wxT("%.2f"), mTime));
780  mKeepNoise->SetValue(mbLeaveNoise);
781  mKeepSignal->SetValue(!mbLeaveNoise);
782 
784  mGainS->SetValue(TrapLong(mGain, GAIN_MIN, GAIN_MAX));
785  mFreqS->SetValue(TrapLong(mFreq / 10, FREQ_MIN, FREQ_MAX));
786  mTimeS->SetValue(TrapLong(mTime * TIME_MAX + 0.5, TIME_MIN, TIME_MAX));
787 
788  return true;
789 }
790 
792 {
793  // Nothing to do here
794  return true;
795 }
796 
797 void NoiseRemovalDialog::OnSensitivityText(wxCommandEvent & WXUNUSED(event))
798 {
799  mSensitivityT->GetValue().ToDouble(&mSensitivity);
801 }
802 
803 void NoiseRemovalDialog::OnGainText(wxCommandEvent & WXUNUSED(event))
804 {
805  mGainT->GetValue().ToDouble(&mGain);
806  mGainS->SetValue(TrapLong(mGain, GAIN_MIN, GAIN_MAX));
807 }
808 
809 void NoiseRemovalDialog::OnFreqText(wxCommandEvent & WXUNUSED(event))
810 {
811  mFreqT->GetValue().ToDouble(&mFreq);
812  mFreqS->SetValue(TrapLong(mFreq / 10, FREQ_MIN, FREQ_MAX));
813 }
814 
815 void NoiseRemovalDialog::OnTimeText(wxCommandEvent & WXUNUSED(event))
816 {
817  mTimeT->GetValue().ToDouble(&mTime);
818  mTimeS->SetValue(TrapLong(mTime * TIME_MAX + 0.5, TIME_MIN, TIME_MAX));
819 }
820 
821 void NoiseRemovalDialog::OnSensitivitySlider(wxCommandEvent & WXUNUSED(event))
822 {
823  mSensitivity = mSensitivityS->GetValue()/100.0 - 20.0;
824  mSensitivityT->SetValue(wxString::Format(wxT("%.2f"), mSensitivity));
825 }
826 
827 void NoiseRemovalDialog::OnGainSlider(wxCommandEvent & WXUNUSED(event))
828 {
829  mGain = mGainS->GetValue();
830  mGainT->SetValue(wxString::Format(wxT("%d"), (int)mGain));
831 }
832 
833 void NoiseRemovalDialog::OnFreqSlider(wxCommandEvent & WXUNUSED(event))
834 {
835  mFreq = mFreqS->GetValue() * 10;
836  mFreqT->SetValue(wxString::Format(wxT("%d"), (int)mFreq));
837 }
838 
839 void NoiseRemovalDialog::OnTimeSlider(wxCommandEvent & WXUNUSED(event))
840 {
841  mTime = mTimeS->GetValue() / (TIME_MAX*1.0);
842  mTimeT->SetValue(wxString::Format(wxT("%.2f"), mTime));
843 }
844 
845 #endif
Init
Definition: ModuleManager.h:152
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
ID_SENSITIVITY_SLIDER
@ ID_SENSITIVITY_SLIDER
Definition: NoiseRemoval.cpp:597
NoiseRemovalDialog::OnKeepNoise
void OnKeepNoise(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:661
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
NoiseRemovalDialog::OnRemoveNoise
void OnRemoveNoise(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:697
EffectNoiseRemoval::mFFTBuffer
Floats mFFTBuffer
Definition: NoiseRemoval.h:105
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
NoiseRemovalDialog::OnSensitivitySlider
void OnSensitivitySlider(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:821
DB_TO_LINEAR
const double MIN_Threshold_Linear DB_TO_LINEAR(MIN_Threshold_dB)
EffectNoiseRemoval::mDoProfile
bool mDoProfile
Definition: NoiseRemoval.h:63
EffectNoiseRemoval::CheckWhetherSkipEffect
bool CheckWhetherSkipEffect() override
Definition: NoiseRemoval.cpp:151
EffectNoiseRemoval::GetType
EffectType GetType() override
Definition: NoiseRemoval.cpp:128
EffectNoiseRemoval::End
void End() override
Definition: NoiseRemoval.cpp:305
EffectNoiseRemoval::mNoiseAttenFactor
float mNoiseAttenFactor
Definition: NoiseRemoval.h:111
MAX_NOISE_LEVEL
#define MAX_NOISE_LEVEL
Definition: NoiseRemoval.cpp:140
EffectNoiseRemoval::mMinSignalTime
float mMinSignalTime
Definition: NoiseRemoval.h:71
EffectNoiseRemoval::mMinSignalBlocks
size_t mMinSignalBlocks
Definition: NoiseRemoval.h:113
NoiseRemovalDialog::TransferDataFromWindow
bool TransferDataFromWindow() override
Definition: NoiseRemoval.cpp:791
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
TIME_MIN
#define TIME_MIN
Definition: NoiseRemoval.cpp:616
NoiseRemovalDialog::mKeepNoise
wxRadioButton * mKeepNoise
Definition: NoiseRemoval.h:173
Effect::CopyInputTracks
void CopyInputTracks(bool allSyncLockSelected=false)
Definition: Effect.cpp:2071
FREQ_MAX
#define FREQ_MAX
Definition: NoiseRemoval.cpp:614
SENSITIVITY_MAX
#define SENSITIVITY_MAX
Definition: NoiseRemoval.cpp:608
ShuttleGuiBase::AddRadioButtonToGroup
wxRadioButton * AddRadioButtonToGroup(const TranslatableString &Prompt, int selector=1, int initValue=0)
Definition: ShuttleGui.cpp:574
EffectNoiseRemoval::Initialize
void Initialize()
Definition: NoiseRemoval.cpp:263
RealFFTf
void RealFFTf(fft_type *buffer, const FFTParam *h)
Definition: RealFFTf.cpp:162
TIME_MAX
#define TIME_MAX
Definition: NoiseRemoval.cpp:617
Effect::mT1
double mT1
Definition: Effect.h:467
ArrayOf::reinit
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:57
EffectNoiseRemoval::EffectNoiseRemoval
EffectNoiseRemoval()
Definition: NoiseRemoval.cpp:83
EffectNoiseRemoval::mWindowSize
size_t mWindowSize
Definition: NoiseRemoval.h:69
ShuttleGui::MinSize
ShuttleGui & MinSize()
Definition: ShuttleGui.h:733
XO
#define XO(s)
Definition: Internat.h:31
NoiseRemovalDialog::mFreq
double mFreq
Definition: NoiseRemoval.h:187
EffectNoiseRemoval::ProcessSamples
void ProcessSamples(size_t len, float *buffer)
Definition: NoiseRemoval.cpp:345
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1238
ID_EFFECT_PREVIEW
#define ID_EFFECT_PREVIEW
Definition: Effect.h:549
EffectNoiseRemoval
A two-pass effect to remove background noise.
Definition: NoiseRemoval.h:35
NoiseRemovalDialog::OnFreqSlider
void OnFreqSlider(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:833
EffectNoiseRemoval::mOutputTrack
std::shared_ptr< WaveTrack > mOutputTrack
Definition: NoiseRemoval.h:99
EffectNoiseRemoval::mOneBlockAttackDecay
float mOneBlockAttackDecay
Definition: NoiseRemoval.h:110
EffectNoiseRemoval::mOutOverlapBuffer
Floats mOutOverlapBuffer
Definition: NoiseRemoval.h:116
WaveTrack::ClearAndPaste
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Definition: WaveTrack.cpp:848
EffectNoiseRemoval::GetDescription
TranslatableString GetDescription() override
Definition: NoiseRemoval.cpp:121
WaveTrack::EmptyCopy
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}) const
Definition: WaveTrack.cpp:671
EffectNoiseRemoval::mInWaveBuffer
Floats mInWaveBuffer
Definition: NoiseRemoval.h:115
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
GAIN_MIN
#define GAIN_MIN
Definition: NoiseRemoval.cpp:610
EffectNoiseRemoval::mInputPos
int mInputPos
Definition: NoiseRemoval.h:102
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2274
NoiseRemoval.h
NoiseRemovalDialog::OnFreqText
void OnFreqText(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:809
ID_FREQ_TEXT
@ ID_FREQ_TEXT
Definition: NoiseRemoval.cpp:603
EffectNoiseRemoval::mInSampleCount
sampleCount mInSampleCount
Definition: NoiseRemoval.h:100
WaveTrack::Get
bool Get(samplePtr buffer, sampleFormat format, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in a specified format.
Definition: WaveTrack.cpp:1984
NoiseRemovalDialog::OnCancel
void OnCancel(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:703
EffectNoiseRemoval::ProcessOne
bool ProcessOne(int count, WaveTrack *track, sampleCount start, sampleCount len)
Definition: NoiseRemoval.cpp:525
NoiseRemovalDialog::mGainT
wxTextCtrl * mGainT
Definition: NoiseRemoval.h:181
ID_TIME_TEXT
@ ID_TIME_TEXT
Definition: NoiseRemoval.cpp:604
NoiseRemovalDialog::mSensitivityT
wxTextCtrl * mSensitivityT
Definition: NoiseRemoval.h:180
floatSample
@ floatSample
Definition: SampleFormat.h:34
ArraysOf::reinit
void reinit(Integral count)
Definition: MemoryX.h:109
Effect::mProjectRate
double mProjectRate
Definition: Effect.h:458
ID_BUTTON_GETPROFILE
@ ID_BUTTON_GETPROFILE
Definition: NoiseRemoval.cpp:593
XXO
#define XXO(s)
Definition: Internat.h:44
EffectNoiseRemoval::mHasProfile
bool mHasProfile
Definition: NoiseRemoval.h:64
Effect::mT0
double mT0
Definition: Effect.h:466
sampleCount::as_double
double as_double() const
Definition: SampleCount.h:45
ArraysOf< float >
EffectNoiseRemoval::mFreqSmoothingBins
int mFreqSmoothingBins
Definition: NoiseRemoval.h:108
NoiseRemovalDialog::m_pButton_Preview
wxButton * m_pButton_Preview
Definition: NoiseRemoval.h:169
EffectNoiseRemoval::mbLeaveNoise
bool mbLeaveNoise
Definition: NoiseRemoval.h:83
NoiseRemovalDialog::OnPreview
void OnPreview(wxCommandEvent &event) override
Definition: NoiseRemoval.cpp:666
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1229
NoiseRemovalDialog::mTimeS
wxSlider * mTimeS
Definition: NoiseRemoval.h:178
EffectNoiseRemoval::GetProfile
void GetProfile()
Definition: NoiseRemoval.cpp:427
NoiseRemovalDialog::OnTimeSlider
void OnTimeSlider(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:839
NoiseRemovalDialog::mFreqT
wxTextCtrl * mFreqT
Definition: NoiseRemoval.h:182
NoiseRemovalDialog::mSensitivity
double mSensitivity
Definition: NoiseRemoval.h:185
Effect::ReplaceProcessedTracks
void ReplaceProcessedTracks(const bool bGoodResult)
Definition: Effect.cpp:2193
SENSITIVITY_MIN
#define SENSITIVITY_MIN
Definition: NoiseRemoval.cpp:607
EffectNoiseRemoval::mAttackDecayTime
double mAttackDecayTime
Definition: NoiseRemoval.h:82
ID_TIME_SLIDER
@ ID_TIME_SLIDER
Definition: NoiseRemoval.cpp:600
EffectNoiseRemoval::mWindow
Floats mWindow
Definition: NoiseRemoval.h:106
EffectNoiseRemoval::mSensitivity
double mSensitivity
Definition: NoiseRemoval.h:79
EffectNoiseRemoval::Symbol
static const ComponentInterfaceSymbol Symbol
Definition: NoiseRemoval.h:37
EffectNoiseRemoval::mNoiseThreshold
Floats mNoiseThreshold
Definition: NoiseRemoval.h:75
EffectNoiseRemoval::RemoveNoise
void RemoveNoise()
Definition: NoiseRemoval.cpp:450
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
EffectNoiseRemoval::FinishTrack
void FinishTrack()
Definition: NoiseRemoval.cpp:410
NoiseRemovalDialog::m_pButton_GetProfile
wxButton * m_pButton_GetProfile
Definition: NoiseRemoval.h:168
EffectNoiseRemoval::mLevel
int mLevel
Definition: NoiseRemoval.h:65
NoiseRemovalDialog::mGainS
wxSlider * mGainS
Definition: NoiseRemoval.h:176
ID_BUTTON_LEAVENOISE
@ ID_BUTTON_LEAVENOISE
Definition: NoiseRemoval.cpp:594
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
ID_GAIN_TEXT
@ ID_GAIN_TEXT
Definition: NoiseRemoval.cpp:602
InverseRealFFTf
void InverseRealFFTf(fft_type *buffer, const FFTParam *h)
Definition: RealFFTf.cpp:264
NoiseRemovalDialog::OnGainSlider
void OnGainSlider(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:827
FREQ_MIN
#define FREQ_MIN
Definition: NoiseRemoval.cpp:613
Effect::mOutputTracks
std::shared_ptr< TrackList > mOutputTracks
Definition: Effect.h:465
EffectNoiseRemoval::mOutSampleCount
sampleCount mOutSampleCount
Definition: NoiseRemoval.h:101
NoiseRemovalDialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S) override
Definition: NoiseRemoval.cpp:708
Effect::Preview
virtual void Preview(bool dryOnly)
Definition: Effect.cpp:2295
GAIN_MAX
#define GAIN_MAX
Definition: NoiseRemoval.cpp:611
EffectNoiseRemoval::mGains
ArraysOf< float > mGains
Definition: NoiseRemoval.h:118
ShuttleGuiBase::AddButton
wxButton * AddButton(const TranslatableString &Text, int PositionFlags=wxALIGN_CENTRE, bool setDefault=false)
Definition: ShuttleGui.cpp:360
LoadEffects.h
samplePtr
char * samplePtr
Definition: SampleFormat.h:49
ShuttleGuiBase::StartStatic
wxStaticBox * StartStatic(const TranslatableString &Str, int iProp=0)
Definition: ShuttleGui.cpp:893
EffectNoiseRemoval::mHistoryLen
size_t mHistoryLen
Definition: NoiseRemoval.h:114
EffectNoiseRemoval::Process
bool Process() override
Definition: NoiseRemoval.cpp:206
WaveTrack::GetMaxBlockSize
size_t GetMaxBlockSize() const
Definition: WaveTrack.cpp:1661
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
wxDialogWrapper
Definition: wxPanelWrapper.h:81
EffectNoiseRemoval::mImagFFTs
ArraysOf< float > mImagFFTs
Definition: NoiseRemoval.h:120
ID_GAIN_SLIDER
@ ID_GAIN_SLIDER
Definition: NoiseRemoval.cpp:598
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
EffectNoiseRemoval::mAttackDecayBlocks
int mAttackDecayBlocks
Definition: NoiseRemoval.h:109
EffectNoiseRemoval::ApplyFreqSmoothing
void ApplyFreqSmoothing(float *spec)
Definition: NoiseRemoval.cpp:244
EffectNoiseRemoval::mSpectrumSize
size_t mSpectrumSize
Definition: NoiseRemoval.h:70
BuiltinEffectsModule::Registration
Definition: LoadEffects.h:40
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
EffectNoiseRemoval::hFFT
HFFT hFFT
Definition: NoiseRemoval.h:104
EffectNoiseRemoval::ShowInterface
bool ShowInterface(wxWindow &parent, const EffectDialogFactory &factory, bool forceModal=false) override
Definition: NoiseRemoval.cpp:156
EffectNoiseRemoval::mFreqSmoothingHz
double mFreqSmoothingHz
Definition: NoiseRemoval.h:80
EffectNoiseRemoval::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: NoiseRemoval.cpp:116
anonymous_namespace{NoiseRemoval.cpp}::Rotate
void Rotate(ArraysOf< float > &arrays, size_t historyLen)
Definition: NoiseRemoval.cpp:391
EffectNoiseRemoval::StartNewTrack
void StartNewTrack()
Definition: NoiseRemoval.cpp:326
NoiseRemovalDialog::TransferDataToWindow
bool TransferDataToWindow() override
Definition: NoiseRemoval.cpp:774
NoiseRemovalDialog::m_pEffect
EffectNoiseRemoval * m_pEffect
Definition: NoiseRemoval.h:166
NoiseRemovalDialog::mKeepSignal
wxRadioButton * mKeepSignal
Definition: NoiseRemoval.h:172
NoiseRemovalDialog::mTime
double mTime
Definition: NoiseRemoval.h:188
EffectNoiseRemoval::SupportsAutomation
bool SupportsAutomation() override
Definition: NoiseRemoval.cpp:133
NoiseRemovalDialog::mGain
double mGain
Definition: NoiseRemoval.h:186
TrapLong
long TrapLong(long x, long min, long max)
Definition: Effect.h:575
M_PI
#define M_PI
Definition: Distortion.cpp:29
Effect::GetNumWaveTracks
int GetNumWaveTracks()
Definition: Effect.h:345
GetFFT
HFFT GetFFT(size_t fftlen)
Definition: RealFFTf.cpp:105
WaveTrack::GetBestBlockSize
size_t GetBestBlockSize(sampleCount t) const
Definition: WaveTrack.cpp:1643
ID_RADIOBUTTON_KEEPSIGNAL
@ ID_RADIOBUTTON_KEEPSIGNAL
Definition: NoiseRemoval.cpp:595
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:238
ShuttleGuiBase::AddVariableText
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:463
NoiseRemovalDialog::OnTimeText
void OnTimeText(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:815
EffectNoiseRemoval::mNoiseGain
double mNoiseGain
Definition: NoiseRemoval.h:81
EffectNoiseRemoval::mSpectrums
ArraysOf< float > mSpectrums
Definition: NoiseRemoval.h:117
ShuttleGuiBase::EndStatic
void EndStatic()
Definition: ShuttleGui.cpp:922
EffectType
EffectType
Definition: EffectInterface.h:55
ID_SENSITIVITY_TEXT
@ ID_SENSITIVITY_TEXT
Definition: NoiseRemoval.cpp:601
NoiseRemovalDialog
Dialog used with EffectNoiseRemoval.
Definition: NoiseRemoval.h:134
NoiseRemovalDialog::mSensitivityS
wxSlider * mSensitivityS
Definition: NoiseRemoval.h:175
ShuttleGuiBase::SetStretchyCol
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:202
EffectNoiseRemoval::RotateHistoryWindows
void RotateHistoryWindows()
Definition: NoiseRemoval.cpp:401
limitSampleBufferSize
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:23
NoiseRemovalDialog::OnSensitivityText
void OnSensitivityText(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:797
NoiseRemovalDialog::OnGetProfile
void OnGetProfile(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:656
EffectNoiseRemoval::~EffectNoiseRemoval
virtual ~EffectNoiseRemoval()
Definition: NoiseRemoval.cpp:110
anonymous_namespace{NoiseRemoval.cpp}::reg
BuiltinEffectsModule::Registration< EffectNoiseRemoval > reg
Definition: NoiseRemoval.cpp:81
END_EVENT_TABLE
END_EVENT_TABLE()
Effect::TrackProgress
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={})
Definition: Effect.cpp:2025
EffectNoiseRemoval::mRealFFTs
ArraysOf< float > mRealFFTs
Definition: NoiseRemoval.h:119
ArrayOf< float >
NoiseRemovalDialog::m_pButton_RemoveNoise
wxButton * m_pButton_RemoveNoise
Definition: NoiseRemoval.h:170
NoiseRemovalDialog::mFreqS
wxSlider * mFreqS
Definition: NoiseRemoval.h:177
EffectNoiseRemoval::FillFirstHistoryWindow
void FillFirstHistoryWindow()
Definition: NoiseRemoval.cpp:372
NoiseRemovalDialog::mTimeT
wxTextCtrl * mTimeT
Definition: NoiseRemoval.h:183
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
NoiseRemovalDialog::mbLeaveNoise
bool mbLeaveNoise
Definition: NoiseRemoval.h:190
EffectNoiseRemoval::Init
bool Init() override
Definition: NoiseRemoval.cpp:141
ID_FREQ_SLIDER
@ ID_FREQ_SLIDER
Definition: NoiseRemoval.cpp:599
NoiseRemovalDialog::OnGainText
void OnGainText(wxCommandEvent &event)
Definition: NoiseRemoval.cpp:803
EffectNoiseRemoval::mSensitivityFactor
float mSensitivityFactor
Definition: NoiseRemoval.h:112
EffectNoiseRemoval::mSampleRate
double mSampleRate
Definition: NoiseRemoval.h:68