diff --git a/src/effects/AutoDuck.cpp b/src/effects/AutoDuck.cpp index 566651874..e1fb8100e 100644 --- a/src/effects/AutoDuck.cpp +++ b/src/effects/AutoDuck.cpp @@ -50,8 +50,8 @@ Param( MaximumPause, double, XO("MaximumPause"), 1.0, 0.0, DB * Common constants */ -enum : size_t { kBufSize = 131072 }; // number of samples to process at once -enum : size_t { kRMSWindowSize = 100 }; // samples in circular RMS window buffer +static const size_t kBufSize = 131072u; // number of samples to process at once +static const size_t kRMSWindowSize = 100u; // samples in circular RMS window buffer /* * A auto duck region and an array of auto duck regions @@ -286,103 +286,99 @@ bool EffectAutoDuck::Process() int rmsPos = 0; float rmsSum = 0; - float *rmsWindow = new float[kRMSWindowSize]; - for (size_t i = 0; i < kRMSWindowSize; i++) - rmsWindow[i] = 0; - - float *buf = new float[kBufSize]; - - bool inDuckRegion = false; - - // initialize the following two variables to prevent compiler warning - double duckRegionStart = 0; - sampleCount curSamplesPause = 0; - // to make the progress bar appear more natural, we first look for all // duck regions and apply them all at once afterwards AutoDuckRegionArray regions; - auto pos = start; - - while (pos < end) + bool inDuckRegion = false; { - const auto len = limitSampleBufferSize( kBufSize, end - pos ); + Floats rmsWindow{ kRMSWindowSize, true }; - mControlTrack->Get((samplePtr)buf, floatSample, pos, len); + Floats buf{ kBufSize }; - for (auto i = pos; i < pos + len; i++) + // initialize the following two variables to prevent compiler warning + double duckRegionStart = 0; + sampleCount curSamplesPause = 0; + + auto pos = start; + + while (pos < end) { - rmsSum -= rmsWindow[rmsPos]; - // i - pos is bounded by len: - auto index = ( i - pos ).as_size_t(); - rmsWindow[rmsPos] = buf[ index ] * buf[ index ]; - rmsSum += rmsWindow[rmsPos]; - rmsPos = (rmsPos + 1) % kRMSWindowSize; + const auto len = limitSampleBufferSize( kBufSize, end - pos ); + + mControlTrack->Get((samplePtr)buf.get(), floatSample, pos, len); - bool thresholdExceeded = rmsSum > threshold; - - if (thresholdExceeded) + for (auto i = pos; i < pos + len; i++) { - // everytime the threshold is exceeded, reset our count for - // the number of pause samples - curSamplesPause = 0; + rmsSum -= rmsWindow[rmsPos]; + // i - pos is bounded by len: + auto index = ( i - pos ).as_size_t(); + rmsWindow[rmsPos] = buf[ index ] * buf[ index ]; + rmsSum += rmsWindow[rmsPos]; + rmsPos = (rmsPos + 1) % kRMSWindowSize; - if (!inDuckRegion) + bool thresholdExceeded = rmsSum > threshold; + + if (thresholdExceeded) { - // the threshold has been exceeded for the first time, so - // let the duck region begin here - inDuckRegion = true; - duckRegionStart = mControlTrack->LongSamplesToTime(i); + // everytime the threshold is exceeded, reset our count for + // the number of pause samples + curSamplesPause = 0; + + if (!inDuckRegion) + { + // the threshold has been exceeded for the first time, so + // let the duck region begin here + inDuckRegion = true; + duckRegionStart = mControlTrack->LongSamplesToTime(i); + } + } + + if (!thresholdExceeded && inDuckRegion) + { + // the threshold has not been exceeded and we are in a duck + // region, but only fade in if the maximum pause has been + // exceeded + curSamplesPause += 1; + + if (curSamplesPause >= minSamplesPause) + { + // do the actual duck fade and reset all values + double duckRegionEnd = + mControlTrack->LongSamplesToTime(i - curSamplesPause); + + regions.Add(AutoDuckRegion( + duckRegionStart - mOuterFadeDownLen, + duckRegionEnd + mOuterFadeUpLen)); + + inDuckRegion = false; + } } } - if (!thresholdExceeded && inDuckRegion) - { - // the threshold has not been exceeded and we are in a duck - // region, but only fade in if the maximum pause has been - // exceeded - curSamplesPause += 1; + pos += len; - if (curSamplesPause >= minSamplesPause) - { - // do the actual duck fade and reset all values - double duckRegionEnd = - mControlTrack->LongSamplesToTime(i - curSamplesPause); - - regions.Add(AutoDuckRegion( - duckRegionStart - mOuterFadeDownLen, - duckRegionEnd + mOuterFadeUpLen)); - - inDuckRegion = false; - } - } - } - - pos += len; - - if (TotalProgress( + if (TotalProgress( (pos - start).as_double() / (end - start).as_double() / (GetNumWaveTracks() + 1) - )) + )) + { + cancel = true; + break; + } + } + + // apply last duck fade, if any + if (inDuckRegion) { - cancel = true; - break; + double duckRegionEnd = + mControlTrack->LongSamplesToTime(end - curSamplesPause); + regions.Add(AutoDuckRegion( + duckRegionStart - mOuterFadeDownLen, + duckRegionEnd + mOuterFadeUpLen)); } } - // apply last duck fade, if any - if (inDuckRegion) - { - double duckRegionEnd = - mControlTrack->LongSamplesToTime(end - curSamplesPause); - regions.Add(AutoDuckRegion( - duckRegionStart - mOuterFadeDownLen, - duckRegionEnd + mOuterFadeUpLen)); - } - - delete[] buf; - delete[] rmsWindow; - if (!cancel) { CopyInputTracks(); // Set up mOutputTracks. @@ -518,7 +514,7 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t, auto start = t->TimeToLongSamples(t0); auto end = t->TimeToLongSamples(t1); - float *buf = new float[kBufSize]; + Floats buf{ kBufSize }; auto pos = start; auto fadeDownSamples = t->TimeToLongSamples( @@ -538,7 +534,7 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t, { const auto len = limitSampleBufferSize( kBufSize, end - pos ); - t->Get((samplePtr)buf, floatSample, pos, len); + t->Get((samplePtr)buf.get(), floatSample, pos, len); for (auto i = pos; i < pos + len; i++) { @@ -557,7 +553,7 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t, buf[ ( i - pos ).as_size_t() ] *= DB_TO_LINEAR(gain); } - t->Set((samplePtr)buf, floatSample, pos, len); + t->Set((samplePtr)buf.get(), floatSample, pos, len); pos += len; @@ -571,7 +567,6 @@ bool EffectAutoDuck::ApplyDuckFade(int trackNumber, WaveTrack* t, } } - delete[] buf; return cancel; } diff --git a/src/effects/Biquad.h b/src/effects/Biquad.h index 5115f46ad..788bb4a4e 100644 --- a/src/effects/Biquad.h +++ b/src/effects/Biquad.h @@ -1,14 +1,14 @@ #ifndef __BIQUAD_H__ #define __BIQUAD_H__ typedef struct { - float* pfIn; - float* pfOut; - float fNumerCoeffs [3]; // B0 B1 B2 - float fDenomCoeffs [2]; // A1 A2 - float fPrevIn; - float fPrevPrevIn; - float fPrevOut; - float fPrevPrevOut; + float* pfIn {}; + float* pfOut {}; + float fNumerCoeffs [3] { 1.0f, 0.0f, 0.0f }; // B0 B1 B2 + float fDenomCoeffs [2] { 0.0f, 0.0f }; // A1 A2 + float fPrevIn {}; + float fPrevPrevIn {}; + float fPrevOut {}; + float fPrevPrevOut {}; } BiquadStruct; void Biquad_Process (BiquadStruct* pBQ, int iNumSamples); void ComplexDiv (float fNumerR, float fNumerI, float fDenomR, float fDenomI, float* pfQuotientR, float* pfQuotientI); diff --git a/src/effects/ChangePitch.cpp b/src/effects/ChangePitch.cpp index a2d98bf78..56b5c7817 100644 --- a/src/effects/ChangePitch.cpp +++ b/src/effects/ChangePitch.cpp @@ -420,22 +420,15 @@ void EffectChangePitch::DeduceFrequencies() auto start = track->TimeToLongSamples(t0); auto analyzeSize = windowSize * numWindows; - float * buffer; - buffer = new float[analyzeSize]; + Floats buffer{ analyzeSize }; - float * freq; - freq = new float[windowSize / 2]; + Floats freq{ windowSize / 2 }; + Floats freqa{ windowSize / 2, true }; - float * freqa; - freqa = new float[windowSize / 2]; - - for(size_t j = 0; j < windowSize / 2; j++) - freqa[j] = 0; - - track->Get((samplePtr) buffer, floatSample, start, analyzeSize); + track->Get((samplePtr) buffer.get(), floatSample, start, analyzeSize); for(unsigned i = 0; i < numWindows; i++) { - ComputeSpectrum(buffer + i * windowSize, windowSize, - windowSize, rate, freq, true); + ComputeSpectrum(buffer.get() + i * windowSize, windowSize, + windowSize, rate, freq.get(), true); for(size_t j = 0; j < windowSize / 2; j++) freqa[j] += freq[j]; } @@ -444,10 +437,6 @@ void EffectChangePitch::DeduceFrequencies() if (freqa[j] > freqa[argmax]) argmax = j; - delete [] freq; - delete [] freqa; - delete [] buffer; - auto lag = (windowSize / 2 - 1) - argmax; m_dStartFrequency = rate / lag; } diff --git a/src/effects/ChangeSpeed.cpp b/src/effects/ChangeSpeed.cpp index 4188220c3..17fb84cfe 100644 --- a/src/effects/ChangeSpeed.cpp +++ b/src/effects/ChangeSpeed.cpp @@ -485,11 +485,11 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track, // the length of the selection being processed. auto inBufferSize = track->GetMaxBlockSize(); - float * inBuffer = new float[inBufferSize]; + Floats inBuffer{ inBufferSize }; // mFactor is at most 100-fold so this shouldn't overflow size_t auto outBufferSize = size_t( mFactor * inBufferSize + 10 ); - float * outBuffer = new float[outBufferSize]; + Floats outBuffer{ outBufferSize }; // Set up the resampling stuff for this track. Resample resample(true, mFactor, mFactor); // constant rate resampling @@ -506,18 +506,18 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track, ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr) inBuffer, floatSample, samplePos, blockSize); + track->Get((samplePtr) inBuffer.get(), floatSample, samplePos, blockSize); const auto results = resample.Process(mFactor, - inBuffer, + inBuffer.get(), blockSize, ((samplePos + blockSize) >= end), - outBuffer, + outBuffer.get(), outBufferSize); const auto outgen = results.second; if (outgen > 0) - outputTrack->Append((samplePtr)outBuffer, floatSample, + outputTrack->Append((samplePtr)outBuffer.get(), floatSample, outgen); // Increment samplePos @@ -533,10 +533,6 @@ bool EffectChangeSpeed::ProcessOne(WaveTrack * track, // Flush the output WaveTrack (since it's buffered, too) outputTrack->Flush(); - // Clean up the buffers - delete [] inBuffer; - delete [] outBuffer; - // Take the output track and insert it in place of the original // sample data double newLength = outputTrack->GetEndTime(); diff --git a/src/effects/ClickRemoval.cpp b/src/effects/ClickRemoval.cpp index 3baa65615..d096e86fb 100644 --- a/src/effects/ClickRemoval.cpp +++ b/src/effects/ClickRemoval.cpp @@ -214,13 +214,13 @@ bool EffectClickRemoval::ProcessOne(int count, WaveTrack * track, sampleCount st bool bResult = true; decltype(len) s = 0; - float *buffer = new float[idealBlockLen]; - float *datawindow = new float[windowSize]; + Floats buffer{ idealBlockLen }; + Floats datawindow{ windowSize }; while ((len - s) > windowSize / 2) { auto block = limitSampleBufferSize( idealBlockLen, len - s ); - track->Get((samplePtr) buffer, floatSample, start + s, block); + track->Get((samplePtr) buffer.get(), floatSample, start + s, block); for (decltype(block) i = 0; i + windowSize / 2 < block; i += windowSize / 2) { @@ -231,14 +231,14 @@ bool EffectClickRemoval::ProcessOne(int count, WaveTrack * track, sampleCount st for(auto j = wcopy; j < windowSize; j++) datawindow[j] = 0; - mbDidSomething |= RemoveClicks(windowSize, datawindow); + mbDidSomething |= RemoveClicks(windowSize, datawindow.get()); for(decltype(wcopy) j = 0; j < wcopy; j++) buffer[i+j] = datawindow[j]; } if (mbDidSomething) // RemoveClicks() actually did something. - track->Set((samplePtr) buffer, floatSample, start + s, block); + track->Set((samplePtr) buffer.get(), floatSample, start + s, block); s += block; @@ -249,13 +249,10 @@ bool EffectClickRemoval::ProcessOne(int count, WaveTrack * track, sampleCount st } } - delete[] buffer; - delete[] datawindow; - return bResult; } -bool EffectClickRemoval::RemoveClicks(int len, float *buffer) +bool EffectClickRemoval::RemoveClicks(size_t len, float *buffer) { bool bResult = false; // This effect usually does nothing. int i; @@ -265,8 +262,8 @@ bool EffectClickRemoval::RemoveClicks(int len, float *buffer) float msw; int ww; int s2 = sep/2; - float *ms_seq = new float[len]; - float *b2 = new float[len]; + Floats ms_seq{ len }; + Floats b2{ len }; for( i=0; i 0) { - mFollow1 = new float[maxlen]; - mFollow2 = new float[maxlen]; + mFollow1.reinit(maxlen); + mFollow2.reinit(maxlen); } mFollowLen = maxlen; @@ -426,7 +400,7 @@ bool EffectCompressor::TwoBufferProcessPass1 // buffer2 is NULL on the last and only the last call if(buffer2 != NULL) { - Follow(buffer2, mFollow2, len2, mFollow1, len1); + Follow(buffer2, mFollow2.get(), len2, mFollow1.get(), len1); } if(buffer1 != NULL) { @@ -442,9 +416,7 @@ bool EffectCompressor::TwoBufferProcessPass1 #endif // Rotate the buffer pointers - float *tmpfloat = mFollow1; - mFollow1 = mFollow2; - mFollow2 = tmpfloat; + mFollow1.swap(mFollow2); return true; } @@ -465,7 +437,7 @@ void EffectCompressor::FreshenCircle() // Recompute the RMS sum periodically to prevent accumulation of rounding errors // during long waveforms mRMSSum = 0; - for(int i=0; i(requestedHistLen.as_long_long()))) throw std::bad_alloc{}; - history = new float[histLen]; + history.reinit(histLen, true); } catch ( const std::bad_alloc& ) { wxMessageBox(_("Requested value exceeds memory capacity.")); return false; } - memset(history, 0, sizeof(float) * histLen); - return history != NULL; } bool EffectEcho::ProcessFinalize() { - delete [] history; - + history.reset(); return true; } diff --git a/src/effects/Echo.h b/src/effects/Echo.h index a74b17a47..0b18709b4 100644 --- a/src/effects/Echo.h +++ b/src/effects/Echo.h @@ -17,6 +17,7 @@ #include #include "Effect.h" +#include "../SampleFormat.h" class ShuttleGui; @@ -58,7 +59,7 @@ private: private: double delay; double decay; - float *history; + Floats history; size_t histPos; size_t histLen; }; diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 9cd91036c..5d56b8065 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -213,14 +213,14 @@ BEGIN_EVENT_TABLE(EffectEqualization, wxEvtHandler) END_EVENT_TABLE() EffectEqualization::EffectEqualization() + : mFFTBuffer{ windowSize } + , mFilterFuncR{ windowSize } + , mFilterFuncI{ windowSize } { mCurve = NULL; mPanel = NULL; hFFT = InitializeFFT(windowSize); - mFFTBuffer = new float[windowSize]; - mFilterFuncR = new float[windowSize]; - mFilterFuncI = new float[windowSize]; SetLinearEffectFlag(true); @@ -285,15 +285,6 @@ EffectEqualization::~EffectEqualization() if(hFFT) EndFFT(hFFT); hFFT = NULL; - if(mFFTBuffer) - delete[] mFFTBuffer; - mFFTBuffer = NULL; - if(mFilterFuncR) - delete[] mFilterFuncR; - if(mFilterFuncI) - delete[] mFilterFuncI; - mFilterFuncR = NULL; - mFilterFuncI = NULL; } // IdentInterface implementation @@ -386,11 +377,11 @@ bool EffectEqualization::ValidateUI() //(done in a hurry, may not be the neatest -MJS) if (mDirty && !mDrawMode) { - int numPoints = mLogEnvelope->GetNumberOfPoints(); - double *when = new double[numPoints]; - double *value = new double[numPoints]; - mLogEnvelope->GetPoints(when, value, numPoints); - for (int i = 0, j = 0; j < numPoints - 2; i++, j++) + size_t numPoints = mLogEnvelope->GetNumberOfPoints(); + Doubles when{ numPoints }; + Doubles value{ numPoints }; + mLogEnvelope->GetPoints(when.get(), value.get(), numPoints); + for (size_t i = 0, j = 0; j + 2 < numPoints; i++, j++) { if ((value[i] < value[i + 1] + .05) && (value[i] > value[i + 1] - .05) && (value[i + 1] < value[i + 2] + .05) && (value[i + 1] > value[i + 2] - .05)) @@ -400,8 +391,6 @@ bool EffectEqualization::ValidateUI() j--; } } - delete [] when; - delete [] value; Select((int) mCurves.GetCount() - 1); } SaveCurves(); @@ -528,12 +517,14 @@ bool EffectEqualization::Init() bool EffectEqualization::Process() { #ifdef EXPERIMENTAL_EQ_SSE_THREADED - if(mEffectEqualization48x) + if(mEffectEqualization48x) { if(mBench) { mBench=false; return mEffectEqualization48x->Benchmark(this); - } else + } + else return mEffectEqualization48x->Process(this); + } #endif this->CopyInputTracks(); // Set up mOutputTracks. bool bGoodResult = true; @@ -1039,7 +1030,7 @@ bool EffectEqualization::TransferDataFromWindow() mPanel->Refresh(false); } - int m = 2 * mMSlider->GetValue() + 1; // odd numbers only + size_t m = 2 * mMSlider->GetValue() + 1; // odd numbers only if (m != mM) { mM = m; ForceRecalc(); @@ -1069,12 +1060,12 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t, if (idealBlockLen % L != 0) idealBlockLen += (L - (idealBlockLen % L)); - float *buffer = new float[idealBlockLen]; + Floats buffer{ idealBlockLen }; - float *window1 = new float[windowSize]; - float *window2 = new float[windowSize]; - float *thisWindow = window1; - float *lastWindow = window2; + Floats window1{ windowSize }; + Floats window2{ windowSize }; + float *thisWindow = window1.get(); + float *lastWindow = window2.get(); auto originalLen = len; @@ -1090,7 +1081,7 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t, { auto block = limitSampleBufferSize( idealBlockLen, len ); - t->Get((samplePtr)buffer, floatSample, s, block); + t->Get((samplePtr)buffer.get(), floatSample, s, block); for(size_t i = 0; i < block; i += L) //go through block in lumps of length L { @@ -1113,7 +1104,7 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t, lastWindow = tempP; } //next i, lump of this block - output->Append((samplePtr)buffer, floatSample, block); + output->Append((samplePtr)buffer.get(), floatSample, block); len -= block; s += block; @@ -1142,7 +1133,7 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t, for(size_t j = 0; j < mM - 1; j++) buffer[j] = lastWindow[wcopy + j]; } - output->Append((samplePtr)buffer, floatSample, mM - 1); + output->Append((samplePtr)buffer.get(), floatSample, mM - 1); output->Flush(); // now move the appropriate bit of the output back to the track @@ -1208,10 +1199,6 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t, } } - delete[] buffer; - delete[] window1; - delete[] window2; - return bLoopSuccess; } @@ -1277,9 +1264,9 @@ bool EffectEqualization::CalcFilter() } //transfer to time domain to do the padding and windowing - float *outr = new float[mWindowSize]; - float *outi = new float[mWindowSize]; - InverseRealFFT(mWindowSize, mFilterFuncR, NULL, outr); // To time domain + Floats outr{ mWindowSize }; + Floats outi{ mWindowSize }; + InverseRealFFT(mWindowSize, mFilterFuncR.get(), NULL, outr.get()); // To time domain { size_t i = 0; @@ -1302,7 +1289,7 @@ bool EffectEqualization::CalcFilter() outr[mWindowSize - i] = 0; } } - float *tempr = new float[mM]; + Floats tempr{ mM }; { size_t i = 0; for(; i < (mM - 1) / 2; i++) @@ -1313,21 +1300,17 @@ bool EffectEqualization::CalcFilter() tempr[(mM - 1) / 2 + i] = outr[i]; } - for(size_t i = 0; i < mM; i++) + for (size_t i = 0; i < mM; i++) { //and copy useful values back outr[i] = tempr[i]; } - for(size_t i = mM; i < mWindowSize; i++) + for (size_t i = mM; i < mWindowSize; i++) { //rest is padding outr[i]=0.; } //Back to the frequency domain so we can use it - RealFFT(mWindowSize, outr, mFilterFuncR, mFilterFuncI); - - delete[] outr; - delete[] outi; - delete[] tempr; + RealFFT(mWindowSize, outr.get(), mFilterFuncR.get(), mFilterFuncI.get()); return TRUE; } @@ -1353,8 +1336,8 @@ void EffectEqualization::Filter(size_t len, float *buffer) mFFTBuffer[1] = buffer[1] * mFilterFuncR[len/2]; // Inverse FFT and normalization - InverseRealFFTf(mFFTBuffer, hFFT); - ReorderToTime(hFFT, mFFTBuffer, buffer); + InverseRealFFTf(mFFTBuffer.get(), hFFT); + ReorderToTime(hFFT, mFFTBuffer.get(), buffer); } // @@ -1855,10 +1838,10 @@ void EffectEqualization::EnvelopeUpdated() void EffectEqualization::EnvelopeUpdated(Envelope *env, bool lin) { // Allocate and populate point arrays - int numPoints = env->GetNumberOfPoints(); - double *when = new double[ numPoints ]; - double *value = new double[ numPoints ]; - env->GetPoints( when, value, numPoints ); + size_t numPoints = env->GetNumberOfPoints(); + Doubles when{ numPoints }; + Doubles value{ numPoints }; + env->GetPoints( when.get(), value.get(), numPoints ); // Clear the unnamed curve int curve = mCurves.GetCount()-1; @@ -1867,8 +1850,7 @@ void EffectEqualization::EnvelopeUpdated(Envelope *env, bool lin) if(lin) { // Copy and convert points - int point; - for( point = 0; point < numPoints; point++ ) + for (size_t point = 0; point < numPoints; point++) { double freq = when[ point ] * mHiFreq; double db = value[ point ]; @@ -1884,8 +1866,7 @@ void EffectEqualization::EnvelopeUpdated(Envelope *env, bool lin) double denom = hiLog - loLog; // Copy and convert points - int point; - for( point = 0; point < numPoints; point++ ) + for (size_t point = 0; point < numPoints; point++) { double freq = pow( 10., ( ( when[ point ] * denom ) + loLog )); double db = value[ point ]; @@ -1899,10 +1880,6 @@ void EffectEqualization::EnvelopeUpdated(Envelope *env, bool lin) // set 'unnamed' as the selected curve Select( (int) mCurves.GetCount()-1 ); - - // Clean up - delete [] when; - delete [] value; } // @@ -1925,7 +1902,7 @@ void EffectEqualization::Flatten() ForceRecalc(); if( !mDrawMode ) { - for( int i=0; i< mBandsInUse; i++) + for( size_t i = 0; i < mBandsInUse; i++) { mSliders[i]->SetValue(0); mSlidersOld[i] = 0; @@ -2154,13 +2131,13 @@ void EffectEqualization::UpdateCurves() void EffectEqualization::UpdateDraw() { - int numPoints = mLogEnvelope->GetNumberOfPoints(); - double *when = new double[ numPoints ]; - double *value = new double[ numPoints ]; + size_t numPoints = mLogEnvelope->GetNumberOfPoints(); + Doubles when{ numPoints }; + Doubles value{ numPoints }; double deltadB = 0.1; double dx, dy, dx1, dy1, err; - mLogEnvelope->GetPoints( when, value, numPoints ); + mLogEnvelope->GetPoints( when.get(), value.get(), numPoints ); // set 'unnamed' as the selected curve EnvelopeUpdated(); @@ -2170,8 +2147,8 @@ void EffectEqualization::UpdateDraw() { flag = false; int numDeleted = 0; - mLogEnvelope->GetPoints( when, value, numPoints ); - for(int j=0;jGetPoints( when.get(), value.get(), numPoints ); + for (size_t j = 0; j + 2 < numPoints; j++) { dx = when[j+2+numDeleted] - when[j+numDeleted]; dy = value[j+2+numDeleted] - value[j+numDeleted]; @@ -2187,8 +2164,6 @@ void EffectEqualization::UpdateDraw() } } } - delete [] when; - delete [] value; if(mLin) // do not use IsLinear() here { @@ -2230,7 +2205,7 @@ void EffectEqualization::UpdateGraphic() mFreqRuler->ruler.SetRange(mLoFreq, mHiFreq); } - for (int i = 0; i < mBandsInUse; i++) + for (size_t i = 0; i < mBandsInUse; i++) { if( kThirdOct[i] == mLoFreq ) mWhenSliders[i] = 0.; @@ -2243,7 +2218,7 @@ void EffectEqualization::UpdateGraphic() mEQVals[i] = -20.; } ErrMin(); //move sliders to minimise error - for (int i = 0; i < mBandsInUse; i++) + for (size_t i = 0; i < mBandsInUse; i++) { mSliders[i]->SetValue(lrint(mEQVals[i])); //actually set slider positions mSlidersOld[i] = mSliders[i]->GetValue(); @@ -2281,52 +2256,49 @@ void EffectEqualization::UpdateGraphic() void EffectEqualization::EnvLogToLin(void) { - int numPoints = mLogEnvelope->GetNumberOfPoints(); + size_t numPoints = mLogEnvelope->GetNumberOfPoints(); if( numPoints == 0 ) { return; } - double *when = new double[ numPoints ]; - double *value = new double[ numPoints ]; + Doubles when{ numPoints }; + Doubles value{ numPoints }; mLinEnvelope->Flatten(0.); mLinEnvelope->SetTrackLen(1.0); - mLogEnvelope->GetPoints( when, value, numPoints ); + mLogEnvelope->GetPoints( when.get(), value.get(), numPoints ); mLinEnvelope->Move(0., value[0]); double loLog = log10(20.); double hiLog = log10(mHiFreq); double denom = hiLog - loLog; - for( int i=0; i < numPoints; i++) + for (size_t i = 0; i < numPoints; i++) mLinEnvelope->Insert(pow( 10., ((when[i] * denom) + loLog))/mHiFreq , value[i]); mLinEnvelope->Move(1., value[numPoints-1]); - - delete [] when; - delete [] value; } void EffectEqualization::EnvLinToLog(void) { - int numPoints = mLinEnvelope->GetNumberOfPoints(); + size_t numPoints = mLinEnvelope->GetNumberOfPoints(); if( numPoints == 0 ) { return; } - double *when = new double[ numPoints ]; - double *value = new double[ numPoints ]; + Doubles when{ numPoints }; + Doubles value{ numPoints }; mLogEnvelope->Flatten(0.); mLogEnvelope->SetTrackLen(1.0); - mLinEnvelope->GetPoints( when, value, numPoints ); + mLinEnvelope->GetPoints( when.get(), value.get(), numPoints ); mLogEnvelope->Move(0., value[0]); double loLog = log10(20.); double hiLog = log10(mHiFreq); double denom = hiLog - loLog; bool changed = false; - for( int i=0; i < numPoints; i++) + for (size_t i = 0; i < numPoints; i++) { if( when[i]*mHiFreq >= 20 ) { @@ -2344,9 +2316,6 @@ void EffectEqualization::EnvLinToLog(void) } mLogEnvelope->Move(1., value[numPoints-1]); - delete [] when; - delete [] value; - if(changed) EnvelopeUpdated(mLogEnvelope.get(), false); } @@ -2354,13 +2323,12 @@ void EffectEqualization::EnvLinToLog(void) void EffectEqualization::ErrMin(void) { double vals[NUM_PTS]; - int i; double error = 0.0; double oldError = 0.0; double mEQValsOld = 0.0; double correction = 1.6; bool flag; - int j=0; + size_t j=0; Envelope testEnvelope; testEnvelope.SetInterpolateDB(false); testEnvelope.SetRange(-120.0, 60.0); @@ -2368,13 +2336,13 @@ void EffectEqualization::ErrMin(void) testEnvelope.SetTrackLen(1.0); testEnvelope.CopyFrom(mLogEnvelope.get(), 0.0, 1.0); - for(i=0; i < NUM_PTS; i++) + for(size_t i = 0; i < NUM_PTS; i++) vals[i] = testEnvelope.GetValue(mWhens[i]); // Do error minimisation error = 0.; GraphicEQ(&testEnvelope); - for(i=0; i < NUM_PTS; i++) //calc initial error + for(size_t i = 0; i < NUM_PTS; i++) //calc initial error { double err = vals[i] - testEnvelope.GetValue(mWhens[i]); error += err*err; @@ -2382,7 +2350,7 @@ void EffectEqualization::ErrMin(void) oldError = error; while( j < mBandsInUse*12 ) //loop over the sliders a number of times { - i = j%mBandsInUse; //use this slider + auto i = j % mBandsInUse; //use this slider if( (j > 0) & (i == 0) ) // if we've come back to the first slider again... { if( correction > 0 ) @@ -2408,7 +2376,7 @@ void EffectEqualization::ErrMin(void) } GraphicEQ(&testEnvelope); //calculate envelope error = 0.; - for(int k=0; k < NUM_PTS; k++) //calculate error + for(size_t k = 0; k < NUM_PTS; k++) //calculate error { double err = vals[k] - testEnvelope.GetValue(mWhens[k]); error += err*err; @@ -2448,7 +2416,7 @@ void EffectEqualization::GraphicEQ(Envelope *env) case kBspline: // B-spline { int minF = 0; - for(int i=0; i 0 ); + + double p, sig; + Doubles u{ n }; y2[0] = 0.; // u[0] = 0.; //'natural' boundary conditions - for(i=1;i=0;i--) + y2[n - 1] = 0.; + for (size_t i = n - 1; i--;) y2[i] = y2[i]*y2[i+1] + u[i]; - - delete [] u; } -double EffectEqualization::splint(double x[], double y[], int n, double y2[], double xr) +double EffectEqualization::splint(double x[], double y[], size_t n, double y2[], double xr) { + wxASSERT( n > 1 ); + double a, b, h; static double xlast = 0.; // remember last x value requested - static int k = 0; // and which interval we were in + static size_t k = 0; // and which interval we were in if( xr < xlast ) k = 0; // gone back to start, (or somewhere to the left) xlast = xr; - while( (x[k] <= xr) && (k < n-1) ) + while( (x[k] <= xr) && (k + 1 < n) ) k++; + wxASSERT( k > 0 ); k--; h = x[k+1] - x[k]; a = ( x[k+1] - xr )/h; @@ -2631,7 +2602,7 @@ void EffectEqualization::OnErase(wxEraseEvent & WXUNUSED(event)) void EffectEqualization::OnSlider(wxCommandEvent & event) { wxSlider *s = (wxSlider *)event.GetEventObject(); - for (int i = 0; i < mBandsInUse; i++) + for (size_t i = 0; i < mBandsInUse; i++) { if( s == mSliders[i]) { @@ -2741,7 +2712,7 @@ void EffectEqualization::OnInvert(wxCommandEvent & WXUNUSED(event)) // Inverts a { if(!mDrawMode) // Graphic (Slider) mode. Invert the sliders. { - for (int i = 0; i < mBandsInUse; i++) + for (size_t i = 0; i < mBandsInUse; i++) { mEQVals[i] = -mEQVals[i]; int newPosn = (int)mEQVals[i]; @@ -2760,7 +2731,7 @@ void EffectEqualization::OnInvert(wxCommandEvent & WXUNUSED(event)) // Inverts a else // Draw mode. Invert the points. { bool lin = IsLinear(); // refers to the 'log' or 'lin' of the frequency scale, not the amplitude - int numPoints; // number of points in the curve/envelope + size_t numPoints; // number of points in the curve/envelope // determine if log or lin curve is the current one // and find out how many points are in the curve @@ -2776,16 +2747,16 @@ void EffectEqualization::OnInvert(wxCommandEvent & WXUNUSED(event)) // Inverts a if( numPoints == 0 ) return; - double *when = new double[ numPoints ]; - double *value = new double[ numPoints ]; + Doubles when{ numPoints }; + Doubles value{ numPoints }; if(lin) - mLinEnvelope->GetPoints( when, value, numPoints ); + mLinEnvelope->GetPoints( when.get(), value.get(), numPoints ); else - mLogEnvelope->GetPoints( when, value, numPoints ); + mLogEnvelope->GetPoints( when.get(), value.get(), numPoints ); // invert the curve - for( int i=0; i < numPoints; i++) + for (size_t i = 0; i < numPoints; i++) { if(lin) mLinEnvelope->Move(when[i] , -value[i]); @@ -2793,9 +2764,6 @@ void EffectEqualization::OnInvert(wxCommandEvent & WXUNUSED(event)) // Inverts a mLogEnvelope->Move(when[i] , -value[i]); } - delete [] when; - delete [] value; - // copy it back to the other one (just in case) if(lin) EnvLinToLog(); @@ -2882,9 +2850,6 @@ EqualizationPanel::EqualizationPanel(EffectEqualization *effect, wxWindow *paren { mParent = parent; mEffect = effect; - - mOutr = NULL; - mOuti = NULL; mBitmap = NULL; mWidth = 0; @@ -2899,11 +2864,6 @@ EqualizationPanel::EqualizationPanel(EffectEqualization *effect, wxWindow *paren EqualizationPanel::~EqualizationPanel() { - if (mOuti) - delete [] mOuti; - if (mOutr) - delete [] mOutr; - if(HasCapture()) ReleaseMouse(); } @@ -2916,16 +2876,11 @@ void EqualizationPanel::ForceRecalc() void EqualizationPanel::Recalc() { - if (mOutr) - delete [] mOutr; - mOutr = new float[mEffect->mWindowSize]; - - if (mOuti) - delete [] mOuti; - mOuti = new float[mEffect->mWindowSize]; + mOutr = Floats{ mEffect->mWindowSize }; + mOuti = Floats{ mEffect->mWindowSize }; mEffect->CalcFilter(); //to calculate the actual response - InverseRealFFT(mEffect->mWindowSize, mEffect->mFilterFuncR, mEffect->mFilterFuncI, mOutr); + InverseRealFFT(mEffect->mWindowSize, mEffect->mFilterFuncR.get(), mEffect->mFilterFuncI.get(), mOutr.get()); } void EqualizationPanel::OnSize(wxSizeEvent & WXUNUSED(event)) @@ -2995,37 +2950,38 @@ void EqualizationPanel::OnPaint(wxPaintEvent & WXUNUSED(event)) } // Med-blue envelope line - memDC.SetPen(wxPen(theTheme.Colour( clrGraphLines ), 3, wxSOLID)); + memDC.SetPen(wxPen(theTheme.Colour(clrGraphLines), 3, wxSOLID)); // Draw envelope - double *values = new double[mEnvRect.width]; - mEffect->mEnvelope->GetValues(values, mEnvRect.width, 0.0, 1.0/mEnvRect.width); int x, y, xlast = 0, ylast = 0; - bool off = false, off1 = false; - for(int i=0; imdBMax-values[i])/(mEffect->mdBMax-mEffect->mdBMin)) + .25 ); //needs more optimising, along with'what you get'? - if( y >= mEnvRect.height) + Doubles values{ size_t(mEnvRect.width) }; + mEffect->mEnvelope->GetValues(values.get(), mEnvRect.width, 0.0, 1.0 / mEnvRect.width); + bool off = false, off1 = false; + for (int i = 0; i < mEnvRect.width; i++) { - y = mEnvRect.height - 1; - off = true; + x = mEnvRect.x + i; + y = lrint(mEnvRect.height*((mEffect->mdBMax - values[i]) / (mEffect->mdBMax - mEffect->mdBMin)) + .25); //needs more optimising, along with'what you get'? + if (y >= mEnvRect.height) + { + y = mEnvRect.height - 1; + off = true; + } + else + { + off = false; + off1 = false; + } + if ((i != 0) & (!off1)) + { + AColor::Line(memDC, xlast, ylast, + x, mEnvRect.y + y); + } + off1 = off; + xlast = x; + ylast = mEnvRect.y + y; } - else - { - off = false; - off1 = false; - } - if ( (i != 0) & (!off1) ) - { - AColor::Line(memDC, xlast, ylast, - x, mEnvRect.y + y); - } - off1 = off; - xlast = x; - ylast = mEnvRect.y + y; } - delete[] values; //Now draw the actual response that you will get. //mFilterFunc has a linear scale, window has a log one so we have to fiddle about diff --git a/src/effects/Equalization.h b/src/effects/Equalization.h index 9be3d2da4..2a644231a 100644 --- a/src/effects/Equalization.h +++ b/src/effects/Equalization.h @@ -41,6 +41,7 @@ #include "../widgets/Grid.h" #include "../widgets/Ruler.h" #include "../RealFFTf.h" +#include "../SampleFormat.h" #define EQUALIZATION_PLUGIN_SYMBOL XO("Equalization") @@ -125,7 +126,7 @@ private: // EffectEqualization implementation // Number of samples in an FFT window - enum : size_t {windowSize=16384}; //MJS - work out the optimum for this at run time? Have a dialog box for it? + static const size_t windowSize = 16384u; //MJS - work out the optimum for this at run time? Have a dialog box for it? // Low frequency of the FFT. 20Hz is the // low range of human hearing @@ -166,8 +167,8 @@ private: void EnvLinToLog(void); void ErrMin(void); void GraphicEQ(Envelope *env); - void spline(double x[], double y[], int n, double y2[]); - double splint(double x[], double y[], int n, double y2[], double xr); + void spline(double x[], double y[], size_t n, double y2[]); + double splint(double x[], double y[], size_t n, double y2[], double xr); void OnSize( wxSizeEvent & event ); void OnErase( wxEraseEvent & event ); @@ -191,9 +192,7 @@ private: private: HFFT hFFT; - float *mFFTBuffer; - float *mFilterFuncR; - float *mFilterFuncI; + Floats mFFTBuffer, mFilterFuncR, mFilterFuncI; size_t mM; wxString mCurveName; bool mLin; @@ -205,7 +204,7 @@ private: double mWhens[NUM_PTS]; double mWhenSliders[NUMBER_OF_BANDS+1]; - int mBandsInUse; + size_t mBandsInUse; RulerPanel *mdBRuler; RulerPanel *mFreqRuler; @@ -320,8 +319,7 @@ private: // size_t mWindowSize; // float *mFilterFuncR; // float *mFilterFuncI; - float *mOutr; - float *mOuti; + Floats mOutr, mOuti; // double mLoFreq; // double mHiFreq; diff --git a/src/effects/Equalization48x.cpp b/src/effects/Equalization48x.cpp index babbad567..8bb4d6b51 100644 --- a/src/effects/Equalization48x.cpp +++ b/src/effects/Equalization48x.cpp @@ -169,7 +169,7 @@ void free_simd(void* mem) EffectEqualization48x::EffectEqualization48x(): mThreadCount(0),mFilterSize(0),mWindowSize(0),mBlockSize(0),mWorkerDataCount(0),mBlocksPerBuffer(20), - mScratchBufferSize(0),mSubBufferSize(0),mBigBuffer(NULL),mBufferInfo(NULL),mEQWorkers(0),mThreaded(false), + mScratchBufferSize(0),mSubBufferSize(0),mBigBuffer(NULL),mThreaded(false), mBenching(false),mBufferCount(0) { } @@ -213,7 +213,7 @@ bool EffectEqualization48x::AllocateBuffersWorkers(int nThreads) mSubBufferSize=mBlockSize*(mBufferCount*(mBlocksPerBuffer-1)); // we are going to do a full block overlap mBigBuffer=(float *)malloc_simd(sizeof(float)*(mSubBufferSize+mFilterSize+mScratchBufferSize)*mWorkerDataCount); // we run over by filtersize // fill the bufferInfo - mBufferInfo = new BufferInfo[mWorkerDataCount]; + mBufferInfo.reinit(mWorkerDataCount); for(int i=0;iGetMaxBlockSize(); - float *buffer1 = new float[trackBlockSize]; - float *buffer2 = new float[trackBlockSize]; + Floats buffer1{ trackBlockSize }; + Floats buffer2{ trackBlockSize }; AudacityProject *p = GetActiveProject(); auto output=p->GetTrackFactory()->NewWaveTrack(floatSample, t->GetRate()); @@ -425,16 +423,14 @@ bool EffectEqualization48x::DeltaTrack(WaveTrack * t, WaveTrack * t2, sampleCoun while(len > 0) { auto curretLength = limitSampleBufferSize(trackBlockSize, len); - t->Get((samplePtr)buffer1, floatSample, currentSample, curretLength); - t2->Get((samplePtr)buffer2, floatSample, currentSample, curretLength); + t->Get((samplePtr)buffer1.get(), floatSample, currentSample, curretLength); + t2->Get((samplePtr)buffer2.get(), floatSample, currentSample, curretLength); for(decltype(curretLength) i=0;iAppend((samplePtr)buffer1, floatSample, curretLength); + output->Append((samplePtr)buffer1.get(), floatSample, curretLength); currentSample+=curretLength; len-=curretLength; } - delete[] buffer1; - delete[] buffer2; output->Flush(); len=originalLen; ProcessTail(t, output.get(), start, len); @@ -669,7 +665,7 @@ bool EffectEqualization48x::ProcessOne1x(int count, WaveTrack * t, } currentSample-=mBlockSize+(mFilterSize>>1); - ProcessBuffer1x(mBufferInfo); + ProcessBuffer1x(mBufferInfo.get()); bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigRun)/bigRuns.as_double()); if( bBreakLoop ) break; @@ -850,7 +846,7 @@ bool EffectEqualization48x::ProcessOne4x(int count, WaveTrack * t, } currentSample-=mBlockSize+(mFilterSize>>1); - ProcessBuffer4x(mBufferInfo); + ProcessBuffer4x(mBufferInfo.get()); bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigRun)/bigRuns.as_double()); if( bBreakLoop ) break; diff --git a/src/effects/Equalization48x.h b/src/effects/Equalization48x.h index f80605fdb..61a493e15 100644 --- a/src/effects/Equalization48x.h +++ b/src/effects/Equalization48x.h @@ -14,6 +14,8 @@ Intrinsics (SSE/AVX) and Threaded Equalization #include "../Experimental.h" #ifdef EXPERIMENTAL_EQ_SSE_THREADED +#include "../MemoryX.h" + #ifdef __AVX_ENABLED #define __MAXBUFFERCOUNT 8 #else @@ -155,9 +157,9 @@ private: size_t mScratchBufferSize; size_t mSubBufferSize; float *mBigBuffer; - BufferInfo* mBufferInfo; + ArrayOf mBufferInfo; wxMutex mDataMutex; - EQWorker* mEQWorkers; + ArrayOf mEQWorkers; bool mThreaded; bool mBenching; friend EQWorker; diff --git a/src/effects/FindClipping.cpp b/src/effects/FindClipping.cpp index 511eeb143..492578f0a 100644 --- a/src/effects/FindClipping.cpp +++ b/src/effects/FindClipping.cpp @@ -95,7 +95,6 @@ bool EffectFindClipping::Process() { std::shared_ptr addedTrack; Maybe modifiedTrack; - //Track *original = NULL; const wxString name{ _("Clipping") }; LabelTrack *lt = NULL; @@ -158,19 +157,19 @@ bool EffectFindClipping::ProcessOne(LabelTrack * lt, return true; } - float *buffer; + Floats buffer; try { if (blockSize < mStart) // overflow throw std::bad_alloc{}; - buffer = new float[blockSize]; + buffer.reinit(blockSize); } catch( const std::bad_alloc & ) { wxMessageBox(_("Requested value exceeds memory capacity.")); return false; } - float *ptr = buffer; + float *ptr = buffer.get(); decltype(len) s = 0, startrun = 0, stoprun = 0, samps = 0; decltype(blockSize) block = 0; @@ -187,8 +186,8 @@ bool EffectFindClipping::ProcessOne(LabelTrack * lt, block = limitSampleBufferSize( blockSize, len - s ); - wt->Get((samplePtr)buffer, floatSample, start + s, block); - ptr = buffer; + wt->Get((samplePtr)buffer.get(), floatSample, start + s, block); + ptr = buffer.get(); } float v = fabs(*ptr++); @@ -226,8 +225,6 @@ bool EffectFindClipping::ProcessOne(LabelTrack * lt, block--; } - delete [] buffer; - return bGoodResult; } diff --git a/src/effects/NoiseRemoval.cpp b/src/effects/NoiseRemoval.cpp index effefc33c..345b4502b 100644 --- a/src/effects/NoiseRemoval.cpp +++ b/src/effects/NoiseRemoval.cpp @@ -100,14 +100,13 @@ EffectNoiseRemoval::EffectNoiseRemoval() mHasProfile = false; mDoProfile = true; - mNoiseThreshold = new float[mSpectrumSize]; + mNoiseThreshold.reinit(mSpectrumSize); Init(); } EffectNoiseRemoval::~EffectNoiseRemoval() { - delete [] mNoiseThreshold; } // IdentInterface implementation @@ -247,10 +246,10 @@ bool EffectNoiseRemoval::Process() void EffectNoiseRemoval::ApplyFreqSmoothing(float *spec) { - float *tmp = new float[mSpectrumSize]; - int i, j, j0, j1; + Floats tmp{ mSpectrumSize }; + int j, j0, j1; - for(i = 0; i < mSpectrumSize; i++) { + for(int i = 0; i < mSpectrumSize; i++) { j0 = wxMax(0, i - mFreqSmoothingBins); j1 = wxMin(mSpectrumSize-1, i + mFreqSmoothingBins); tmp[i] = 0.0; @@ -260,16 +259,12 @@ void EffectNoiseRemoval::ApplyFreqSmoothing(float *spec) tmp[i] /= (j1 - j0 + 1); } - for(i = 0; i < mSpectrumSize; i++) + for(size_t i = 0; i < mSpectrumSize; i++) spec[i] = tmp[i]; - - delete[] tmp; } void EffectNoiseRemoval::Initialize() { - int i; - mSampleRate = mProjectRate; mFreqSmoothingBins = (int)(mFreqSmoothingHz * mWindowSize / mSampleRate); mAttackDecayBlocks = 1 + @@ -287,68 +282,52 @@ void EffectNoiseRemoval::Initialize() if (mHistoryLen < mMinSignalBlocks) mHistoryLen = mMinSignalBlocks; - mSpectrums = new float*[mHistoryLen]; - mGains = new float*[mHistoryLen]; - mRealFFTs = new float*[mHistoryLen]; - mImagFFTs = new float*[mHistoryLen]; - for(i = 0; i < mHistoryLen; i++) { - mSpectrums[i] = new float[mSpectrumSize]; - mGains[i] = new float[mSpectrumSize]; - mRealFFTs[i] = new float[mSpectrumSize]; - mImagFFTs[i] = new float[mSpectrumSize]; - } + mSpectrums.reinit(mHistoryLen, mSpectrumSize); + mGains.reinit(mHistoryLen, mSpectrumSize); + mRealFFTs.reinit(mHistoryLen, mSpectrumSize); + mImagFFTs.reinit(mHistoryLen, mSpectrumSize); // Initialize the FFT hFFT = InitializeFFT(mWindowSize); - mFFTBuffer = new float[mWindowSize]; - mInWaveBuffer = new float[mWindowSize]; - mWindow = new float[mWindowSize]; - mOutOverlapBuffer = new float[mWindowSize]; + mFFTBuffer.reinit(mWindowSize); + mInWaveBuffer.reinit(mWindowSize); + mWindow.reinit(mWindowSize); + mOutOverlapBuffer.reinit(mWindowSize); // Create a Hanning window function - for(i=0; iBitReversed[i] ]; mImagFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[i]+1]; mSpectrums[0][i] = mRealFFTs[0][i]*mRealFFTs[0][i] + mImagFFTs[0][i]*mImagFFTs[0][i]; @@ -413,30 +388,24 @@ void EffectNoiseRemoval::FillFirstHistoryWindow() mGains[0][mSpectrumSize-1] = mNoiseAttenFactor; } +namespace { + inline void Rotate(ArraysOf &arrays, size_t historyLen) + { + Floats temp = std::move( arrays[ historyLen - 1 ] ); + + for ( size_t nn = historyLen - 1; nn--; ) + arrays[ nn + 1 ] = std::move( arrays[ nn ] ); + arrays[0] = std::move( temp ); + } +} + void EffectNoiseRemoval::RotateHistoryWindows() { - int last = mHistoryLen - 1; - int i; - // Remember the last window so we can reuse it - float *lastSpectrum = mSpectrums[last]; - float *lastGain = mGains[last]; - float *lastRealFFT = mRealFFTs[last]; - float *lastImagFFT = mImagFFTs[last]; - - // Rotate each window forward - for(i = last; i >= 1; i--) { - mSpectrums[i] = mSpectrums[i-1]; - mGains[i] = mGains[i-1]; - mRealFFTs[i] = mRealFFTs[i-1]; - mImagFFTs[i] = mImagFFTs[i-1]; - } - - // Reuse the last buffers as the NEW first window - mSpectrums[0] = lastSpectrum; - mGains[0] = lastGain; - mRealFFTs[0] = lastRealFFT; - mImagFFTs[0] = lastImagFFT; + Rotate(mSpectrums, mHistoryLen); + Rotate(mGains, mHistoryLen); + Rotate(mRealFFTs, mHistoryLen); + Rotate(mImagFFTs, mHistoryLen); } void EffectNoiseRemoval::FinishTrack() @@ -447,16 +416,13 @@ void EffectNoiseRemoval::FinishTrack() // Well, not exactly, but not more than mWindowSize/2 extra samples at the end. // We'll DELETE them later in ProcessOne. - float *empty = new float[mWindowSize / 2]; - int i; - for(i = 0; i < mWindowSize / 2; i++) + Floats empty{ mWindowSize / 2 }; + for(size_t i = 0; i < mWindowSize / 2; i++) empty[i] = 0.0; while (mOutSampleCount < mInSampleCount) { - ProcessSamples(mWindowSize / 2, empty); + ProcessSamples(mWindowSize / 2, empty.get()); } - - delete [] empty; } void EffectNoiseRemoval::GetProfile() @@ -467,9 +433,9 @@ void EffectNoiseRemoval::GetProfile() int start = mHistoryLen - mMinSignalBlocks; int finish = mHistoryLen; - int i, j; + int i; - for (j = 0; j < mSpectrumSize; j++) { + for (size_t j = 0; j < mSpectrumSize; j++) { float min = mSpectrums[start][j]; for (i = start+1; i < finish; i++) { if (mSpectrums[i][j] < min) @@ -484,15 +450,14 @@ void EffectNoiseRemoval::GetProfile() void EffectNoiseRemoval::RemoveNoise() { - int center = mHistoryLen / 2; - int start = center - mMinSignalBlocks/2; - int finish = start + mMinSignalBlocks; - int i, j; + size_t center = mHistoryLen / 2; + size_t start = center - mMinSignalBlocks/2; + size_t finish = start + mMinSignalBlocks; // Raise the gain for elements in the center of the sliding history - for (j = 0; j < mSpectrumSize; j++) { + for (size_t j = 0; j < mSpectrumSize; j++) { float min = mSpectrums[start][j]; - for (i = start+1; i < finish; i++) { + for (size_t i = start+1; i < finish; i++) { if (mSpectrums[i][j] < min) min = mSpectrums[i][j]; } @@ -507,14 +472,14 @@ void EffectNoiseRemoval::RemoveNoise() // Decay the gain in both directions; // note that mOneBlockAttackDecay is less than 1.0 // of linear attenuation per block - for (j = 0; j < mSpectrumSize; j++) { - for (i = center + 1; i < mHistoryLen; i++) { + for (size_t j = 0; j < mSpectrumSize; j++) { + for (size_t i = center + 1; i < mHistoryLen; i++) { if (mGains[i][j] < mGains[i - 1][j] * mOneBlockAttackDecay) mGains[i][j] = mGains[i - 1][j] * mOneBlockAttackDecay; if (mGains[i][j] < mNoiseAttenFactor) mGains[i][j] = mNoiseAttenFactor; } - for (i = center - 1; i >= 0; i--) { + for (size_t i = center; i--;) { if (mGains[i][j] < mGains[i + 1][j] * mOneBlockAttackDecay) mGains[i][j] = mGains[i + 1][j] * mOneBlockAttackDecay; if (mGains[i][j] < mNoiseAttenFactor) @@ -526,10 +491,10 @@ void EffectNoiseRemoval::RemoveNoise() // Apply frequency smoothing to output gain int out = mHistoryLen - 1; // end of the queue - ApplyFreqSmoothing(mGains[out]); + ApplyFreqSmoothing(mGains[out].get()); // Apply gain to FFT - for (j = 0; j < (mSpectrumSize-1); j++) { + for (size_t j = 0; j < (mSpectrumSize-1); j++) { mFFTBuffer[j*2 ] = mRealFFTs[out][j] * mGains[out][j]; mFFTBuffer[j*2+1] = mImagFFTs[out][j] * mGains[out][j]; } @@ -537,10 +502,10 @@ void EffectNoiseRemoval::RemoveNoise() mFFTBuffer[1] = mRealFFTs[out][mSpectrumSize-1] * mGains[out][mSpectrumSize-1]; // Invert the FFT into the output buffer - InverseRealFFTf(mFFTBuffer, hFFT); + InverseRealFFTf(mFFTBuffer.get(), hFFT); // Overlap-add - for(j = 0; j < (mSpectrumSize-1); j++) { + for(size_t j = 0; j < (mSpectrumSize-1); j++) { mOutOverlapBuffer[j*2 ] += mFFTBuffer[hFFT->BitReversed[j] ] * mWindow[j*2 ]; mOutOverlapBuffer[j*2+1] += mFFTBuffer[hFFT->BitReversed[j]+1] * mWindow[j*2+1]; } @@ -548,11 +513,11 @@ void EffectNoiseRemoval::RemoveNoise() // Output the first half of the overlap buffer, they're done - // and then shift the next half over. if (mOutSampleCount >= 0) { // ...but not if it's the first half-window - mOutputTrack->Append((samplePtr)mOutOverlapBuffer, floatSample, + mOutputTrack->Append((samplePtr)mOutOverlapBuffer.get(), floatSample, mWindowSize / 2); } mOutSampleCount += mWindowSize / 2; - for(j = 0; j < mWindowSize / 2; j++) { + for(size_t j = 0; j < mWindowSize / 2; j++) { mOutOverlapBuffer[j] = mOutOverlapBuffer[j + (mWindowSize / 2)]; mOutOverlapBuffer[j + (mWindowSize / 2)] = 0.0; } @@ -571,7 +536,7 @@ bool EffectNoiseRemoval::ProcessOne(int count, WaveTrack * track, track->GetRate()); auto bufferSize = track->GetMaxBlockSize(); - float *buffer = new float[bufferSize]; + Floats buffer{ bufferSize }; bool bLoopSuccess = true; auto samplePos = start; @@ -584,10 +549,10 @@ bool EffectNoiseRemoval::ProcessOne(int count, WaveTrack * track, ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr)buffer, floatSample, samplePos, blockSize); + track->Get((samplePtr)buffer.get(), floatSample, samplePos, blockSize); mInSampleCount += blockSize; - ProcessSamples(blockSize, buffer); + ProcessSamples(blockSize, buffer.get()); samplePos += blockSize; @@ -599,7 +564,6 @@ bool EffectNoiseRemoval::ProcessOne(int count, WaveTrack * track, } FinishTrack(); - delete [] buffer; if (!mDoProfile) { // Flush the output WaveTrack (since it's buffered) diff --git a/src/effects/NoiseRemoval.h b/src/effects/NoiseRemoval.h index ba01f8139..ba13bb4dc 100644 --- a/src/effects/NoiseRemoval.h +++ b/src/effects/NoiseRemoval.h @@ -21,6 +21,7 @@ #include "Effect.h" #include "../MemoryX.h" +#include "../SampleFormat.h" #include #include @@ -70,12 +71,12 @@ private: // Parameters chosen before the first phase double mSampleRate; size_t mWindowSize; - int mSpectrumSize; + size_t mSpectrumSize; float mMinSignalTime; // in secs // The frequency-indexed noise threshold derived during the first // phase of analysis - float *mNoiseThreshold; // length is mSpectrumSize + Floats mNoiseThreshold; // length is mSpectrumSize // Parameters that affect the noise removal, regardless of how the // noise profile was extracted @@ -106,22 +107,22 @@ private: int mInputPos; HFFT hFFT; - float *mFFTBuffer; // mWindowSize - float *mWindow; // mWindowSize + Floats mFFTBuffer; // mWindowSize + Floats mWindow; // mWindowSize int mFreqSmoothingBins; int mAttackDecayBlocks; float mOneBlockAttackDecay; float mNoiseAttenFactor; float mSensitivityFactor; - int mMinSignalBlocks; - int mHistoryLen; - float *mInWaveBuffer; // mWindowSize - float *mOutOverlapBuffer; // mWindowSize - float **mSpectrums; // mHistoryLen x mSpectrumSize - float **mGains; // mHistoryLen x mSpectrumSize - float **mRealFFTs; // mHistoryLen x mWindowSize - float **mImagFFTs; // mHistoryLen x mWindowSize + size_t mMinSignalBlocks; + size_t mHistoryLen; + Floats mInWaveBuffer; // mWindowSize + Floats mOutOverlapBuffer; // mWindowSize + ArraysOf mSpectrums; // mHistoryLen x mSpectrumSize + ArraysOf mGains; // mHistoryLen x mSpectrumSize + ArraysOf mRealFFTs; // mHistoryLen x mWindowSize + ArraysOf mImagFFTs; // mHistoryLen x mWindowSize friend class NoiseRemovalDialog; }; diff --git a/src/effects/Normalize.cpp b/src/effects/Normalize.cpp index d2daf993b..db3626144 100644 --- a/src/effects/Normalize.cpp +++ b/src/effects/Normalize.cpp @@ -384,7 +384,7 @@ bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg, //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()]; + Floats buffer{ track->GetMaxBlockSize() }; mSum = 0.0; // dc offset inits mCount = 0; @@ -401,10 +401,10 @@ bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg, ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr) buffer, floatSample, s, block); + track->Get((samplePtr) buffer.get(), floatSample, s, block); //Process the buffer. - AnalyzeData(buffer, block); + AnalyzeData(buffer.get(), block); //Increment s one blockfull of samples s += block; @@ -417,9 +417,6 @@ bool EffectNormalize::AnalyseDC(const WaveTrack * track, const wxString &msg, } } - //Clean up the buffer - delete[] buffer; - offset = -mSum / mCount.as_double(); // calculate actual offset (amount that needs to be added on) //Return true because the effect processing succeeded ... unless cancelled @@ -446,7 +443,7 @@ bool EffectNormalize::ProcessOne( //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()]; + Floats buffer{ track->GetMaxBlockSize() }; //Go through the track one buffer at a time. s counts which //sample the current buffer starts at. @@ -460,13 +457,13 @@ bool EffectNormalize::ProcessOne( ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr) buffer, floatSample, s, block); + track->Get((samplePtr) buffer.get(), floatSample, s, block); //Process the buffer. - ProcessData(buffer, block, offset); + ProcessData(buffer.get(), block, offset); //Copy the newly-changed samples back onto the track. - track->Set((samplePtr) buffer, floatSample, s, block); + track->Set((samplePtr) buffer.get(), floatSample, s, block); //Increment s one blockfull of samples s += block; @@ -478,8 +475,6 @@ bool EffectNormalize::ProcessOne( break; } } - //Clean up the buffer - delete[] buffer; //Return true because the effect processing succeeded ... unless cancelled return rc; diff --git a/src/effects/Paulstretch.cpp b/src/effects/Paulstretch.cpp index 0ce554099..fda0397b4 100644 --- a/src/effects/Paulstretch.cpp +++ b/src/effects/Paulstretch.cpp @@ -45,7 +45,7 @@ public: //in_bufsize is also a half of a FFT buffer (in samples) virtual ~PaulStretch(); - void process(float *smps,int nsmps); + void process(float *smps, size_t nsmps); size_t get_nsamples();//how many samples are required to be added in the pool next time size_t get_nsamples_for_fill();//how many samples are required to be added for a complete buffer refill (at start of the song or after seek) @@ -59,24 +59,20 @@ private: public: const size_t out_bufsize; - float *const out_buf; + const Floats out_buf; private: - float *const old_out_smp_buf; + const Floats old_out_smp_buf; public: const size_t poolsize;//how many samples are inside the input_pool size (need to know how many samples to fill when seeking) private: - float *const in_pool;//de marimea in_bufsize + const Floats in_pool;//de marimea in_bufsize double remained_samples;//how many fraction of samples has remained (0..1) - float *const fft_smps; - float *const fft_c; - float *const fft_s; - float *const fft_freq; - float *const fft_tmp; + const Floats fft_smps, fft_c, fft_s, fft_freq, fft_tmp; }; // @@ -329,58 +325,59 @@ bool EffectPaulstretch::ProcessOne(WaveTrack *track,double t0,double t1,int coun auto nget = stretch.get_nsamples_for_fill(); auto bufsize = stretch.poolsize; - float *buffer0 = new float[bufsize]; - float *bufferptr0 = buffer0; + Floats buffer0{ bufsize }; + float *bufferptr0 = buffer0.get(); bool first_time = true; const auto fade_len = std::min(100, bufsize / 2 - 1); - float *fade_track_smps = new float[fade_len]; - decltype(len) s = 0; bool cancelled = false; - while (s < len) { - track->Get((samplePtr)bufferptr0, floatSample, start + s, nget); - stretch.process(buffer0, nget); + { + Floats fade_track_smps{ fade_len }; + decltype(len) s=0; - if (first_time) { - stretch.process(buffer0, 0); - }; + while (s < len) { + track->Get((samplePtr)bufferptr0, floatSample, start + s, nget); + stretch.process(buffer0.get(), nget); - s += nget; - - if (first_time) {//blend the the start of the selection - track->Get((samplePtr)fade_track_smps, floatSample, start, fade_len); - first_time = false; - for (int i = 0; i < fade_len; i++){ - float fi = (float)i / (float)fade_len; - stretch.out_buf[i] = - stretch.out_buf[i] * fi + (1.0 - fi) * fade_track_smps[i]; + if (first_time) { + stretch.process(buffer0.get(), 0); }; - }; - if (s >= len) {//blend the end of the selection - track->Get((samplePtr)fade_track_smps,floatSample,end-fade_len,fade_len); - for (int i = 0; i < fade_len; i++){ - float fi = (float)i / (float)fade_len; - auto i2 = bufsize / 2 - 1 - i; - stretch.out_buf[i2] = - stretch.out_buf[i2] * fi + (1.0 - fi) * - fade_track_smps[fade_len - 1 - i]; - }; - }; - outputTrack->Append((samplePtr)stretch.out_buf, floatSample, - stretch.out_bufsize); + s += nget; - nget = stretch.get_nsamples(); - if (TrackProgress(count, - s.as_double() / len.as_double() - )) { - cancelled=true; - break; + if (first_time){//blend the the start of the selection + track->Get((samplePtr)fade_track_smps.get(), floatSample, start, fade_len); + first_time = false; + for (size_t i = 0; i < fade_len; i++){ + float fi = (float)i / (float)fade_len; + stretch.out_buf[i] = + stretch.out_buf[i] * fi + (1.0 - fi) * fade_track_smps[i]; + } + } + if (s >= len){//blend the end of the selection + track->Get((samplePtr)fade_track_smps.get(), floatSample, end - fade_len, fade_len); + for (size_t i = 0; i < fade_len; i++){ + float fi = (float)i / (float)fade_len; + auto i2 = bufsize / 2 - 1 - i; + stretch.out_buf[i2] = + stretch.out_buf[i2] * fi + (1.0 - fi) * + fade_track_smps[fade_len - 1 - i]; + } + } + + outputTrack->Append((samplePtr)stretch.out_buf.get(), floatSample, stretch.out_bufsize); + + nget = stretch.get_nsamples(); + if (TrackProgress(count, + s.as_double() / len.as_double() + )) { + cancelled = true; + break; + } } } - delete [] fade_track_smps; outputTrack->Flush(); track->Clear(t0,t1); @@ -389,8 +386,6 @@ bool EffectPaulstretch::ProcessOne(WaveTrack *track,double t0,double t1,int coun m_t1 = mT0 + outputTrack->GetEndTime(); } - delete []buffer0; - return !cancelled; } catch ( const std::bad_alloc& ) { @@ -407,32 +402,24 @@ PaulStretch::PaulStretch(float rap_, size_t in_bufsize_, float samplerate_ ) , rap { std::max(1.0f, rap_) } , in_bufsize { in_bufsize_ } , out_bufsize { std::max(size_t{ 8 }, in_bufsize) } - , out_buf { new float[out_bufsize] } - , old_out_smp_buf { new float[out_bufsize * 2] { 0.0f } } + , out_buf { out_bufsize } + , old_out_smp_buf { out_bufsize * 2, true } , poolsize { in_bufsize_ * 2 } - , in_pool { new float[poolsize] { 0.0f } } + , in_pool { poolsize, true } , remained_samples { 0.0 } - , fft_smps { new float[poolsize] { 0.0f } } - , fft_s { new float[poolsize] { 0.0f } } - , fft_c { new float[poolsize] { 0.0f } } - , fft_freq { new float[poolsize] { 0.0f } } - , fft_tmp { new float[poolsize] } + , fft_smps { poolsize, true } + , fft_s { poolsize, true } + , fft_c { poolsize, true } + , fft_freq { poolsize, true } + , fft_tmp { poolsize } { } PaulStretch::~PaulStretch() { - delete [] out_buf; - delete [] old_out_smp_buf; - delete [] in_pool; - delete [] fft_smps; - delete [] fft_c; - delete [] fft_s; - delete [] fft_freq; - delete [] fft_tmp; } -void PaulStretch::process(float *smps,int nsmps) +void PaulStretch::process(float *smps, size_t nsmps) { //add NEW samples to the pool if ((smps != NULL) && (nsmps != 0)) { @@ -446,20 +433,20 @@ void PaulStretch::process(float *smps,int nsmps) in_pool[i] = in_pool[i + nsmps]; //add NEW samples to the pool - for (int i = 0; i < nsmps; i++) + for (size_t i = 0; i < nsmps; i++) in_pool[i + nleft] = smps[i]; } //get the samples from the pool for (size_t i = 0; i < poolsize; i++) fft_smps[i] = in_pool[i]; - WindowFunc(eWinFuncHanning, poolsize, fft_smps); + WindowFunc(eWinFuncHanning, poolsize, fft_smps.get()); - RealFFT(poolsize, fft_smps, fft_c, fft_s); + RealFFT(poolsize, fft_smps.get(), fft_c.get(), fft_s.get()); for (size_t i = 0; i < poolsize / 2; i++) fft_freq[i] = sqrt(fft_c[i] * fft_c[i] + fft_s[i] * fft_s[i]); - process_spectrum(fft_freq); + process_spectrum(fft_freq.get()); //put randomize phases to frequencies and do a IFFT @@ -477,7 +464,7 @@ void PaulStretch::process(float *smps,int nsmps) fft_c[0] = fft_s[0] = 0.0; fft_c[poolsize / 2] = fft_s[poolsize / 2] = 0.0; - FFT(poolsize, true, fft_c, fft_s, fft_smps, fft_tmp); + FFT(poolsize, true, fft_c.get(), fft_s.get(), fft_smps.get(), fft_tmp.get()); float max = 0.0, max2 = 0.0; for (size_t i = 0; i < poolsize; i++) { diff --git a/src/effects/Repair.cpp b/src/effects/Repair.cpp index c7d3c5d52..03d3cea76 100644 --- a/src/effects/Repair.cpp +++ b/src/effects/Repair.cpp @@ -138,11 +138,10 @@ bool EffectRepair::ProcessOne(int count, WaveTrack * track, size_t len, size_t repairStart, size_t repairLen) { - float *buffer = new float[len]; - track->Get((samplePtr) buffer, floatSample, start, len); - InterpolateAudio(buffer, len, repairStart, repairLen); + Floats buffer{ len }; + track->Get((samplePtr) buffer.get(), floatSample, start, len); + InterpolateAudio(buffer.get(), len, repairStart, repairLen); track->Set((samplePtr)&buffer[repairStart], floatSample, start + repairStart, repairLen); - delete[] buffer; return !TrackProgress(count, 1.0); // TrackProgress returns true on Cancel. } diff --git a/src/effects/Reverse.cpp b/src/effects/Reverse.cpp index ce6c78428..bd7ae35e1 100644 --- a/src/effects/Reverse.cpp +++ b/src/effects/Reverse.cpp @@ -222,8 +222,8 @@ bool EffectReverse::ProcessOneClip(int count, WaveTrack *track, auto blockSize = track->GetMaxBlockSize(); float tmp; - float *buffer1 = new float[blockSize]; - float *buffer2 = new float[blockSize]; + Floats buffer1{ blockSize }; + Floats buffer2{ blockSize }; auto originalLen = originalEnd - originalStart; @@ -232,15 +232,15 @@ bool EffectReverse::ProcessOneClip(int count, WaveTrack *track, limitSampleBufferSize( track->GetBestBlockSize(first), len / 2 ); auto second = first + (len - block); - track->Get((samplePtr)buffer1, floatSample, first, block); - track->Get((samplePtr)buffer2, floatSample, second, block); + track->Get((samplePtr)buffer1.get(), floatSample, first, block); + track->Get((samplePtr)buffer2.get(), floatSample, second, block); for (decltype(block) i = 0; i < block; i++) { tmp = buffer1[i]; buffer1[i] = buffer2[block-i-1]; buffer2[block-i-1] = tmp; } - track->Set((samplePtr)buffer1, floatSample, first, block); - track->Set((samplePtr)buffer2, floatSample, second, block); + track->Set((samplePtr)buffer1.get(), floatSample, first, block); + track->Set((samplePtr)buffer2.get(), floatSample, second, block); len -= 2 * block; first += block; @@ -252,8 +252,5 @@ bool EffectReverse::ProcessOneClip(int count, WaveTrack *track, } } - delete[] buffer1; - delete[] buffer2; - return rc; } diff --git a/src/effects/ScienFilter.cpp b/src/effects/ScienFilter.cpp index 06f1b89e3..c65c46821 100644 --- a/src/effects/ScienFilter.cpp +++ b/src/effects/ScienFilter.cpp @@ -153,6 +153,7 @@ BEGIN_EVENT_TABLE(EffectScienFilter, wxEvtHandler) END_EVENT_TABLE() EffectScienFilter::EffectScienFilter() +: mpBiquad{ size_t( MAX_Order / 2 ), true } { mOrder = DEF_Order; mFilterType = DEF_Type; @@ -170,18 +171,10 @@ EffectScienFilter::EffectScienFilter() mLoFreq = 20; // Lowest frequency to display in response graph mNyquist = 44100.0 / 2.0; // only used during initialization, updated when effect is used - - mpBiquad = new BiquadStruct[MAX_Order / 2]; - memset(mpBiquad, 0, sizeof(BiquadStruct) * MAX_Order / 2); - for (int i = 0; i < MAX_Order / 2; i++) - { - mpBiquad[i].fNumerCoeffs[0] = 1.0; // straight-through - } } EffectScienFilter::~EffectScienFilter() { - delete [] mpBiquad; } // IdentInterface implementation diff --git a/src/effects/ScienFilter.h b/src/effects/ScienFilter.h index 3556e86f3..80f0aaf49 100644 --- a/src/effects/ScienFilter.h +++ b/src/effects/ScienFilter.h @@ -100,7 +100,7 @@ private: int mFilterSubtype; // lowpass, highpass int mOrder; int mOrderIndex; - BiquadStruct *mpBiquad; + ArrayOf mpBiquad; double mdBMax; double mdBMin; diff --git a/src/effects/SimpleMono.cpp b/src/effects/SimpleMono.cpp index b20e8a60a..da48e3595 100644 --- a/src/effects/SimpleMono.cpp +++ b/src/effects/SimpleMono.cpp @@ -88,7 +88,7 @@ bool EffectSimpleMono::ProcessOne(WaveTrack * track, //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()]; + Floats buffer{ track->GetMaxBlockSize() }; //Go through the track one buffer at a time. s counts which //sample the current buffer starts at. @@ -100,19 +100,17 @@ bool EffectSimpleMono::ProcessOne(WaveTrack * track, limitSampleBufferSize( track->GetBestBlockSize(s), end - s ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr) buffer, floatSample, s, block); + track->Get((samplePtr) buffer.get(), floatSample, s, block); //Process the buffer. If it fails, clean up and exit. - if (!ProcessSimpleMono(buffer, block)) { - delete[]buffer; - + if (!ProcessSimpleMono(buffer.get(), block)) { //Return false because the effect failed. return false; } //Processing succeeded. copy the newly-changed samples back //onto the track. - track->Set((samplePtr) buffer, floatSample, s, block); + track->Set((samplePtr) buffer.get(), floatSample, s, block); //Increment s one blockfull of samples s += block; @@ -121,14 +119,10 @@ bool EffectSimpleMono::ProcessOne(WaveTrack * track, if (TrackProgress(mCurTrackNum, (s - start).as_double() / len)) { - delete[]buffer; return false; } } - //Clean up the buffer - delete[]buffer; - //Return true because the effect processing succeeded. return true; } diff --git a/src/effects/SoundTouchEffect.cpp b/src/effects/SoundTouchEffect.cpp index c85887899..1783d16c5 100644 --- a/src/effects/SoundTouchEffect.cpp +++ b/src/effects/SoundTouchEffect.cpp @@ -182,58 +182,55 @@ bool EffectSoundTouch::ProcessOne(WaveTrack *track, //to make it a double now than it is to do it later auto len = (end - start).as_double(); - //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()]; + { + //Initiate a processing buffer. This buffer will (most likely) + //be shorter than the length of the track being processed. + Floats buffer{ track->GetMaxBlockSize() }; - //Go through the track one buffer at a time. s counts which - //sample the current buffer starts at. - auto s = start; - while (s < end) { - //Get a block of samples (smaller than the size of the buffer) - const auto block = - limitSampleBufferSize( track->GetBestBlockSize(s), end - s ); + //Go through the track one buffer at a time. s counts which + //sample the current buffer starts at. + auto s = start; + while (s < end) { + //Get a block of samples (smaller than the size of the buffer) + const auto block = + limitSampleBufferSize( track->GetBestBlockSize(s), end - s ); - //Get the samples from the track and put them in the buffer - track->Get((samplePtr) buffer, floatSample, s, block); + //Get the samples from the track and put them in the buffer + track->Get((samplePtr)buffer.get(), floatSample, s, block); - //Add samples to SoundTouch - mSoundTouch->putSamples(buffer, block); + //Add samples to SoundTouch + mSoundTouch->putSamples(buffer.get(), 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; + //Get back samples from SoundTouch + unsigned int outputCount = mSoundTouch->numSamples(); + if (outputCount > 0) { + Floats buffer2{ outputCount }; + mSoundTouch->receiveSamples(buffer2.get(), outputCount); + outputTrack->Append((samplePtr)buffer2.get(), floatSample, outputCount); + } + + //Increment s one blockfull of samples + s += block; + + //Update the Progress meter + if (TrackProgress(mCurTrackNum, (s - start).as_double() / len)) + return false; } - //Increment s one blockfull of samples - s += block; + // Tell SoundTouch to finish processing any remaining samples + mSoundTouch->flush(); // this should only be used for changeTempo - it dumps data otherwise with pRateTransposer->clear(); - //Update the Progress meter - if (TrackProgress(mCurTrackNum, (s - start).as_double() / len)) - return false; + unsigned int outputCount = mSoundTouch->numSamples(); + if (outputCount > 0) { + Floats buffer2{ outputCount }; + mSoundTouch->receiveSamples(buffer2.get(), outputCount); + outputTrack->Append((samplePtr)buffer2.get(), floatSample, outputCount); + } + + // Flush the output WaveTrack (since it's buffered, too) + outputTrack->Flush(); } - // Tell SoundTouch to finish processing any remaining samples - mSoundTouch->flush(); // this should only be used for changeTempo - it dumps data otherwise with pRateTransposer->clear(); - - 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->ClearAndPaste(mCurT0, mCurT1, outputTrack.get(), true, false, &warper); @@ -249,7 +246,7 @@ bool EffectSoundTouch::ProcessStereo( WaveTrack* leftTrack, WaveTrack* rightTrack, sampleCount start, sampleCount end, const TimeWarper &warper) { - mSoundTouch->setSampleRate((unsigned int)(leftTrack->GetRate()+0.5)); + mSoundTouch->setSampleRate((unsigned int)(leftTrack->GetRate() + 0.5)); auto outputLeftTrack = mFactory->NewWaveTrack(leftTrack->GetSampleFormat(), leftTrack->GetRate()); @@ -267,75 +264,70 @@ bool EffectSoundTouch::ProcessStereo( // because Soundtouch wants them interleaved, i.e., each // Soundtouch sample is left-right pair. auto maxBlockSize = leftTrack->GetMaxBlockSize(); - float* leftBuffer = new float[maxBlockSize]; - float* rightBuffer = new float[maxBlockSize]; - float* soundTouchBuffer = new float[maxBlockSize * 2]; + { + Floats leftBuffer{ maxBlockSize }; + Floats rightBuffer{ maxBlockSize }; + Floats soundTouchBuffer{ maxBlockSize * 2 }; - // Go through the track one stereo buffer at a time. - // sourceSampleCount counts the sample at which the current buffer starts, - // per channel. - auto sourceSampleCount = start; - while (sourceSampleCount < end) { - //Get a block of samples (smaller than the size of the buffer) - //Adjust the block size if it is the final block in the track - auto blockSize = limitSampleBufferSize( - leftTrack->GetBestBlockSize(sourceSampleCount), - end - sourceSampleCount - ); + // Go through the track one stereo buffer at a time. + // sourceSampleCount counts the sample at which the current buffer starts, + // per channel. + auto sourceSampleCount = start; + while (sourceSampleCount < end) { + auto blockSize = limitSampleBufferSize( + leftTrack->GetBestBlockSize(sourceSampleCount), + 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); + // Get the samples from the tracks and put them in the buffers. + leftTrack->Get((samplePtr)(leftBuffer.get()), floatSample, sourceSampleCount, blockSize); + rightTrack->Get((samplePtr)(rightBuffer.get()), floatSample, sourceSampleCount, blockSize); - // Interleave into soundTouchBuffer. - for (decltype(blockSize) index = 0; index < blockSize; index++) { - soundTouchBuffer[index*2] = leftBuffer[index]; - soundTouchBuffer[(index*2)+1] = rightBuffer[index]; + // Interleave into soundTouchBuffer. + for (decltype(blockSize) index = 0; index < blockSize; index++) { + soundTouchBuffer[index * 2] = leftBuffer[index]; + soundTouchBuffer[(index * 2) + 1] = rightBuffer[index]; + } + + //Add samples to SoundTouch + mSoundTouch->putSamples(soundTouchBuffer.get(), blockSize); + + //Get back samples from SoundTouch + unsigned int outputCount = mSoundTouch->numSamples(); + if (outputCount > 0) + this->ProcessStereoResults(outputCount, outputLeftTrack.get(), outputRightTrack.get()); + + //Increment sourceSampleCount one blockfull of samples + sourceSampleCount += blockSize; + + //Update the Progress meter + // mCurTrackNum is left track. Include right track. + int nWhichTrack = mCurTrackNum; + double frac = (sourceSampleCount - start).as_double() / len; + if (frac < 0.5) + frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once. + else + { + nWhichTrack++; + frac -= 0.5; + frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once. + } + if (TrackProgress(nWhichTrack, frac)) + return false; } - //Add samples to SoundTouch - mSoundTouch->putSamples(soundTouchBuffer, blockSize); + // Tell SoundTouch to finish processing any remaining samples + mSoundTouch->flush(); - //Get back samples from SoundTouch unsigned int outputCount = mSoundTouch->numSamples(); if (outputCount > 0) this->ProcessStereoResults(outputCount, outputLeftTrack.get(), outputRightTrack.get()); - //Increment sourceSampleCount one blockfull of samples - sourceSampleCount += blockSize; - - //Update the Progress meter - // mCurTrackNum is left track. Include right track. - int nWhichTrack = mCurTrackNum; - double frac = (sourceSampleCount - start).as_double() / len; - if (frac < 0.5) - frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once. - else - { - nWhichTrack++; - frac -= 0.5; - frac *= 2.0; // Show twice as far for each track, because we're doing 2 at once. - } - if (TrackProgress(nWhichTrack, frac)) - return false; + // Flush the output WaveTracks (since they're buffered, too) + outputLeftTrack->Flush(); + outputRightTrack->Flush(); } - // Tell SoundTouch to finish processing any remaining samples - mSoundTouch->flush(); - - unsigned int outputCount = mSoundTouch->numSamples(); - if (outputCount > 0) - this->ProcessStereoResults(outputCount, outputLeftTrack.get(), outputRightTrack.get()); - - // 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->ClearAndPaste( @@ -357,24 +349,20 @@ bool EffectSoundTouch::ProcessStereoResults(const unsigned int outputCount, WaveTrack* outputLeftTrack, WaveTrack* outputRightTrack) { - float* outputSoundTouchBuffer = new float[outputCount*2]; - mSoundTouch->receiveSamples(outputSoundTouchBuffer, outputCount); + Floats outputSoundTouchBuffer{ outputCount * 2 }; + mSoundTouch->receiveSamples(outputSoundTouchBuffer.get(), outputCount); // Dis-interleave outputSoundTouchBuffer into separate track buffers. - float* outputLeftBuffer = new float[outputCount]; - float* outputRightBuffer = new float[outputCount]; + Floats outputLeftBuffer{ outputCount }; + Floats outputRightBuffer{ 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; + outputLeftTrack->Append((samplePtr)outputLeftBuffer.get(), floatSample, outputCount); + outputRightTrack->Append((samplePtr)outputRightBuffer.get(), floatSample, outputCount); return true; } diff --git a/src/effects/StereoToMono.cpp b/src/effects/StereoToMono.cpp index 46bd4225a..a5e257497 100644 --- a/src/effects/StereoToMono.cpp +++ b/src/effects/StereoToMono.cpp @@ -138,13 +138,13 @@ bool EffectStereoToMono::ProcessOne(int count) auto idealBlockLen = mLeftTrack->GetMaxBlockSize() * 2; auto index = mStart; - float *leftBuffer = new float[idealBlockLen]; - float *rightBuffer = new float[idealBlockLen]; + Floats leftBuffer { idealBlockLen }; + Floats rightBuffer{ idealBlockLen }; bool bResult = true; while (index < mEnd) { - bResult &= mLeftTrack->Get((samplePtr)leftBuffer, floatSample, index, idealBlockLen); - bResult &= mRightTrack->Get((samplePtr)rightBuffer, floatSample, index, idealBlockLen); + bResult &= mLeftTrack->Get((samplePtr)leftBuffer.get(), floatSample, index, idealBlockLen); + bResult &= mRightTrack->Get((samplePtr)rightBuffer.get(), floatSample, index, idealBlockLen); auto limit = limitSampleBufferSize( idealBlockLen, mEnd - index ); for (decltype(limit) i = 0; i < limit; ++i) { index++; @@ -153,7 +153,7 @@ bool EffectStereoToMono::ProcessOne(int count) curMonoFrame = (curLeftFrame + curRightFrame) / 2.0; leftBuffer[i] = curMonoFrame; } - bResult &= mOutTrack->Append((samplePtr)leftBuffer, floatSample, limit); + bResult &= mOutTrack->Append((samplePtr)leftBuffer.get(), floatSample, limit); if (TrackProgress(count, 2.*(index.as_double() / (mEnd - mStart).as_double()))) return false; } @@ -167,9 +167,6 @@ bool EffectStereoToMono::ProcessOne(int count) mLeftTrack->SetChannel(Track::MonoChannel); mOutputTracks->Remove(mRightTrack); - delete [] leftBuffer; - delete [] rightBuffer; - return bResult; } diff --git a/src/effects/TruncSilence.cpp b/src/effects/TruncSilence.cpp index e943a28c7..587fa7490 100644 --- a/src/effects/TruncSilence.cpp +++ b/src/effects/TruncSilence.cpp @@ -500,13 +500,13 @@ bool EffectTruncSilence::DoRemoval } // Perform cross-fade in memory - float *buf1 = new float[blendFrames]; - float *buf2 = new float[blendFrames]; + Floats buf1{ blendFrames }; + Floats buf2{ blendFrames }; auto t1 = wt->TimeToLongSamples(cutStart) - blendFrames / 2; auto t2 = wt->TimeToLongSamples(cutEnd) - blendFrames / 2; - wt->Get((samplePtr)buf1, floatSample, t1, blendFrames); - wt->Get((samplePtr)buf2, floatSample, t2, blendFrames); + wt->Get((samplePtr)buf1.get(), floatSample, t1, blendFrames); + wt->Get((samplePtr)buf2.get(), floatSample, t2, blendFrames); for (decltype(blendFrames) i = 0; i < blendFrames; ++i) { @@ -518,10 +518,7 @@ bool EffectTruncSilence::DoRemoval wt->Clear(cutStart, cutEnd); // Write cross-faded data - wt->Set((samplePtr)buf1, floatSample, t1, blendFrames); - - delete [] buf1; - delete [] buf2; + wt->Set((samplePtr)buf1.get(), floatSample, t1, blendFrames); } else // Non-wave tracks: just do a sync-lock adjust @@ -560,7 +557,7 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, RegionList::iterator rit(silenceList.begin()); // Allocate buffer - float *buffer = new float[blockLen]; + Floats buffer{ blockLen }; // Loop through current track while (*index < end) { @@ -579,10 +576,8 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, (*index - start).as_double() / (end - start).as_double()) / (double)GetNumWaveTracks()); - if (cancelled) { - delete [] buffer; + if (cancelled) return false; - } } // Optimization: if not in a silent region skip ahead to the next one @@ -630,7 +625,7 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, auto count = limitSampleBufferSize( blockLen, end - *index ); // Fill buffer - wt->Get((samplePtr)(buffer), floatSample, *index, count); + wt->Get((samplePtr)(buffer.get()), floatSample, *index, count); // Look for silenceList in current block for (decltype(count) i = 0; i < count; ++i) { @@ -680,7 +675,6 @@ bool EffectTruncSilence::Analyze(RegionList& silenceList, // Next block *index += count; } - delete [] buffer; if (inputLength) { *inputLength = std::min(*inputLength, *minInputLength); diff --git a/src/effects/TwoPassSimpleMono.cpp b/src/effects/TwoPassSimpleMono.cpp index b5e2a6575..71ad6f4e7 100644 --- a/src/effects/TwoPassSimpleMono.cpp +++ b/src/effects/TwoPassSimpleMono.cpp @@ -100,7 +100,6 @@ bool EffectTwoPassSimpleMono::ProcessOne(WaveTrack * track, sampleCount start, sampleCount end) { bool ret; - float *tmpfloat; //Get the length of the buffer (as double). len is //used simple to calculate a progress meter, so it is easier @@ -110,26 +109,22 @@ bool EffectTwoPassSimpleMono::ProcessOne(WaveTrack * track, //Initiate a processing buffer. This buffer will (most likely) //be shorter than the length of the track being processed. - float *buffer1 = new float[maxblock]; - float *buffer2 = new float[maxblock]; + Floats buffer1{ maxblock }; + Floats buffer2{ maxblock }; auto samples1 = limitSampleBufferSize( std::min( maxblock, track->GetBestBlockSize(start) ), end - start ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr) buffer1, floatSample, start, samples1); + track->Get((samplePtr) buffer1.get(), floatSample, start, samples1); // Process the first buffer with a NULL previous buffer if (mPass == 0) - ret = TwoBufferProcessPass1(NULL, 0, buffer1, samples1); + ret = TwoBufferProcessPass1(NULL, 0, buffer1.get(), samples1); else - ret = TwoBufferProcessPass2(NULL, 0, buffer1, samples1); - if (!ret) { - delete[]buffer1; - delete[]buffer2; - + ret = TwoBufferProcessPass2(NULL, 0, buffer1.get(), samples1); + if (!ret) //Return false because the effect failed. return false; - } //Go through the track one buffer at a time. s counts which //sample the current buffer starts at. @@ -142,23 +137,20 @@ bool EffectTwoPassSimpleMono::ProcessOne(WaveTrack * track, ); //Get the samples from the track and put them in the buffer - track->Get((samplePtr) buffer2, floatSample, s, samples2); + track->Get((samplePtr)buffer2.get(), floatSample, s, samples2); //Process the buffer. If it fails, clean up and exit. if (mPass == 0) - ret = TwoBufferProcessPass1(buffer1, samples1, buffer2, samples2); + ret = TwoBufferProcessPass1(buffer1.get(), samples1, buffer2.get(), samples2); else - ret = TwoBufferProcessPass2(buffer1, samples1, buffer2, samples2); - if (!ret) { - delete[]buffer1; - delete[]buffer2; + ret = TwoBufferProcessPass2(buffer1.get(), samples1, buffer2.get(), samples2); + if (!ret) //Return false because the effect failed. return false; - } //Processing succeeded. copy the newly-changed samples back //onto the track. - track->Set((samplePtr) buffer1, floatSample, s-samples1, samples1); + track->Set((samplePtr)buffer1.get(), floatSample, s - samples1, samples1); //Increment s one blockfull of samples s += samples2; @@ -172,41 +164,29 @@ bool EffectTwoPassSimpleMono::ProcessOne(WaveTrack * track, ret = TotalProgress( (mCurTrackNum + (s-start).as_double()/len + GetNumWaveTracks()*mPass) / (GetNumWaveTracks()*2)); - if (ret) { - delete[]buffer1; - delete[]buffer2; + if (ret) //Return false because the effect failed. return false; - } // Rotate the buffers - tmpfloat = buffer1; - buffer1 = buffer2; - buffer2 = tmpfloat; + buffer1.swap(buffer2); std::swap(samples1, samples2); } // Send the last buffer with a NULL pointer for the current buffer if (mPass == 0) - ret = TwoBufferProcessPass1(buffer1, samples1, NULL, 0); + ret = TwoBufferProcessPass1(buffer1.get(), samples1, NULL, 0); else - ret = TwoBufferProcessPass2(buffer1, samples1, NULL, 0); + ret = TwoBufferProcessPass2(buffer1.get(), samples1, NULL, 0); - if (!ret) { - delete[]buffer1; - delete[]buffer2; + if (!ret) //Return false because the effect failed. return false; - } //Processing succeeded. copy the newly-changed samples back //onto the track. - track->Set((samplePtr) buffer1, floatSample, s-samples1, samples1); - - //Clean up the buffer - delete[]buffer1; - delete[]buffer2; + track->Set((samplePtr)buffer1.get(), floatSample, s - samples1, samples1); //Return true because the effect processing succeeded. return true;