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

📄 soundtoucheffect.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  SoundTouchEffect.cpp  Dominic Mazzoni, Vaughan Johnson  This abstract class contains all of the common code for an  effect that uses SoundTouch to do its processing (ChangeTempo  and ChangePitch).**********************************************************************/#include "../Audacity.h"#if USE_SOUNDTOUCH#include <math.h>#include "SoundTouchEffect.h"#include "../WaveTrack.h"bool EffectSoundTouch::Process(){   // Assumes that mSoundTouch has already been initialized   // by the subclass for subclass-specific parameters.   //Iterate over each track   TrackListIterator iter(mWaveTracks);   WaveTrack* leftTrack = (WaveTrack*)(iter.First());   WaveTrack* rightTrack = NULL;   mCurTrackNum = 0;	m_maxNewLength = 0.0;   while (leftTrack) {      //Get start and end times from track      double trackStart = leftTrack->GetStartTime();      double trackEnd = leftTrack->GetEndTime();      //Set the current bounds to whichever left marker is      //greater and whichever right marker is less:      mCurT0 = mT0 < trackStart? trackStart: mT0;      mCurT1 = mT1 > trackEnd? trackEnd: mT1;      // Process only if the right marker is to the right of the left marker      if (mCurT1 > mCurT0) {         //Transform the marker timepoints to samples         longSampleCount start = leftTrack->TimeToLongSamples(mCurT0);         longSampleCount end = leftTrack->TimeToLongSamples(mCurT1);                  rightTrack = NULL;          if (leftTrack->GetLinked()) {            rightTrack = (WaveTrack*)(iter.Next());            mSoundTouch->setChannels(2);            if (!ProcessStereo(leftTrack, rightTrack, start, end))               return false;            mCurTrackNum++; // Increment for rightTrack, too.         } else {            mSoundTouch->setChannels(1);            //ProcessOne() (implemented below) processes a single track            if (!ProcessOne(leftTrack, start, end))               return false;         }      }            //Iterate to the next track      leftTrack = (WaveTrack*)(iter.Next());      mCurTrackNum++;   }   delete mSoundTouch;   mSoundTouch = NULL;	mT1 = mT0 + m_maxNewLength; // Update selection.   return true;}//ProcessOne() takes a track, transforms it to bunch of buffer-blocks,//and executes ProcessSoundTouch on these blocksbool EffectSoundTouch::ProcessOne(WaveTrack *track,                                  longSampleCount start, longSampleCount end){   WaveTrack *outputTrack;   longSampleCount s;   mSoundTouch->setSampleRate((unsigned int)(track->GetRate()+0.5));      outputTrack = mFactory->NewWaveTrack(track->GetSampleFormat());   //Get the length of the buffer (as double). len is   //used simple to calculate a progress meter, so it is easier   //to make it a double now than it is to do it later    double len = (double)(end - start);   //Initiate a processing buffer.  This buffer will (most likely)   //be shorter than the length of the track being processed.   float *buffer = new float[track->GetMaxBlockSize()];   //Go through the track one buffer at a time. s counts which   //sample the current buffer starts at.   s = start;   while (s < end) {      //Get a block of samples (smaller than the size of the buffer)      sampleCount block = track->GetBestBlockSize(s);      //Adjust the block size if it is the final block in the track      if (s + block > end)         block = end - s;      //Get the samples from the track and put them in the buffer      track->Get((samplePtr) buffer, floatSample, s, block);      //Add samples to SoundTouch      mSoundTouch->putSamples(buffer, block);      //Get back samples from SoundTouch      unsigned int outputCount = mSoundTouch->numSamples();      if (outputCount > 0) {         float *buffer2 = new float[outputCount];         mSoundTouch->receiveSamples(buffer2, outputCount);         outputTrack->Append((samplePtr)buffer2, floatSample, outputCount);         delete[] buffer2;      }      //Increment s one blockfull of samples      s += block;      //Update the Progress meter      if (TrackProgress(mCurTrackNum, (s - start) / len))         return false;   }   // Tell SoundTouch to finish processing any remaining samples   mSoundTouch->flush();   unsigned int outputCount = mSoundTouch->numSamples();   if (outputCount > 0) {      float *buffer2 = new float[outputCount];      mSoundTouch->receiveSamples(buffer2, outputCount);      outputTrack->Append((samplePtr)buffer2, floatSample, outputCount);      delete[] buffer2;   }   // Flush the output WaveTrack (since it's buffered, too)   outputTrack->Flush();   // Clean up the buffer   delete[]buffer;   // Take the output track and insert it in place of the original   // sample data   track->Clear(mT0, mT1);   track->Paste(mT0, outputTrack);	double newLength = outputTrack->GetEndTime(); 	if (newLength > m_maxNewLength) 		m_maxNewLength = newLength;    // Delete the outputTrack now that its data is inserted in place   delete outputTrack;   //Return true because the effect processing succeeded.   return true;}bool EffectSoundTouch::ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack,                                        longSampleCount start, longSampleCount end){   mSoundTouch->setSampleRate((unsigned int)(leftTrack->GetRate()+0.5));      WaveTrack* outputLeftTrack = mFactory->NewWaveTrack(leftTrack->GetSampleFormat());   WaveTrack* outputRightTrack = mFactory->NewWaveTrack(rightTrack->GetSampleFormat());   //Get the length of the buffer (as double). len is   //used simple to calculate a progress meter, so it is easier   //to make it a double now than it is to do it later    double len = (double)(end - start);   //Initiate a processing buffer.  This buffer will (most likely)   //be shorter than the length of the track being processed.   // Make soundTouchBuffer twice as big as MaxBlockSize for each channel,    // because Soundtouch wants them interleaved, i.e., each    // Soundtouch sample is left-right pair.    sampleCount maxBlockSize = leftTrack->GetMaxBlockSize();   float* leftBuffer = new float[maxBlockSize];   float* rightBuffer = new float[maxBlockSize];   float* soundTouchBuffer = new float[maxBlockSize * 2];   // Go through the track one stereo buffer at a time.    // sourceSampleCount counts the sample at which the current buffer starts,    // per channel.   longSampleCount sourceSampleCount = start;   while (sourceSampleCount < end) {      //Get a block of samples (smaller than the size of the buffer)      sampleCount blockSize = leftTrack->GetBestBlockSize(sourceSampleCount);      //Adjust the block size if it is the final block in the track      if (sourceSampleCount + blockSize > end)         blockSize = end - sourceSampleCount;      // Get the samples from the tracks and put them in the buffers.      leftTrack->Get((samplePtr)(leftBuffer), floatSample, sourceSampleCount, blockSize);      rightTrack->Get((samplePtr)(rightBuffer), floatSample, sourceSampleCount, blockSize);      // Interleave into soundTouchBuffer.      for (int index = 0; index < blockSize; index++) {         soundTouchBuffer[index*2]       = leftBuffer[index];         soundTouchBuffer[(index*2)+1]   = rightBuffer[index];      }      //Add samples to SoundTouch      mSoundTouch->putSamples(soundTouchBuffer, blockSize);      //Get back samples from SoundTouch      unsigned int outputCount = mSoundTouch->numSamples();      if (outputCount > 0)          this->ProcessStereoResults(outputCount, outputLeftTrack, outputRightTrack);      //Increment sourceSampleCount one blockfull of samples      sourceSampleCount += blockSize;      //Update the Progress meter      if (TrackProgress(mCurTrackNum, (sourceSampleCount - start) / len))         return false;   }   // Tell SoundTouch to finish processing any remaining samples   mSoundTouch->flush();   unsigned int outputCount = mSoundTouch->numSamples();   if (outputCount > 0)       this->ProcessStereoResults(outputCount, outputLeftTrack, outputRightTrack);   // Flush the output WaveTracks (since they're buffered, too)   outputLeftTrack->Flush();   outputRightTrack->Flush();   // Clean up the buffers.   delete [] leftBuffer;   delete [] rightBuffer;   delete [] soundTouchBuffer;   // Take the output tracks and insert in place of the original   // sample data.   leftTrack->Clear(mT0, mT1);   leftTrack->Paste(mT0, outputLeftTrack);   rightTrack->Clear(mT0, mT1);   rightTrack->Paste(mT0, outputRightTrack);	double newLength = outputLeftTrack->GetEndTime(); 	if (newLength > m_maxNewLength) 		m_maxNewLength = newLength;    // Delete the outputTracks now that their data are inserted in place.   delete outputLeftTrack;   delete outputRightTrack;   //Return true because the effect processing succeeded.   return true;}bool EffectSoundTouch::ProcessStereoResults(const unsigned int outputCount,                                             WaveTrack* outputLeftTrack,                                             WaveTrack* outputRightTrack){   float* outputSoundTouchBuffer = new float[outputCount*2];   mSoundTouch->receiveSamples(outputSoundTouchBuffer, outputCount);   // Dis-interleave outputSoundTouchBuffer into separate track buffers.   float* outputLeftBuffer = new float[outputCount];   float* outputRightBuffer = new float[outputCount];   for (unsigned int index = 0; index < outputCount; index++)   {      outputLeftBuffer[index] = outputSoundTouchBuffer[index*2];      outputRightBuffer[index] = outputSoundTouchBuffer[(index*2)+1];   }   outputLeftTrack->Append((samplePtr)outputLeftBuffer, floatSample, outputCount);   outputRightTrack->Append((samplePtr)outputRightBuffer, floatSample, outputCount);   delete[] outputSoundTouchBuffer;   delete[] outputLeftBuffer;   delete[] outputRightBuffer;   return true;}#endif // USE_SOUNDTOUCH// Indentation settings for Vim and Emacs and unique identifier for Arch, a// version control system. Please do not modify past this point.//// Local Variables:// c-basic-offset: 3// indent-tabs-mode: nil// End://// vim: et sts=3 sw=3// arch-tag: 43212604-7b03-4b49-85bd-adde0f909460

⌨️ 快捷键说明

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