Remove naked new[] in: builtin effects

This commit is contained in:
Paul Licameli 2016-04-14 12:35:15 -04:00
parent f858d97352
commit 6ca89c28ff
28 changed files with 558 additions and 774 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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<len; i++)
b2[i] = buffer[i]*buffer[i];
@ -322,8 +319,6 @@ bool EffectClickRemoval::RemoveClicks(int len, float *buffer)
}
}
}
delete[] ms_seq;
delete[] b2;
return bResult;
}

View File

@ -61,7 +61,7 @@ private:
bool ProcessOne(int count, WaveTrack * track,
sampleCount start, sampleCount len);
bool RemoveClicks(int len, float *buffer);
bool RemoveClicks(size_t len, float *buffer);
void OnWidthText(wxCommandEvent & evt);
void OnThreshText(wxCommandEvent & evt);

View File

@ -84,9 +84,6 @@ EffectCompressor::EffectCompressor()
mThreshold = 0.25;
mNoiseFloor = 0.01;
mCompression = 0.5;
mCircle = NULL;
mFollow1 = NULL;
mFollow2 = NULL;
mFollowLen = 0;
SetLinearEffectFlag(false);
@ -94,18 +91,6 @@ EffectCompressor::EffectCompressor()
EffectCompressor::~EffectCompressor()
{
if (mCircle) {
delete[] mCircle;
mCircle = NULL;
}
if(mFollow1!=NULL) {
delete[] mFollow1;
mFollow1 = NULL;
}
if(mFollow2!=NULL) {
delete[] mFollow2;
mFollow2 = NULL;
}
}
// IdentInterface implementation
@ -346,13 +331,8 @@ bool EffectCompressor::NewTrackPass1()
mLastLevel = mThreshold;
if (mCircle)
delete[] mCircle;
mCircleSize = 100;
mCircle = new double[mCircleSize];
for(int j=0; j<mCircleSize; j++) {
mCircle[j] = 0.0;
}
mCircle.reinit( mCircleSize, true );
mCirclePos = 0;
mRMSSum = 0.0;
@ -374,18 +354,12 @@ bool EffectCompressor::InitPass1()
//Iterate to the next track
track = (WaveTrack *) iter.Next();
}
if(mFollow1!=NULL) {
delete[] mFollow1;
mFollow1 = NULL;
}
if(mFollow2!=NULL) {
delete[] mFollow2;
mFollow2 = NULL;
}
mFollow1.reset();
mFollow2.reset();
// Allocate buffers for the envelope
if(maxlen > 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<mCircleSize; i++)
for(size_t i=0; i<mCircleSize; i++)
mRMSSum += mCircle[i];
}

View File

@ -22,6 +22,7 @@
#include "../widgets/wxPanelWrapper.h"
#include "TwoPassSimpleMono.h"
#include "../SampleFormat.h"
class EffectCompressorPanel;
class ShuttleGui;
@ -79,9 +80,9 @@ private:
private:
double mRMSSum;
int mCircleSize;
int mCirclePos;
double *mCircle;
size_t mCircleSize;
size_t mCirclePos;
Doubles mCircle;
double mAttackTime;
double mThresholdDB;
@ -100,8 +101,7 @@ private:
int mNoiseCounter;
double mGain;
double mLastLevel;
float *mFollow1;
float *mFollow2;
Floats mFollow1, mFollow2;
size_t mFollowLen;
double mMax; //MJS

View File

@ -28,6 +28,7 @@
#include "../ShuttleGui.h"
#include "../widgets/valnum.h"
#include "../SampleFormat.h"
// Define keys, defaults, minimums, and maximums for the effect parameters
//
@ -95,22 +96,19 @@ bool EffectEcho::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames
if (requestedHistLen !=
(histLen = static_cast<size_t>(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;
}

View File

@ -17,6 +17,7 @@
#include <wx/textctrl.h>
#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;
};

View File

@ -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;j<numPoints-2;j++)
mLogEnvelope->GetPoints( 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<NUM_PTS; i++)
for(size_t i = 0; i < NUM_PTS; i++)
{
while( (mWhenSliders[minF] <= mWhens[i]) & (minF < mBandsInUse) )
minF++;
@ -2514,7 +2482,7 @@ void EffectEqualization::GraphicEQ(Envelope *env)
case kCosine: // Cosine squared
{
int minF = 0;
for(int i=0; i<NUM_PTS; i++)
for(size_t i = 0; i < NUM_PTS; i++)
{
while( (mWhenSliders[minF] <= mWhens[i]) & (minF < mBandsInUse) )
minF++;
@ -2571,14 +2539,16 @@ void EffectEqualization::GraphicEQ(Envelope *env)
ForceRecalc();
}
void EffectEqualization::spline(double x[], double y[], int n, double y2[])
void EffectEqualization::spline(double x[], double y[], size_t n, double y2[])
{
int i;
double p, sig, *u = new double[n];
wxASSERT( n > 0 );
double p, sig;
Doubles u{ n };
y2[0] = 0.; //
u[0] = 0.; //'natural' boundary conditions
for(i=1;i<n-1;i++)
for (size_t i = 1; i + 1 < n; i++)
{
sig = ( x[i] - x[i-1] ) / ( x[i+1] - x[i-1] );
p = sig * y2[i-1] + 2.;
@ -2586,24 +2556,25 @@ void EffectEqualization::spline(double x[], double y[], int n, double y2[])
u[i] = ( y[i+1] - y[i] ) / ( x[i+1] - x[i] ) - ( y[i] - y[i-1] ) / ( x[i] - x[i-1] );
u[i] = (6.*u[i]/( x[i+1] - x[i-1] ) - sig * u[i-1]) / p;
}
y2[n-1] = 0.;
for(i=n-2;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; i<mEnvRect.width; i++)
{
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)
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

View File

@ -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;

View File

@ -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;i<mWorkerDataCount;i++) {
mBufferInfo[i].mFftWindowSize=mWindowSize;
mBufferInfo[i].mFftFilterSize=mFilterSize;
@ -226,9 +226,9 @@ bool EffectEqualization48x::AllocateBuffersWorkers(int nThreads)
if(mThreadCount) {
// start the workers
mDataMutex.IsOk();
mEQWorkers=new EQWorker[mThreadCount];
mEQWorkers.reinit(mThreadCount);
for(int i=0;i<mThreadCount;i++) {
mEQWorkers[i].SetData( mBufferInfo, mWorkerDataCount, &mDataMutex, this);
mEQWorkers[i].SetData( mBufferInfo.get(), mWorkerDataCount, &mDataMutex, this);
mEQWorkers[i].Create();
mEQWorkers[i].Run();
}
@ -245,13 +245,11 @@ bool EffectEqualization48x::FreeBuffersWorkers()
for(int i=0;i<mThreadCount;i++) {
mEQWorkers[i].Wait();
}
delete[] mEQWorkers; // kill the workers ( go directly to jail)
mEQWorkers= NULL;
mEQWorkers.reset(); // kill the workers ( go directly to jail)
mThreadCount=0;
mWorkerDataCount=0;
}
delete [] mBufferInfo;
mBufferInfo = NULL;
mBufferInfo.reset();
free_simd(mBigBuffer);
mBigBuffer=NULL;
return true;
@ -415,8 +413,8 @@ bool EffectEqualization48x::DeltaTrack(WaveTrack * t, WaveTrack * t2, sampleCoun
auto trackBlockSize = t->GetMaxBlockSize();
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;i<curretLength;i++)
buffer1[i]-=buffer2[i];
output->Append((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;

View File

@ -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<BufferInfo> mBufferInfo;
wxMutex mDataMutex;
EQWorker* mEQWorkers;
ArrayOf<EQWorker> mEQWorkers;
bool mThreaded;
bool mBenching;
friend EQWorker;

View File

@ -95,7 +95,6 @@ bool EffectFindClipping::Process()
{
std::shared_ptr<AddedAnalysisTrack> addedTrack;
Maybe<ModifiedAnalysisTrack> 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;
}

View File

@ -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; i<mWindowSize; i++)
for(size_t i=0; i<mWindowSize; i++)
mWindow[i] = 0.5 - 0.5 * cos((2.0*M_PI*i) / mWindowSize);
if (mDoProfile) {
for (i = 0; i < mSpectrumSize; i++)
for (size_t i = 0; i < mSpectrumSize; i++)
mNoiseThreshold[i] = float(0);
}
}
void EffectNoiseRemoval::Cleanup()
{
int i;
EndFFT(hFFT);
if (mDoProfile) {
ApplyFreqSmoothing(mNoiseThreshold);
ApplyFreqSmoothing(mNoiseThreshold.get());
}
for(i = 0; i < mHistoryLen; i++) {
delete[] mSpectrums[i];
delete[] mGains[i];
delete[] mRealFFTs[i];
delete[] mImagFFTs[i];
}
delete[] mSpectrums;
delete[] mGains;
delete[] mRealFFTs;
delete[] mImagFFTs;
mSpectrums.reset();
mGains.reset();
mRealFFTs.reset();
mImagFFTs.reset();
delete[] mFFTBuffer;
delete[] mInWaveBuffer;
delete[] mWindow;
delete[] mOutOverlapBuffer;
mFFTBuffer.reset();
mInWaveBuffer.reset();
mWindow.reset();
mOutOverlapBuffer.reset();
}
void EffectNoiseRemoval::StartNewTrack()
{
int i, j;
for(i = 0; i < mHistoryLen; i++) {
for(j = 0; j < mSpectrumSize; j++) {
for(size_t i = 0; i < mHistoryLen; i++) {
for(size_t j = 0; j < mSpectrumSize; j++) {
mSpectrums[i][j] = 0;
mGains[i][j] = mNoiseAttenFactor;
mRealFFTs[i][j] = 0.0;
@ -356,7 +335,7 @@ void EffectNoiseRemoval::StartNewTrack()
}
}
for(j = 0; j < mWindowSize; j++)
for(size_t j = 0; j < mWindowSize; j++)
mOutOverlapBuffer[j] = 0.0;
mInputPos = 0;
@ -366,17 +345,15 @@ void EffectNoiseRemoval::StartNewTrack()
void EffectNoiseRemoval::ProcessSamples(size_t len, float *buffer)
{
int i;
while(len && mOutSampleCount < mInSampleCount) {
int avail = wxMin(len, mWindowSize - mInputPos);
for(i = 0; i < avail; i++)
size_t avail = wxMin(len, mWindowSize - mInputPos);
for(size_t i = 0; i < avail; i++)
mInWaveBuffer[mInputPos + i] = buffer[i];
buffer += avail;
len -= avail;
mInputPos += avail;
if (mInputPos == mWindowSize) {
if (mInputPos == int(mWindowSize)) {
FillFirstHistoryWindow();
if (mDoProfile)
GetProfile();
@ -385,7 +362,7 @@ void EffectNoiseRemoval::ProcessSamples(size_t len, float *buffer)
RotateHistoryWindows();
// Rotate halfway for overlap-add
for(i = 0; i < mWindowSize / 2; i++) {
for(size_t i = 0; i < mWindowSize / 2; i++) {
mInWaveBuffer[i] = mInWaveBuffer[i + mWindowSize / 2];
}
mInputPos = mWindowSize / 2;
@ -395,12 +372,10 @@ void EffectNoiseRemoval::ProcessSamples(size_t len, float *buffer)
void EffectNoiseRemoval::FillFirstHistoryWindow()
{
int i;
for(i=0; i < mWindowSize; i++)
for(size_t i = 0; i < mWindowSize; i++)
mFFTBuffer[i] = mInWaveBuffer[i];
RealFFTf(mFFTBuffer, hFFT);
for(i = 1; i < (mSpectrumSize-1); i++) {
RealFFTf(mFFTBuffer.get(), hFFT);
for(size_t i = 1; i < (mSpectrumSize-1); i++) {
mRealFFTs[0][i] = mFFTBuffer[hFFT->BitReversed[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<float> &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)

View File

@ -21,6 +21,7 @@
#include "Effect.h"
#include "../MemoryX.h"
#include "../SampleFormat.h"
#include <wx/dialog.h>
#include <wx/slider.h>
@ -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<float> mSpectrums; // mHistoryLen x mSpectrumSize
ArraysOf<float> mGains; // mHistoryLen x mSpectrumSize
ArraysOf<float> mRealFFTs; // mHistoryLen x mWindowSize
ArraysOf<float> mImagFFTs; // mHistoryLen x mWindowSize
friend class NoiseRemovalDialog;
};

View File

@ -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;

View File

@ -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<size_t>(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++) {

View File

@ -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.
}

View File

@ -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;
}

View File

@ -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

View File

@ -100,7 +100,7 @@ private:
int mFilterSubtype; // lowpass, highpass
int mOrder;
int mOrderIndex;
BiquadStruct *mpBiquad;
ArrayOf<BiquadStruct> mpBiquad;
double mdBMax;
double mdBMin;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<double>(*inputLength, *minInputLength);

View File

@ -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;