⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 noiseremoval.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  NoiseRemoval.cpp  Dominic Mazzoni  The noise is removed using noise gates on each frequency band in  the FFT, and the signal is reconstructed using overlap/add of  Hanning windows.**********************************************************************/#include "NoiseRemoval.h"#include "../Audacity.h"#include "../Envelope.h"#include "../FFT.h"#include "../WaveTrack.h"#include "../Prefs.h"#include "../Project.h"#include <math.h>#if defined(__WXMSW__) && !defined(__CYGWIN__)#include <float.h>#define finite(x) _finite(x)#endif#ifdef __MACOS9__#include <fp.h>#define finite(x) isfinite(x)#endif#include <wx/file.h>#include <wx/ffile.h>#include <wx/bitmap.h>#include <wx/brush.h>#include <wx/button.h>#include <wx/dcmemory.h>#include <wx/image.h>#include <wx/intl.h>#include <wx/msgdlg.h>#include <wx/sizer.h>#include <wx/statbox.h>#include <wx/stattext.h>#include "../AudacityApp.h"EffectNoiseRemoval::EffectNoiseRemoval(){   windowSize = 2048;   int halfWindowSize = windowSize / 2;   mNoiseGate = new float[windowSize];   sum = new float[windowSize];   sumsq = new float[windowSize];   profileCount = new int[windowSize];   smoothing = new float[windowSize];   mHasProfile = false;   // These two are safe to do, even if not in CleanSpeechMode   wxGetApp().SetCleanSpeechNoiseGate(mNoiseGate);   wxGetApp().SetCleanSpeechNoiseGateExpectedCount(halfWindowSize * sizeof(float));	CleanSpeechMayReadNoisegate();   Init();}EffectNoiseRemoval::~EffectNoiseRemoval(){   delete [] mNoiseGate;   delete [] sum;   delete [] sumsq;   delete [] profileCount;   delete [] smoothing;}void EffectNoiseRemoval::CleanSpeechMayReadNoisegate(){   int halfWindowSize = windowSize / 2;//lda-131a always try to get noisegate.nrp if in CleanSpeechMode and it exists	AudacityProject * project = GetActiveProject();   if (project == NULL) {      int mode = gPrefs->Read(wxT("/Batch/CleanSpeechMode"), 0L);      if (mode == 0) {         return;      }   }   // Try to open the file.   wxString filename = FILENAME(wxT("noisegate.nrp"));   // if file doesn't exist, return quietly.   if( !wxFile::Exists( filename ))      return;	wxFFile   noiseGateFile((const wxChar*)filename, (const wxChar*)wxT("rb"));   bool flag = noiseGateFile.IsOpened();   if (flag != true)      return;   // Now get its data.   int expectedCount = halfWindowSize * sizeof(float);   int count = noiseGateFile.Read(mNoiseGate, expectedCount);   noiseGateFile.Close();   if (count == expectedCount) {      for (int i = halfWindowSize; i < windowSize; ++i) {         mNoiseGate[i] = float(0.0);  // only half filled by Read      }      mHasProfile = true;      mDoProfile = false;   }}void EffectNoiseRemoval::CleanSpeechMayWriteNoiseGate(){	AudacityProject * project = GetActiveProject();	if( !project || !project->GetCleanSpeechMode() )      return;   wxFFile   noiseGateFile((const wxChar*)FILENAME(wxT("noisegate.nrp")), (const wxChar*)wxT("wb"));   bool flag = noiseGateFile.IsOpened();   if (flag == true) {      int expectedCount = (windowSize / 2) * sizeof(float);      // FIX-ME: Should we check return value on Write?      noiseGateFile.Write(mNoiseGate, expectedCount);      noiseGateFile.Close();   }}#define MAX_NOISE_LEVEL  30bool EffectNoiseRemoval::Init(){   mLevel = gPrefs->Read(wxT("/CsPresets/Noise_Level"), 3L);   if ((mLevel < 0) || (mLevel > MAX_NOISE_LEVEL)) {  // corrupted Prefs?      mLevel = 0;  //Off-skip      gPrefs->Write(wxT("/CsPresets/Noise_Level"), mLevel);   }   return true;}bool EffectNoiseRemoval::CheckWhetherSkipEffect(){   bool rc = (mLevel == 0);   return rc;}bool EffectNoiseRemoval::PromptUser(){   NoiseRemovalDialog dlog(this, mParent, -1, _("Noise Removal"));   dlog.m_pSlider->SetValue(mLevel);   dlog.mLevel = mLevel;   if( !mHasProfile )   {   	CleanSpeechMayReadNoisegate();   }   // We may want to twiddle the levels if we are setting   // from an automation dialog, the only case in which we can   // get here without any wavetracks.   bool bAllowTwiddleSettings = (mWaveTracks==NULL);    if (mHasProfile || bAllowTwiddleSettings ) {      dlog.m_pButton_Preview->Enable(mWaveTracks != NULL);		dlog.m_pButton_RemoveNoise->SetDefault();		dlog.m_pButton_RemoveNoise->SetFocus();	} else {      dlog.m_pSlider->Enable(false);      dlog.m_pButton_Preview->Enable(false);      dlog.m_pButton_RemoveNoise->Enable(false);   }   dlog.CentreOnParent();   dlog.ShowModal();      if (dlog.GetReturnCode() == 0) {      return false;   }   mLevel = dlog.m_pSlider->GetValue();   gPrefs->Write(wxT("/CsPresets/Noise_Level"), mLevel);  //lda-131a make persistent   mDoProfile = (dlog.GetReturnCode() == 1);   return true;}   bool EffectNoiseRemoval::TransferParameters( Shuttle & shuttle ){     shuttle.TransferInt(wxT("Level"),mLevel,1);   return true;}bool EffectNoiseRemoval::Process(){	// If we are creating a profile, we don't care whether we have	// one already.  We just prepare the counters.   if (mDoProfile) {      for(int i=0; i<windowSize; i++) {         sum[i] = float(0.0);         sumsq[i] = float(0.0);         profileCount[i] = 0;      }   }	else	{		// We need a profile.      if( !mHasProfile )      {         CleanSpeechMayReadNoisegate();      }   	   // If we still don't have a profile we have a problem.      if( !mHasProfile)      {         wxMessageBox( _("Attempt to run Noise Removal without a noise profile\n.") );         return false;      }	}	// This same code will both remove noise and	// profile it, depending on 'mDoProfile'   TrackListIterator iter(mWaveTracks);   WaveTrack *track = (WaveTrack *) iter.First();   int count = 0;   while (track) {      double trackStart = track->GetStartTime();      double trackEnd = track->GetEndTime();      double t0 = mT0 < trackStart? trackStart: mT0;      double t1 = mT1 > trackEnd? trackEnd: mT1;      if (t1 > t0) {         longSampleCount start = track->TimeToLongSamples(t0);         longSampleCount end = track->TimeToLongSamples(t1);         sampleCount len = (sampleCount)(end - start);         if (!ProcessOne(count, track, start, len)){            return false;	      }      }      track = (WaveTrack *) iter.Next();      count++;   }   if (mDoProfile) {      for(int i=0; i<=windowSize/2; i++) {         //float stddev = sqrt(sumsq[i] - (sum[i]*sum[i])/profileCount[i])         //                               / profileCount[i];         mNoiseGate[i] = sum[i] / profileCount[i]; // average      }		CleanSpeechMayWriteNoiseGate();      mHasProfile = true;      mDoProfile = false;   }   return true;}bool EffectNoiseRemoval::ProcessOne(int count, WaveTrack * track,                                    longSampleCount start, sampleCount len){   bool retCode = true;   sampleCount s = 0;   sampleCount idealBlockLen = track->GetMaxBlockSize() * 4;   if (idealBlockLen % windowSize != 0)      idealBlockLen += (windowSize - (idealBlockLen % windowSize));      float *buffer = new float[idealBlockLen];      float *window1 = new float[windowSize];   float *window2 = new float[windowSize];   float *thisWindow = window1;   float *lastWindow = window2;      int i;      for(i=0; i<windowSize; i++) {      lastWindow[i] = 0;      smoothing[i] = float(0.0);   }      while((s < len)&&((len-s)>(windowSize/2))) {      sampleCount block = idealBlockLen;      if (s + block > len)         block = len - s;            track->Get((samplePtr) buffer, floatSample, start + s, block);            for(i=0; i<(block-windowSize/2); i+=windowSize/2) {         int wcopy = windowSize;         if (i + wcopy > block)            wcopy = block - i;                  int j;         for(j=0; j<wcopy; j++)            thisWindow[j] = buffer[i+j];         for(j=wcopy; j<windowSize; j++)            thisWindow[j] = 0;                  if (mDoProfile)            GetProfile(windowSize, thisWindow);         else {				//TIDY-ME: could we just test mLevel=<0 in CheckWhetherSkipEffect?            if (mLevel > 0) { // Skip NoiseRemoval if zero ... may apply for CleanChain            RemoveNoise(windowSize, thisWindow);               for(j=0; j<windowSize/2; j++) {               	buffer[i+j] = thisWindow[j] + lastWindow[windowSize/2 + j];         		}            }         }                  float *tempP = thisWindow;         thisWindow = lastWindow;         lastWindow = tempP;      }            // Shift by half-a-window less than the block size we loaded      // (so that the blocks properly overlap)      block -= windowSize/2;      if (!mDoProfile)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -