No naked array new!

This commit is contained in:
Paul Licameli 2017-03-09 09:53:21 -05:00
commit c5007d846e
106 changed files with 1782 additions and 2711 deletions

View File

@ -1705,10 +1705,11 @@ int AudioIO::StartStream(const ConstWaveTrackArray &playbackTracks,
mPlayMode = options.playLooped ? PLAY_LOOPED : PLAY_STRAIGHT;
mCutPreviewGapStart = options.cutPreviewGapStart;
mCutPreviewGapLen = options.cutPreviewGapLen;
mPlaybackBuffers = NULL;
mPlaybackMixers = NULL;
mCaptureBuffers = NULL;
mResample = NULL;
mPlaybackBuffers.reset();
mPlaybackMixers.reset();
mCaptureBuffers.reset();
mResample.reset();
double playbackTime = 4.0;
@ -1859,12 +1860,8 @@ int AudioIO::StartStream(const ConstWaveTrackArray &playbackTracks,
auto playbackMixBufferSize =
mPlaybackSamplesToCopy;
mPlaybackBuffers = new RingBuffer* [mPlaybackTracks.size()];
mPlaybackMixers = new Mixer* [mPlaybackTracks.size()];
// Set everything to zero in case we have to DELETE these due to a memory exception.
memset(mPlaybackBuffers, 0, sizeof(RingBuffer*)*mPlaybackTracks.size());
memset(mPlaybackMixers, 0, sizeof(Mixer*)*mPlaybackTracks.size());
mPlaybackBuffers.reinit(mPlaybackTracks.size());
mPlaybackMixers.reinit(mPlaybackTracks.size());
const Mixer::WarpOptions &warpOptions =
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
@ -1878,10 +1875,11 @@ int AudioIO::StartStream(const ConstWaveTrackArray &playbackTracks,
for (unsigned int i = 0; i < mPlaybackTracks.size(); i++)
{
mPlaybackBuffers[i] = new RingBuffer(floatSample, playbackBufferSize);
mPlaybackBuffers[i] = std::make_unique<RingBuffer>(floatSample, playbackBufferSize);
// MB: use normal time for the end time, not warped time!
mPlaybackMixers[i] = new Mixer(WaveTrackConstArray{ mPlaybackTracks[i] },
mPlaybackMixers[i] = std::make_unique<Mixer>
(WaveTrackConstArray{ mPlaybackTracks[i] },
warpOptions,
mT0, mT1, 1,
playbackMixBufferSize, false,
@ -1904,19 +1902,16 @@ int AudioIO::StartStream(const ConstWaveTrackArray &playbackTracks,
return 0;
}
mCaptureBuffers = new RingBuffer* [mCaptureTracks.size()];
mResample = new Resample* [mCaptureTracks.size()];
mCaptureBuffers.reinit(mCaptureTracks.size());
mResample.reinit(mCaptureTracks.size());
mFactor = sampleRate / mRate;
// Set everything to zero in case we have to DELETE these due to a memory exception.
memset(mCaptureBuffers, 0, sizeof(RingBuffer*)*mCaptureTracks.size());
memset(mResample, 0, sizeof(Resample*)*mCaptureTracks.size());
for( unsigned int i = 0; i < mCaptureTracks.size(); i++ )
{
mCaptureBuffers[i] = new RingBuffer( mCaptureTracks[i]->GetSampleFormat(),
mCaptureBuffers[i] = std::make_unique<RingBuffer>
( mCaptureTracks[i]->GetSampleFormat(),
captureBufferSize );
mResample[i] = new Resample(true, mFactor, mFactor); // constant rate resampling
mResample[i] = std::make_unique<Resample>(true, mFactor, mFactor); // constant rate resampling
}
}
}
@ -2087,37 +2082,10 @@ void AudioIO::StartStreamCleanup(bool bOnlyBuffers)
EffectManager::Get().RealtimeFinalize();
}
if(mPlaybackBuffers)
{
for (unsigned int i = 0; i < mPlaybackTracks.size(); i++)
delete mPlaybackBuffers[i];
delete [] mPlaybackBuffers;
mPlaybackBuffers = NULL;
}
if(mPlaybackMixers)
{
for (unsigned int i = 0; i < mPlaybackTracks.size(); i++)
delete mPlaybackMixers[i];
delete [] mPlaybackMixers;
mPlaybackMixers = NULL;
}
if(mCaptureBuffers)
{
for (unsigned int i = 0; i < mCaptureTracks.size(); i++)
delete mCaptureBuffers[i];
delete [] mCaptureBuffers;
mCaptureBuffers = NULL;
}
if(mResample)
{
for (unsigned int i = 0; i < mCaptureTracks.size(); i++)
delete mResample[i];
delete [] mResample;
mResample = NULL;
}
mPlaybackBuffers.reset();
mPlaybackMixers.reset();
mCaptureBuffers.reset();
mResample.reset();
if(!bOnlyBuffers)
{
@ -2443,14 +2411,8 @@ void AudioIO::StopStream()
if (mPlaybackTracks.size() > 0)
{
for (unsigned int i = 0; i < mPlaybackTracks.size(); i++)
{
delete mPlaybackBuffers[i];
delete mPlaybackMixers[i];
}
delete[] mPlaybackBuffers;
delete[] mPlaybackMixers;
mPlaybackBuffers.reset();
mPlaybackMixers.reset();
}
//
@ -2458,6 +2420,9 @@ void AudioIO::StopStream()
//
if (mCaptureTracks.size() > 0)
{
mCaptureBuffers.reset();
mResample.reset();
//
// We only apply latency correction when we actually played back
// tracks during the recording. If we did not play back tracks,
@ -2473,9 +2438,6 @@ void AudioIO::StopStream()
for (unsigned int i = 0; i < mCaptureTracks.size(); i++)
{
delete mCaptureBuffers[i];
delete mResample[i];
WaveTrack* track = mCaptureTracks[i];
track->Flush();
@ -2521,9 +2483,6 @@ void AudioIO::StopStream()
}
}
}
delete[] mCaptureBuffers;
delete[] mResample;
}
}
@ -4378,7 +4337,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
bool selected = false;
int group = 0;
int chanCnt = 0;
int maxLen = 0;
decltype(framesPerBuffer) maxLen = 0;
for (unsigned t = 0; t < numPlaybackTracks; t++)
{
const WaveTrack *vt = gAudioIO->mPlaybackTracks[t];
@ -4410,7 +4369,7 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer,
#define ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
#ifdef ORIGINAL_DO_NOT_PLAY_ALL_MUTED_TRACKS_TO_END
int len = 0;
decltype(framesPerBuffer) len = 0;
// this is original code prior to r10680 -RBD
if (cut)
{

View File

@ -555,13 +555,13 @@ private:
#ifdef EXPERIMENTAL_MIDI_OUT
std::unique_ptr<AudioThread> mMidiThread;
#endif
Resample **mResample;
RingBuffer **mCaptureBuffers;
ArrayOf<std::unique_ptr<Resample>> mResample;
ArrayOf<std::unique_ptr<RingBuffer>> mCaptureBuffers;
WaveTrackArray mCaptureTracks;
RingBuffer **mPlaybackBuffers;
ArrayOf<std::unique_ptr<RingBuffer>> mPlaybackBuffers;
ConstWaveTrackArray mPlaybackTracks;
Mixer **mPlaybackMixers;
ArrayOf<std::unique_ptr<Mixer>> mPlaybackMixers;
volatile int mStreamToken;
static int mNextStreamToken;
double mFactor;

View File

@ -641,9 +641,8 @@ void AutoSaveFile::CheckSpace(wxMemoryOutputStream & os)
if (left == 0)
{
size_t origPos = buf->GetIntPosition();
char *temp = new char[mAllocSize];
buf->Write(temp, mAllocSize);
delete[] temp;
ArrayOf<char> temp{ mAllocSize };
buf->Write(temp.get(), mAllocSize);
buf->SetIntPosition(origPos);
}
}
@ -739,54 +738,54 @@ bool AutoSaveFile::Decode(const wxString & fileName)
return true;
}
len = file.Length() - len;
char *buf = new char[len];
if (file.Read(buf, len) != len)
{
delete[] buf;
return false;
}
wxMemoryInputStream in(buf, len);
file.Close();
// Decode to a temporary file to preserve the orignal.
wxString tempName = fn.CreateTempFileName(fnPath);
bool opened = false;
XMLFileWriter out;
// JKC: ANSWER-ME: Is the try catch actually doing anything?
// If it is useful, why are we not using it everywhere?
// If it isn't useful, why are we doing it here?
try
wxString tempName;
len = file.Length() - len;
{
out.Open(tempName, wxT("wb"));
opened = out.IsOpened();
}
catch (const XMLFileWriterException&)
{
}
using Chars = ArrayOf < char >;
using WxChars = ArrayOf < wxChar >;
Chars buf{ len };
if (!opened)
{
delete[] buf;
wxRemoveFile(tempName);
return false;
}
mIds.clear();
while (!in.Eof() && !out.Error())
{
short id;
switch (in.GetC())
if (file.Read(buf.get(), len) != len)
{
return false;
}
wxMemoryInputStream in(buf.get(), len);
file.Close();
// Decode to a temporary file to preserve the original.
tempName = fn.CreateTempFileName(fnPath);
bool opened = false;
// JKC: ANSWER-ME: Is the try catch actually doing anything?
// If it is useful, why are we not using it everywhere?
// If it isn't useful, why are we doing it here?
try
{
out.Open(tempName, wxT("wb"));
opened = out.IsOpened();
}
catch (const XMLFileWriterException&)
{
}
if (!opened)
{
wxRemoveFile(tempName);
return false;
}
mIds.clear();
while (!in.Eof() && !out.Error())
{
short id;
switch (in.GetC())
{
case FT_Push:
{
mIdStack.Add(mIds);
@ -807,11 +806,10 @@ bool AutoSaveFile::Decode(const wxString & fileName)
in.Read(&id, sizeof(id));
in.Read(&len, sizeof(len));
wxChar *name = new wxChar[len / sizeof(wxChar)];
in.Read(name, len);
WxChars name{ len / sizeof(wxChar) };
in.Read(name.get(), len);
mIds[id] = wxString(name, len / sizeof(wxChar));
delete[] name;
mIds[id] = wxString(name.get(), len / sizeof(wxChar));
}
break;
@ -837,11 +835,10 @@ bool AutoSaveFile::Decode(const wxString & fileName)
in.Read(&id, sizeof(id));
in.Read(&len, sizeof(len));
wxChar *val = new wxChar[len / sizeof(wxChar)];
in.Read(val, len);
WxChars val{ len / sizeof(wxChar) };
in.Read(val.get(), len);
out.WriteAttr(mIds[id], wxString(val, len / sizeof(wxChar)));
delete[] val;
out.WriteAttr(mIds[id], wxString(val.get(), len / sizeof(wxChar)));
}
break;
@ -931,11 +928,10 @@ bool AutoSaveFile::Decode(const wxString & fileName)
int len;
in.Read(&len, sizeof(len));
wxChar *val = new wxChar[len / sizeof(wxChar)];
in.Read(val, len);
WxChars val{ len / sizeof(wxChar) };
in.Read(val.get(), len);
out.WriteData(wxString(val, len / sizeof(wxChar)));
delete[] val;
out.WriteData(wxString(val.get(), len / sizeof(wxChar)));
}
break;
@ -944,22 +940,20 @@ bool AutoSaveFile::Decode(const wxString & fileName)
int len;
in.Read(&len, sizeof(len));
wxChar *val = new wxChar[len / sizeof(wxChar)];
in.Read(val, len);
WxChars val{ len / sizeof(wxChar) };
in.Read(val.get(), len);
out.Write(wxString(val, len / sizeof(wxChar)));
delete[] val;
out.Write(wxString(val.get(), len / sizeof(wxChar)));
}
break;
default:
wxASSERT(true);
break;
break;
}
}
}
delete[] buf;
bool error = out.Error();
out.Close();

View File

@ -373,28 +373,29 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
int trials = numEdits;
short *small1 = new short[nChunks];
short *block = new short[chunkSize];
using Shorts = ArrayOf < short > ;
Shorts small1{ nChunks };
Shorts block{ chunkSize };
Printf(wxT("Preparing...\n"));
wxTheApp->Yield();
FlushPrint();
int i, b, v;
int v;
int bad;
int z;
long elapsed;
wxString tempStr;
wxStopWatch timer;
for (i = 0; i < nChunks; i++) {
for (size_t i = 0; i < nChunks; i++) {
v = short(rand());
small1[i] = v;
for (b = 0; b < chunkSize; b++)
for (size_t b = 0; b < chunkSize; b++)
block[b] = v;
t->Append((samplePtr)block, int16Sample, chunkSize);
t->Append((samplePtr)block.get(), int16Sample, chunkSize);
}
t->Flush();
@ -486,10 +487,10 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
bad = 0;
timer.Start();
for (i = 0; i < nChunks; i++) {
for (size_t i = 0; i < nChunks; i++) {
v = small1[i];
t->Get((samplePtr)block, int16Sample, i * chunkSize, chunkSize);
for (b = 0; b < chunkSize; b++)
t->Get((samplePtr)block.get(), int16Sample, i * chunkSize, chunkSize);
for (size_t b = 0; b < chunkSize; b++)
if (block[b] != v) {
bad++;
if (bad < 10)
@ -512,10 +513,10 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
timer.Start();
for (i = 0; i < nChunks; i++) {
for (size_t i = 0; i < nChunks; i++) {
v = small1[i];
t->Get((samplePtr)block, int16Sample, i * chunkSize, chunkSize);
for (b = 0; b < chunkSize; b++)
t->Get((samplePtr)block.get(), int16Sample, i * chunkSize, chunkSize);
for (size_t b = 0; b < chunkSize; b++)
if (block[b] != v)
bad++;
}
@ -534,8 +535,6 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
Printf(wxT("TEST FAILED!!!\n"));
success:
delete[]small1;
delete[]block;
dd.reset();

View File

@ -193,13 +193,11 @@ void *BlockFile::CalcSummary(samplePtr buffer, size_t len,
float *summary64K = (float *)(fullSummary.get() + mSummaryInfo.offset64K);
float *summary256 = (float *)(fullSummary.get() + mSummaryInfo.offset256);
float *fbuffer = new float[len];
Floats fbuffer{ len };
CopySamples(buffer, format,
(samplePtr)fbuffer, floatSample, len);
(samplePtr)fbuffer.get(), floatSample, len);
CalcSummaryFromBuffer(fbuffer, len, summary256, summary64K);
delete[] fbuffer;
CalcSummaryFromBuffer(fbuffer.get(), len, summary256, summary64K);
return fullSummary.get();
}
@ -436,14 +434,14 @@ bool BlockFile::Read256(float *buffer,
{
wxASSERT(start >= 0);
char *summary = new char[mSummaryInfo.totalSummaryBytes];
ArrayOf<char> summary{ mSummaryInfo.totalSummaryBytes };
// FIXME: TRAP_ERR ReadSummary() could return fail.
this->ReadSummary(summary);
this->ReadSummary(summary.get());
start = std::min( start, mSummaryInfo.frames256 );
len = std::min( len, mSummaryInfo.frames256 - start );
CopySamples(summary + mSummaryInfo.offset256 + (start * mSummaryInfo.bytesPerFrame),
CopySamples(summary.get() + mSummaryInfo.offset256 + (start * mSummaryInfo.bytesPerFrame),
mSummaryInfo.format,
(samplePtr)buffer, floatSample, len * mSummaryInfo.fields);
@ -456,8 +454,6 @@ bool BlockFile::Read256(float *buffer,
}
}
delete[] summary;
return true;
}
@ -475,14 +471,14 @@ bool BlockFile::Read64K(float *buffer,
{
wxASSERT(start >= 0);
char *summary = new char[mSummaryInfo.totalSummaryBytes];
ArrayOf<char> summary{ mSummaryInfo.totalSummaryBytes };
// FIXME: TRAP_ERR ReadSummary() could return fail.
this->ReadSummary(summary);
this->ReadSummary(summary.get());
start = std::min( start, mSummaryInfo.frames64K );
len = std::min( len, mSummaryInfo.frames64K - start );
CopySamples(summary + mSummaryInfo.offset64K +
CopySamples(summary.get() + mSummaryInfo.offset64K +
(start * mSummaryInfo.bytesPerFrame),
mSummaryInfo.format,
(samplePtr)buffer, floatSample, len*mSummaryInfo.fields);
@ -496,8 +492,6 @@ bool BlockFile::Read64K(float *buffer,
}
}
delete[] summary;
return true;
}

View File

@ -39,7 +39,10 @@
* 9: Gaussian(a=4.5)
*/
#include "Audacity.h"
#include "FFT.h"
#include "MemoryX.h"
#include "SampleFormat.h"
#include <wx/intl.h>
#include <stdlib.h>
@ -49,7 +52,7 @@
#include "RealFFTf.h"
#include "Experimental.h"
static int **gFFTBitTable = NULL;
static ArraysOf<int> gFFTBitTable;
static const size_t MaxFastBits = 16;
/* Declare Static functions */
@ -94,15 +97,14 @@ int ReverseBits(size_t index, size_t NumBits)
void InitFFT()
{
gFFTBitTable = new int *[MaxFastBits];
gFFTBitTable.reinit(MaxFastBits);
size_t len = 2;
for (size_t b = 1; b <= MaxFastBits; b++) {
gFFTBitTable[b - 1] = new int[len];
auto &array = gFFTBitTable[b - 1];
array.reinit(len);
for (size_t i = 0; i < len; i++)
gFFTBitTable[b - 1][i] = ReverseBits(i, b);
array[i] = ReverseBits(i, b);
len <<= 1;
}
@ -110,12 +112,7 @@ void InitFFT()
void DeinitFFT()
{
if (gFFTBitTable) {
for (size_t b = 1; b <= MaxFastBits; b++) {
delete[] gFFTBitTable[b-1];
}
delete[] gFFTBitTable;
}
gFFTBitTable.reset();
// Deallocate any unused RealFFTf tables
CleanupFFT();
}
@ -233,31 +230,30 @@ void FFT(size_t NumSamples,
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
{
size_t i;
HFFT hFFT = GetFFT(NumSamples);
float *pFFT = new float[NumSamples];
Floats pFFT{ NumSamples };
// Copy the data into the processing buffer
for(i = 0; i < NumSamples; i++)
for(size_t i = 0; i < NumSamples; i++)
pFFT[i] = RealIn[i];
// Perform the FFT
RealFFTf(pFFT, hFFT);
RealFFTf(pFFT.get(), hFFT);
// Copy the data into the real and imaginary outputs
for(i = 1; i < (NumSamples / 2); i++) {
for (size_t i = 1; i<(NumSamples / 2); i++) {
RealOut[i]=pFFT[hFFT->BitReversed[i] ];
ImagOut[i]=pFFT[hFFT->BitReversed[i]+1];
}
// Handle the (real-only) DC and Fs/2 bins
RealOut[0] = pFFT[0];
RealOut[i] = pFFT[1];
ImagOut[0] = ImagOut[i] = 0;
RealOut[NumSamples / 2] = pFFT[1];
ImagOut[0] = ImagOut[NumSamples / 2] = 0;
// Fill in the upper half using symmetry properties
for(i++ ; i < NumSamples; i++) {
for(size_t i = NumSamples / 2 + 1; i < NumSamples; i++) {
RealOut[i] = RealOut[NumSamples-i];
ImagOut[i] = -ImagOut[NumSamples-i];
}
delete [] pFFT;
ReleaseFFT(hFFT);
}
@ -275,29 +271,27 @@ void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *Imag
void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
float *RealOut)
{
size_t i;
HFFT hFFT = GetFFT(NumSamples);
float *pFFT = new float[NumSamples];
Floats pFFT{ NumSamples };
// Copy the data into the processing buffer
for(i = 0; i < (NumSamples / 2); i++)
for (size_t i = 0; i < (NumSamples / 2); i++)
pFFT[2*i ] = RealIn[i];
if(ImagIn == NULL) {
for(i = 0; i < (NumSamples/2); i++)
for (size_t i = 0; i < (NumSamples / 2); i++)
pFFT[2*i+1] = 0;
} else {
for(i = 0; i < (NumSamples/2); i++)
for (size_t i = 0; i < (NumSamples / 2); i++)
pFFT[2*i+1] = ImagIn[i];
}
// Put the fs/2 component in the imaginary part of the DC bin
pFFT[1] = RealIn[i];
pFFT[1] = RealIn[NumSamples / 2];
// Perform the FFT
InverseRealFFTf(pFFT, hFFT);
InverseRealFFTf(pFFT.get(), hFFT);
// Copy the data to the (purely real) output buffer
ReorderToTime(hFFT, pFFT, RealOut);
ReorderToTime(hFFT, pFFT.get(), RealOut);
delete [] pFFT;
ReleaseFFT(hFFT);
}
@ -314,25 +308,23 @@ void InverseRealFFT(size_t NumSamples, const float *RealIn, const float *ImagIn,
void PowerSpectrum(size_t NumSamples, const float *In, float *Out)
{
size_t i;
HFFT hFFT = GetFFT(NumSamples);
float *pFFT = new float[NumSamples];
Floats pFFT{ NumSamples };
// Copy the data into the processing buffer
for(i = 0; i < NumSamples; i++)
for (size_t i = 0; i<NumSamples; i++)
pFFT[i] = In[i];
// Perform the FFT
RealFFTf(pFFT, hFFT);
RealFFTf(pFFT.get(), hFFT);
// Copy the data into the real and imaginary outputs
for(i = 1; i < NumSamples / 2; i++) {
for (size_t i = 1; i<NumSamples / 2; i++) {
Out[i]= (pFFT[hFFT->BitReversed[i] ]*pFFT[hFFT->BitReversed[i] ])
+ (pFFT[hFFT->BitReversed[i]+1]*pFFT[hFFT->BitReversed[i]+1]);
}
// Handle the (real-only) DC and Fs/2 bins
Out[0] = pFFT[0]*pFFT[0];
Out[i] = pFFT[1]*pFFT[1];
delete [] pFFT;
Out[NumSamples / 2] = pFFT[1]*pFFT[1];
ReleaseFFT(hFFT);
}

View File

@ -189,7 +189,6 @@ FreqWindow::FreqWindow(wxWindow * parent, wxWindowID id,
const wxPoint & pos)
: wxDialogWrapper(parent, id, title, pos, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX),
mData(NULL),
mAnalyst(std::make_unique<SpectrumAnalyst>())
{
SetName(GetTitle());
@ -514,8 +513,6 @@ FreqWindow::FreqWindow(wxWindow * parent, wxWindowID id,
FreqWindow::~FreqWindow()
{
if (mData)
delete[] mData;
}
bool FreqWindow::Show(bool show)
@ -546,10 +543,7 @@ bool FreqWindow::Show(bool show)
void FreqWindow::GetAudio()
{
if (mData) {
delete [] mData;
mData = NULL;
}
mData.reset();
mDataLen = 0;
int selcount = 0;
@ -571,23 +565,21 @@ void FreqWindow::GetAudio()
else
// dataLen is not more than 10 * 2 ^ 20
mDataLen = dataLen.as_size_t();
mData = new float[mDataLen];
track->Get((samplePtr)mData, floatSample, start, mDataLen);
mData = Floats{ mDataLen };
track->Get((samplePtr)mData.get(), floatSample, start, mDataLen);
}
else {
if (track->GetRate() != mRate) {
wxMessageBox(_("To plot the spectrum, all selected tracks must be the same sample rate."));
delete[] mData;
mData = NULL;
mData.reset();
mDataLen = 0;
return;
}
auto start = track->TimeToLongSamples(p->mViewInfo.selectedRegion.t0());
float *buffer2 = new float[mDataLen];
track->Get((samplePtr)buffer2, floatSample, start, mDataLen);
Floats buffer2{ mDataLen };
track->Get((samplePtr)buffer2.get(), floatSample, start, mDataLen);
for (size_t i = 0; i < mDataLen; i++)
mData[i] += buffer2[i];
delete[] buffer2;
}
selcount++;
}
@ -1000,7 +992,7 @@ void FreqWindow::Recalc()
wxYieldIfNeeded();
mAnalyst->Calculate(alg, windowFunc, mWindowSize, mRate,
mData, mDataLen,
mData.get(), mDataLen,
&mYMin, &mYMax, mProgress);
}
if (hadFocus) {
@ -1202,22 +1194,22 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
auto half = mWindowSize / 2;
mProcessed.resize(mWindowSize);
float *in = new float[mWindowSize];
float *out = new float[mWindowSize];
float *out2 = new float[mWindowSize];
float *win = new float[mWindowSize];
Floats in{ mWindowSize };
Floats out{ mWindowSize };
Floats out2{ mWindowSize };
Floats win{ mWindowSize };
for (size_t i = 0; i < mWindowSize; i++) {
mProcessed[i] = 0.0f;
win[i] = 1.0f;
}
WindowFunc(windowFunc, mWindowSize, win);
WindowFunc(windowFunc, mWindowSize, win.get());
// Scale window such that an amplitude of 1.0 in the time domain
// shows an amplitude of 0dB in the frequency domain
double wss = 0;
for(size_t i = 0; i < mWindowSize; i++)
for (size_t i = 0; i<mWindowSize; i++)
wss += win[i];
if(wss > 0)
wss = 4.0 / (wss*wss);
@ -1236,7 +1228,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
switch (alg) {
case Spectrum:
PowerSpectrum(mWindowSize, in, out);
PowerSpectrum(mWindowSize, in.get(), out.get());
for (size_t i = 0; i < half; i++)
mProcessed[i] += out[i];
@ -1247,7 +1239,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
case EnhancedAutocorrelation:
// Take FFT
RealFFT(mWindowSize, in, out, out2);
RealFFT(mWindowSize, in.get(), out.get(), out2.get());
// Compute power
for (size_t i = 0; i < mWindowSize; i++)
in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);
@ -1265,7 +1257,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
in[i] = pow(in[i], 1.0f / 3.0f);
}
// Take FFT
RealFFT(mWindowSize, in, out, out2);
RealFFT(mWindowSize, in.get(), out.get(), out2.get());
// Take real part of result
for (size_t i = 0; i < half; i++)
@ -1273,7 +1265,8 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
break;
case Cepstrum:
RealFFT(mWindowSize, in, out, out2);
RealFFT(mWindowSize, in.get(), out.get(), out2.get());
// Compute log power
// Set a sane lower limit assuming maximum time amplitude of 1.0
{
@ -1288,7 +1281,7 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
in[i] = log(power);
}
// Take IFFT
InverseRealFFT(mWindowSize, in, NULL, out);
InverseRealFFT(mWindowSize, in.get(), NULL, out.get());
// Take real part of result
for (size_t i = 0; i < half; i++)
@ -1407,11 +1400,6 @@ bool SpectrumAnalyst::Calculate(Algorithm alg, int windowFunc,
break;
}
delete[]in;
delete[]out;
delete[]out2;
delete[]win;
if (pYMin)
*pYMin = mYMin;
if (pYMax)

View File

@ -30,6 +30,7 @@
#include <wx/textctrl.h>
#include <wx/utils.h>
#include "widgets/Ruler.h"
#include "SampleFormat.h"
class wxStatusBar;
class wxButton;
@ -198,7 +199,7 @@ private:
double mRate;
size_t mDataLen;
float *mData;
Floats mData;
size_t mWindowSize;
bool mLogAxis;

View File

@ -15,6 +15,7 @@
#include "InterpolateAudio.h"
#include "Matrix.h"
#include "SampleFormat.h"
static inline int imin(int x, int y)
{
@ -78,11 +79,10 @@ static void LinearInterpolateAudio(float *buffer, int len,
// Here's the main interpolate function, using
// Least Squares AutoRegression (LSAR):
void InterpolateAudio(float *buffer, int len,
int firstBad, int numBad)
void InterpolateAudio(float *buffer, const size_t len,
size_t firstBad, size_t numBad)
{
int N = len;
int i, row, col;
const auto N = len;
wxASSERT(len > 0 &&
firstBad >= 0 &&
@ -97,34 +97,35 @@ void InterpolateAudio(float *buffer, int len,
// performs poorly when interpolating to the left. If
// we're asked to interpolate the left side of a buffer,
// we just reverse the problem and try it that way.
float *buffer2 = new float[len];
for(i=0; i<len; i++)
Floats buffer2{ len };
for(size_t i=0; i<len; i++)
buffer2[len-1-i] = buffer[i];
InterpolateAudio(buffer2, len, len-numBad, numBad);
for(i=0; i<len; i++)
InterpolateAudio(buffer2.get(), len, len-numBad, numBad);
for(size_t i=0; i<len; i++)
buffer[len-1-i] = buffer2[i];
delete[] buffer2;
return;
}
Vector s(len, buffer);
// Choose P, the order of the autoregression equation
int P = imin(numBad * 3, 50);
P = imin(P, imax(firstBad - 1, len - (firstBad + numBad) - 1));
const int IP =
imin(imin(numBad * 3, 50), imax(firstBad - 1, len - (firstBad + numBad) - 1));
if (P < 3) {
if (IP < 3 || IP >= N) {
LinearInterpolateAudio(buffer, len, firstBad, numBad);
return;
}
size_t P(IP);
// Add a tiny amount of random noise to the input signal -
// this sounds like a bad idea, but the amount we're adding
// is only about 1 bit in 16-bit audio, and it's an extremely
// effective way to avoid nearly-singular matrices. If users
// run it more than once they get slightly different results;
// this is sometimes even advantageous.
for(i=0; i<N; i++)
for(size_t i=0; i<N; i++)
s[i] += (rand()-(RAND_MAX/2))/(RAND_MAX*10000.0);
// Solve for the best autoregression coefficients
@ -133,10 +134,10 @@ void InterpolateAudio(float *buffer, int len,
Matrix X(P, P);
Vector b(P);
for(i=0; i<len-P; i++)
for(size_t i = 0; i + P < len; i++)
if (i+P < firstBad || i >= (firstBad + numBad))
for(row=0; row<P; row++) {
for(col=0; col<P; col++)
for(size_t row=0; row<P; row++) {
for(size_t col=0; col<P; col++)
X[row][col] += (s[i+row] * s[i+col]);
b[row] += s[i+P] * s[i+row];
}
@ -151,14 +152,14 @@ void InterpolateAudio(float *buffer, int len,
}
// This vector now contains the autoregression coefficients
Vector a = Xinv * b;
const Vector &a = Xinv * b;
// Create a matrix (a "Toeplitz" matrix, as it turns out)
// which encodes the autoregressive relationship between
// elements of the sequence.
Matrix A(N-P, N);
for(row=0; row<N-P; row++) {
for(col=0; col<P; col++)
for(size_t row=0; row<N-P; row++) {
for(size_t col=0; col<P; col++)
A[row][row+col] = -a[col];
A[row][row+P] = 1;
}
@ -175,10 +176,10 @@ void InterpolateAudio(float *buffer, int len,
firstBad+numBad, N-(firstBad+numBad));
Matrix Ak = MatrixConcatenateCols(A_left, A_right);
Vector s_left = VectorSubset(s, 0, firstBad);
Vector s_right = VectorSubset(s, firstBad+numBad,
const Vector &s_left = VectorSubset(s, 0, firstBad);
const Vector &s_right = VectorSubset(s, firstBad+numBad,
N-(firstBad+numBad));
Vector sk = VectorConcatenate(s_left, s_right);
const Vector &sk = VectorConcatenate(s_left, s_right);
// Do some linear algebra to find the best possible
// values that fill in the "bad" area
@ -195,9 +196,9 @@ void InterpolateAudio(float *buffer, int len,
Matrix X4 = MatrixMultiply(X3, Ak);
// This vector contains our best guess as to the
// unknown values
Vector su = X4 * sk;
const Vector &su = X4 * sk;
// Put the results into the return buffer
for(i=0; i<numBad; i++)
for(size_t i=0; i<numBad; i++)
buffer[firstBad+i] = (float)su[i];
}

View File

@ -35,7 +35,7 @@
// side (6x the number of bad samples on either side is great). However,
// it will work with less data, and with the bad samples on one end or
// the other.
void AUDACITY_DLL_API InterpolateAudio(float *buffer, int len,
int firstBad, int numBad);
void AUDACITY_DLL_API InterpolateAudio(float *buffer, size_t len,
size_t firstBad, size_t numBad);
#endif // __AUDACITY_INTERPOLATE_AUDIO__

View File

@ -17,89 +17,74 @@
Vector::Vector()
{
mCopy = false;
mN = 0;
mData = NULL;
}
Vector::Vector(int len, double *data, bool copy)
Vector::Vector(unsigned len, double *data)
: mN{ len }
, mData(len)
{
mN = len;
mCopy = copy;
if (mCopy || !data) {
mCopy = true;
mData = new double[mN];
int i;
for(i=0; i<mN; i++)
if (data)
mData[i] = data[i];
else
mData[i] = 0.0;
}
else {
mCopy = false;
mData = data;
}
if (data)
std::copy(data, data + len, mData.get());
else
std::fill(mData.get(), mData.get() + len, 0.0);
}
Vector::Vector(unsigned len, float *data)
: mN{ len }
, mData{ len }
{
if (data)
std::copy(data, data + len, mData.get());
else
std::fill(mData.get(), mData.get() + len, 0.0);
}
Vector& Vector::operator=(const Vector &other)
{
wxASSERT(Len() == other.Len());
int i;
for(i=0; i<Len(); i++)
mData[i] = other.mData[i];
std::copy(other.mData.get(), other.mData.get() + mN, mData.get());
return *this;
}
Vector::Vector(const Vector &other)
: mN{ other.Len() }
, mData{ mN }
{
CopyFrom(other);
}
void Vector::CopyFrom(const Vector &other)
{
mN = other.Len();
mCopy = true;
mData = new double[mN];
int i;
for(i=0; i<mN; i++)
mData[i] = other.mData[i];
std::copy(other.mData.get(), other.mData.get() + mN, mData.get());
}
Vector::~Vector()
{
if (mCopy)
delete[] mData;
}
Vector::Vector(int len, float *data)
void Vector::Reinit(unsigned len)
{
mCopy = true;
mN = len;
mData = new double[mN];
int i;
for(i=0; i<mN; i++)
mData[i] = (double)data[i];
Vector temp(len);
Swap(temp);
}
void Vector::Swap(Vector &that)
{
std::swap(mN, that.mN);
mData.swap(that.mData);
}
double Vector::Sum() const
{
int i;
double sum = 0.0;
for(i=0; i<Len(); i++)
for(unsigned i = 0; i < Len(); i++)
sum += mData[i];
return sum;
}
Matrix::Matrix(int rows, int cols, double **data)
Matrix::Matrix(unsigned rows, unsigned cols, double **data)
: mRows{ rows }
, mCols{ cols }
, mRowVec{ mRows }
{
mRows = rows;
mCols = cols;
mRowVec = new Vector *[mRows];
int i, j;
for(i=0; i<mRows; i++) {
mRowVec[i] = new Vector(mCols);
for(j=0; j<mCols; j++) {
for(unsigned i = 0; i < mRows; i++) {
mRowVec[i].Reinit( mCols );
for(unsigned j = 0; j < mCols; j++) {
if (data)
(*this)[i][j] = data[i][j];
else
@ -123,44 +108,26 @@ void Matrix::CopyFrom(const Matrix &other)
{
mRows = other.mRows;
mCols = other.mCols;
mRowVec = new Vector *[mRows];
int i;
for(i=0; i<mRows; i++) {
mRowVec[i] = new Vector(mCols);
*mRowVec[i] = *other.mRowVec[i];
mRowVec.reinit(mRows);
for (unsigned i = 0; i < mRows; i++) {
mRowVec[i].Reinit( mCols );
mRowVec[i] = other.mRowVec[i];
}
}
Matrix::~Matrix()
{
int i;
for(i=0; i<mRows; i++)
delete mRowVec[i];
delete[] mRowVec;
}
void Matrix::SwapRows(int i, int j)
void Matrix::SwapRows(unsigned i, unsigned j)
{
Vector *tmp = mRowVec[i];
mRowVec[i] = mRowVec[j];
mRowVec[j] = tmp;
mRowVec[i].Swap(mRowVec[j]);
}
double Matrix::Sum() const
{
int i, j;
double sum = 0.0;
for(i=0; i<Rows(); i++)
for(j=0; j<Cols(); j++)
sum += (*mRowVec[i])[j];
return sum;
}
Matrix IdentityMatrix(int N)
Matrix IdentityMatrix(unsigned N)
{
Matrix M(N, N);
int i;
for(i=0; i<N; i++)
for(unsigned i = 0; i < N; i++)
M[i][i] = 1.0;
return M;
}
@ -169,8 +136,7 @@ Vector operator+(const Vector &left, const Vector &right)
{
wxASSERT(left.Len() == right.Len());
Vector v(left.Len());
int i;
for(i=0; i<left.Len(); i++)
for(unsigned i = 0; i < left.Len(); i++)
v[i] = left[i] + right[i];
return v;
}
@ -179,8 +145,7 @@ Vector operator-(const Vector &left, const Vector &right)
{
wxASSERT(left.Len() == right.Len());
Vector v(left.Len());
int i;
for(i=0; i<left.Len(); i++)
for(unsigned i = 0; i < left.Len(); i++)
v[i] = left[i] - right[i];
return v;
}
@ -189,8 +154,7 @@ Vector operator*(const Vector &left, const Vector &right)
{
wxASSERT(left.Len() == right.Len());
Vector v(left.Len());
int i;
for(i=0; i<left.Len(); i++)
for(unsigned i = 0; i < left.Len(); i++)
v[i] = left[i] * right[i];
return v;
}
@ -198,17 +162,15 @@ Vector operator*(const Vector &left, const Vector &right)
Vector operator*(const Vector &left, double right)
{
Vector v(left.Len());
int i;
for(i=0; i<left.Len(); i++)
for(unsigned i = 0; i < left.Len(); i++)
v[i] = left[i] * right;
return v;
}
Vector VectorSubset(const Vector &other, int start, int len)
Vector VectorSubset(const Vector &other, unsigned start, unsigned len)
{
Vector v(len);
int i;
for(i=0; i<len; i++)
for(unsigned i = 0; i < len; i++)
v[i] = other[start+i];
return v;
}
@ -216,10 +178,9 @@ Vector VectorSubset(const Vector &other, int start, int len)
Vector VectorConcatenate(const Vector& left, const Vector& right)
{
Vector v(left.Len() + right.Len());
int i;
for(i=0; i<left.Len(); i++)
for(unsigned i = 0; i < left.Len(); i++)
v[i] = left[i];
for(i=0; i<right.Len(); i++)
for(unsigned i = 0; i < right.Len(); i++)
v[i + left.Len()] = right[i];
return v;
}
@ -228,10 +189,9 @@ Vector operator*(const Vector &left, const Matrix &right)
{
wxASSERT(left.Len() == right.Rows());
Vector v(right.Cols());
int i, j;
for(i=0; i<right.Cols(); i++) {
for(unsigned i = 0; i < right.Cols(); i++) {
v[i] = 0.0;
for(j=0; j<right.Rows(); j++)
for(unsigned j = 0; j < right.Rows(); j++)
v[i] += left[j] * right[j][i];
}
return v;
@ -241,10 +201,9 @@ Vector operator*(const Matrix &left, const Vector &right)
{
wxASSERT(left.Cols() == right.Len());
Vector v(left.Rows());
int i, j;
for(i=0; i<left.Rows(); i++) {
for(unsigned i = 0; i < left.Rows(); i++) {
v[i] = 0.0;
for(j=0; j<left.Cols(); j++)
for(unsigned j = 0; j < left.Cols(); j++)
v[i] += left[i][j] * right[j];
}
return v;
@ -255,9 +214,8 @@ Matrix operator+(const Matrix &left, const Matrix &right)
wxASSERT(left.Rows() == right.Rows());
wxASSERT(left.Cols() == right.Cols());
Matrix M(left.Rows(), left.Cols());
int i, j;
for(i=0; i<left.Rows(); i++)
for(j=0; j<left.Cols(); j++)
for(unsigned i = 0; i < left.Rows(); i++)
for(unsigned j = 0; j < left.Cols(); j++)
M[i][j] = left[i][j] + right[i][j];
return M;
}
@ -265,9 +223,8 @@ Matrix operator+(const Matrix &left, const Matrix &right)
Matrix operator*(const Matrix &left, const double right)
{
Matrix M(left.Rows(), left.Cols());
int i, j;
for(i=0; i<left.Rows(); i++)
for(j=0; j<left.Cols(); j++)
for(unsigned i = 0; i < left.Rows(); i++)
for(unsigned j = 0; j < left.Cols(); j++)
M[i][j] = left[i][j] * right;
return M;
}
@ -277,9 +234,8 @@ Matrix ScalarMultiply(const Matrix &left, const Matrix &right)
wxASSERT(left.Rows() == right.Rows());
wxASSERT(left.Cols() == right.Cols());
Matrix M(left.Rows(), left.Cols());
int i, j;
for(i=0; i<left.Rows(); i++)
for(j=0; j<left.Cols(); j++)
for(unsigned i = 0; i < left.Rows(); i++)
for(unsigned j = 0; j < left.Cols(); j++)
M[i][j] = left[i][j] * right[i][j];
return M;
}
@ -288,23 +244,22 @@ Matrix MatrixMultiply(const Matrix &left, const Matrix &right)
{
wxASSERT(left.Cols() == right.Rows());
Matrix M(left.Rows(), right.Cols());
int i, j, k;
for(i=0; i<left.Rows(); i++)
for(j=0; j<right.Cols(); j++) {
for(unsigned i = 0; i < left.Rows(); i++)
for(unsigned j = 0; j < right.Cols(); j++) {
M[i][j] = 0.0;
for(k=0; k<left.Cols(); k++)
for(unsigned k = 0; k < left.Cols(); k++)
M[i][j] += left[i][k] * right[k][j];
}
return M;
}
Matrix MatrixSubset(const Matrix &input,
int startRow, int numRows, int startCol, int numCols)
unsigned startRow, unsigned numRows,
unsigned startCol, unsigned numCols)
{
Matrix M(numRows, numCols);
int i, j;
for(i=0; i<numRows; i++)
for(j=0; j<numCols; j++)
for(unsigned i = 0; i < numRows; i++)
for(unsigned j = 0; j < numCols; j++)
M[i][j] = input[startRow+i][startCol+j];
return M;
}
@ -313,11 +268,10 @@ Matrix MatrixConcatenateCols(const Matrix& left, const Matrix& right)
{
wxASSERT(left.Rows() == right.Rows());
Matrix M(left.Rows(), left.Cols() + right.Cols());
int i, j;
for(i=0; i<left.Rows(); i++) {
for(j=0; j<left.Cols(); j++)
for(unsigned i = 0; i < left.Rows(); i++) {
for(unsigned j = 0; j < left.Cols(); j++)
M[i][j] = left[i][j];
for(j=0; j<right.Cols(); j++)
for(unsigned j = 0; j < right.Cols(); j++)
M[i][j+left.Cols()] = right[i][j];
}
return M;
@ -326,9 +280,8 @@ Matrix MatrixConcatenateCols(const Matrix& left, const Matrix& right)
Matrix TransposeMatrix(const Matrix& other)
{
Matrix M(other.Cols(), other.Rows());
int i, j;
for(i=0; i<other.Rows(); i++)
for(j=0; j<other.Cols(); j++)
for(unsigned i = 0; i < other.Rows(); i++)
for(unsigned j = 0; j < other.Cols(); j++)
M[j][i] = other[i][j];
return M;
}
@ -340,20 +293,19 @@ bool InvertMatrix(const Matrix& input, Matrix& Minv)
// Returns true if successful
wxASSERT(input.Rows() == input.Cols());
int N = input.Rows();
int i, j, k;
auto N = input.Rows();
Matrix M = input;
Minv = IdentityMatrix(N);
// Do the elimination one column at a time
for(i=0; i<N; i++) {
for(unsigned i = 0; i < N; i++) {
// Pivot the row with the largest absolute value in
// column i, into row i
double absmax = 0.0;
int argmax=0;
int argmax = 0;
for(j=i; j<N; j++)
for(unsigned j = i; j < N; j++)
if (fabs(M[j][i]) > absmax) {
absmax = fabs(M[j][i]);
argmax = j;
@ -375,13 +327,13 @@ bool InvertMatrix(const Matrix& input, Matrix& Minv)
Minv[i] = Minv[i] * factor;
// Eliminate the rest of the column
for(j=0; j<N; j++) {
if (j==i)
for(unsigned j = 0; j < N; j++) {
if (j == i)
continue;
if (fabs(M[j][i]) > 0) {
// Subtract a multiple of row i from row j
double factor = M[j][i];
for(k=0; k<N; k++) {
for(unsigned k = 0; k < N; k++) {
M[j][k] -= (M[i][k] * factor);
Minv[j][k] -= (Minv[i][k] * factor);
}

View File

@ -26,6 +26,8 @@
#ifndef __AUDACITY_MATRIX__
#define __AUDACITY_MATRIX__
#include "SampleFormat.h"
class Matrix;
class Vector
@ -33,63 +35,61 @@ class Vector
public:
Vector();
Vector(const Vector& copyFrom);
Vector(int len, double *data=NULL, bool copy=true);
Vector(int len, float *data);
Vector(unsigned len, double *data=NULL);
Vector(unsigned len, float *data);
Vector& operator=(const Vector &other);
virtual ~Vector();
~Vector();
inline double& operator[](int i) { return mData[i]; }
inline double operator[](int i) const { return mData[i]; }
inline int Len() const { return mN; }
void Reinit(unsigned len);
void Swap(Vector &that);
inline double& operator[](unsigned i) { return mData[i]; }
inline double operator[](unsigned i) const { return mData[i]; }
inline unsigned Len() const { return mN; }
double Sum() const;
private:
void CopyFrom(const Vector &other);
int mN;
double *mData;
bool mCopy;
unsigned mN{ 0 };
Doubles mData;
};
class Matrix
{
public:
Matrix(const Matrix& copyFrom);
Matrix(int rows, int cols, double **data=NULL);
virtual ~Matrix();
Matrix(unsigned rows, unsigned cols, double **data=NULL);
~Matrix();
Matrix& operator=(const Matrix& other);
inline Vector& operator[](int i) { return *mRowVec[i]; }
inline Vector& operator[](int i) const { return *mRowVec[i]; }
inline int Rows() const { return mRows; }
inline int Cols() const { return mCols; }
inline Vector& operator[](unsigned i) { return mRowVec[i]; }
inline Vector& operator[](unsigned i) const { return mRowVec[i]; }
inline unsigned Rows() const { return mRows; }
inline unsigned Cols() const { return mCols; }
void SwapRows(int i, int j);
double Sum() const;
void SwapRows(unsigned i, unsigned j);
private:
void CopyFrom(const Matrix& other);
int mRows;
int mCols;
Vector **mRowVec;
unsigned mRows;
unsigned mCols;
ArrayOf<Vector> mRowVec;
};
bool InvertMatrix(const Matrix& input, Matrix& Minv);
Matrix TransposeMatrix(const Matrix& M);
Matrix IdentityMatrix(int N);
Matrix IdentityMatrix(unsigned N);
Vector operator+(const Vector &left, const Vector &right);
Vector operator-(const Vector &left, const Vector &right);
Vector operator*(const Vector &left, const Vector &right);
Vector operator*(const Vector &left, double right);
Vector VectorSubset(const Vector &other, int start, int len);
Vector VectorSubset(const Vector &other, unsigned start, unsigned len);
Vector VectorConcatenate(const Vector& left, const Vector& right);
Vector operator*(const Vector &left, const Matrix &right);
@ -103,7 +103,8 @@ Matrix ScalarMultiply(const Matrix &left, const Matrix &right);
Matrix MatrixMultiply(const Matrix &left, const Matrix &right);
Matrix MatrixSubset(const Matrix &M,
int startRow, int numRows, int startCol, int numCols);
unsigned startRow, unsigned numRows,
unsigned startCol, unsigned numCols);
Matrix MatrixConcatenateCols(const Matrix& left, const Matrix& right);

View File

@ -3439,12 +3439,8 @@ void AudacityProject::OnPlaySpeedDec()
double AudacityProject::NearestZeroCrossing(double t0)
{
// Window is 1/100th of a second.
int windowSize = (int)(GetRate() / 100);
float *dist = new float[windowSize];
int i, j;
for(i=0; i<windowSize; i++)
dist[i] = 0.0;
auto windowSize = size_t(std::max(1.0, GetRate() / 100));
Floats dist{ windowSize, true };
TrackListIterator iter(GetTracks());
Track *track = iter.First();
@ -3454,26 +3450,26 @@ double AudacityProject::NearestZeroCrossing(double t0)
continue;
}
WaveTrack *one = (WaveTrack *)track;
int oneWindowSize = (int)(one->GetRate() / 100);
float *oneDist = new float[oneWindowSize];
auto oneWindowSize = size_t(std::max(1.0, one->GetRate() / 100));
Floats oneDist{ oneWindowSize };
auto s = one->TimeToLongSamples(t0);
// fillTwo to ensure that missing values are treated as 2, and hence do not
// get used as zero crossings.
one->Get((samplePtr)oneDist, floatSample,
s - oneWindowSize/2, oneWindowSize, fillTwo);
one->Get((samplePtr)oneDist.get(), floatSample,
s - (int)oneWindowSize/2, oneWindowSize, fillTwo);
// Start by penalizing downward motion. We prefer upward
// zero crossings.
if (oneDist[1] - oneDist[0] < 0)
oneDist[0] = oneDist[0]*6 + (oneDist[0] > 0 ? 0.3 : -0.3);
for(i=1; i<oneWindowSize; i++)
for(size_t i=1; i<oneWindowSize; i++)
if (oneDist[i] - oneDist[i-1] < 0)
oneDist[i] = oneDist[i]*6 + (oneDist[i] > 0 ? 0.3 : -0.3);
// Taking the absolute value -- apply a tiny LPF so square waves work.
float newVal, oldVal = oneDist[0];
oneDist[0] = fabs(.75 * oneDist[0] + .25 * oneDist[1]);
for(i=1; i<oneWindowSize-1; i++)
for(size_t i=1; i + 1 < oneWindowSize; i++)
{
newVal = fabs(.25 * oldVal + .5 * oneDist[i] + .25 * oneDist[i+1]);
oldVal = oneDist[i];
@ -3485,7 +3481,8 @@ double AudacityProject::NearestZeroCrossing(double t0)
// TODO: The mixed rate zero crossing code is broken,
// if oneWindowSize > windowSize we'll miss out some
// samples - so they will still be zero, so we'll use them.
for(i=0; i<windowSize; i++) {
for(size_t i = 0; i < windowSize; i++) {
size_t j;
if (windowSize != oneWindowSize)
j = i * (oneWindowSize-1) / (windowSize-1);
else
@ -3493,26 +3490,23 @@ double AudacityProject::NearestZeroCrossing(double t0)
dist[i] += oneDist[j];
// Apply a small penalty for distance from the original endpoint
dist[i] += 0.1 * (abs(i - windowSize/2)) / float(windowSize/2);
dist[i] += 0.1 * (abs(int(i) - int(windowSize/2))) / float(windowSize/2);
}
delete [] oneDist;
track = iter.Next();
}
// Find minimum
int argmin = 0;
float min = 3.0;
for(i=0; i<windowSize; i++) {
for(size_t i=0; i<windowSize; i++) {
if (dist[i] < min) {
argmin = i;
min = dist[i];
}
}
delete [] dist;
return t0 + (argmin - windowSize/2)/GetRate();
return t0 + (argmin - (int)windowSize/2)/GetRate();
}
void AudacityProject::OnZeroCrossing()

View File

@ -244,18 +244,24 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
double outRate, sampleFormat outFormat,
bool highQuality, MixerSpec *mixerSpec)
{
int i;
: mNumInputTracks { inputTracks.size() }
const auto numInputTracks = inputTracks.size();
// This is the number of samples grabbed in one go from a track
// and placed in a queue, when mixing with resampling.
// (Should we use WaveTrack::GetBestBlockSize instead?)
, mQueueMaxLen{ 65536 }
, mSampleQueue{ mNumInputTracks, mQueueMaxLen }
, mNumChannels{ static_cast<size_t>(numOutChannels) }
, mGains{ mNumChannels }
{
mHighQuality = highQuality;
mNumInputTracks = numInputTracks;
mInputTrack = new WaveTrackCache[mNumInputTracks];
mInputTrack.reinit(mNumInputTracks);
// mSamplePos holds for each track the next sample position not
// yet processed.
mSamplePos = new sampleCount[mNumInputTracks];
for(i=0; i<mNumInputTracks; i++) {
mSamplePos.reinit(mNumInputTracks);
for(size_t i=0; i<mNumInputTracks; i++) {
mInputTrack[i].SetTrack(inputTracks[i]);
mSamplePos[i] = inputTracks[i]->TimeToLongSamples(startTime);
}
@ -263,14 +269,12 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
mT0 = startTime;
mT1 = stopTime;
mTime = startTime;
mNumChannels = numOutChannels;
mBufferSize = outBufferSize;
mInterleaved = outInterleaved;
mRate = outRate;
mSpeed = 1.0;
mFormat = outFormat;
mApplyTrackGains = true;
mGains = new float[mNumChannels];
if( mixerSpec && mixerSpec->GetNumChannels() == mNumChannels &&
mixerSpec->GetNumTracks() == mNumInputTracks )
mMixerSpec = mixerSpec;
@ -286,18 +290,13 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
mInterleavedBufferSize = mBufferSize;
}
mBuffer = new SampleBuffer[mNumBuffers];
mTemp = new SampleBuffer[mNumBuffers];
mBuffer.reinit(mNumBuffers);
mTemp.reinit(mNumBuffers);
for (int c = 0; c < mNumBuffers; c++) {
mBuffer[c].Allocate(mInterleavedBufferSize, mFormat);
mTemp[c].Allocate(mInterleavedBufferSize, floatSample);
}
mFloatBuffer = new float[mInterleavedBufferSize];
// This is the number of samples grabbed in one go from a track
// and placed in a queue, when mixing with resampling.
// (Should we use WaveTrack::GetBestBlockSize instead?)
mQueueMaxLen = 65536;
mFloatBuffer = Floats{ mInterleavedBufferSize };
// But cut the queue into blocks of this finer size
// for variable rate resampling. Each block is resampled at some
@ -305,13 +304,12 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
mProcessLen = 1024;
// Position in each queue of the start of the next block to resample.
mQueueStart = new int[mNumInputTracks];
mQueueStart.reinit(mNumInputTracks);
// For each queue, the number of available samples after the queue start.
mQueueLen = new int[mNumInputTracks];
mSampleQueue = new float *[mNumInputTracks];
mResample = new Resample*[mNumInputTracks];
for(i=0; i<mNumInputTracks; i++) {
mQueueLen.reinit(mNumInputTracks);
mResample.reinit(mNumInputTracks);
for(size_t i=0; i<mNumInputTracks; i++) {
double factor = (mRate / mInputTrack[i].GetTrack()->GetRate());
double minFactor, maxFactor;
if (mTimeTrack) {
@ -332,36 +330,17 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
minFactor = maxFactor = factor;
}
mResample[i] = new Resample(mHighQuality, minFactor, maxFactor);
mSampleQueue[i] = new float[mQueueMaxLen];
mResample[i] = std::make_unique<Resample>(mHighQuality, minFactor, maxFactor);
mQueueStart[i] = 0;
mQueueLen[i] = 0;
}
const auto envLen = std::max(mQueueMaxLen, mInterleavedBufferSize);
mEnvValues = new double[envLen];
mEnvValues.reinit(envLen);
}
Mixer::~Mixer()
{
int i;
delete[] mBuffer;
delete[] mTemp;
delete[] mInputTrack;
delete[] mEnvValues;
delete[] mFloatBuffer;
delete[] mGains;
delete[] mSamplePos;
for(i=0; i<mNumInputTracks; i++) {
delete mResample[i];
delete[] mSampleQueue[i];
}
delete[] mResample;
delete[] mSampleQueue;
delete[] mQueueStart;
delete[] mQueueLen;
}
void Mixer::ApplyTrackGains(bool apply)
@ -461,7 +440,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
else
memset(&queue[*queueLen], 0, sizeof(float) * getLen);
track->GetEnvelopeValues(mEnvValues,
track->GetEnvelopeValues(mEnvValues.get(),
getLen,
(*pos - (getLen- 1)).as_double() / trackRate);
*pos -= getLen;
@ -473,7 +452,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
else
memset(&queue[*queueLen], 0, sizeof(float) * getLen);
track->GetEnvelopeValues(mEnvValues,
track->GetEnvelopeValues(mEnvValues.get(),
getLen,
(*pos).as_double() / trackRate);
@ -532,7 +511,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
}
}
for (int c = 0; c < mNumChannels; c++) {
for (size_t c = 0; c < mNumChannels; c++) {
if (mApplyTrackGains) {
mGains[c] = track->GetChannelGain(c);
}
@ -543,9 +522,9 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
MixBuffers(mNumChannels,
channelFlags,
mGains,
(samplePtr)mFloatBuffer,
mTemp,
mGains.get(),
(samplePtr)mFloatBuffer.get(),
mTemp.get(),
out,
mInterleaved);
@ -557,7 +536,6 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
{
const WaveTrack *const track = cache.GetTrack();
auto slen = mMaxOut;
int c;
const double t = ( *pos ).as_double() / track->GetRate();
const double trackEndTime = track->GetEndTime();
const double trackStartTime = track->GetStartTime();
@ -578,37 +556,37 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
if (backwards) {
auto results = cache.Get(floatSample, *pos - (slen - 1), slen);
if (results)
memcpy(mFloatBuffer, results, sizeof(float) * slen);
memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
else
memset(mFloatBuffer, 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues, slen, t - (slen - 1) / mRate);
memset(mFloatBuffer.get(), 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues.get(), slen, t - (slen - 1) / mRate);
for(decltype(slen) i = 0; i < slen; i++)
mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
ReverseSamples((samplePtr)mFloatBuffer, floatSample, 0, slen);
ReverseSamples((samplePtr)mFloatBuffer.get(), floatSample, 0, slen);
*pos -= slen;
}
else {
auto results = cache.Get(floatSample, *pos, slen);
if (results)
memcpy(mFloatBuffer, results, sizeof(float) * slen);
memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
else
memset(mFloatBuffer, 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues, slen, t);
memset(mFloatBuffer.get(), 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues.get(), slen, t);
for(decltype(slen) i = 0; i < slen; i++)
mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
*pos += slen;
}
for(c=0; c<mNumChannels; c++)
for(size_t c=0; c<mNumChannels; c++)
if (mApplyTrackGains)
mGains[c] = track->GetChannelGain(c);
else
mGains[c] = 1.0;
MixBuffers(mNumChannels, channelFlags, mGains,
(samplePtr)mFloatBuffer, mTemp, slen, mInterleaved);
MixBuffers(mNumChannels, channelFlags, mGains.get(),
(samplePtr)mFloatBuffer.get(), mTemp.get(), slen, mInterleaved);
return slen;
}
@ -620,28 +598,27 @@ size_t Mixer::Process(size_t maxToProcess)
//if (mT >= mT1)
// return 0;
int i, j;
decltype(Process(0)) maxOut = 0;
int *channelFlags = new int[mNumChannels];
ArrayOf<int> channelFlags{ mNumChannels };
mMaxOut = maxToProcess;
Clear();
for(i=0; i<mNumInputTracks; i++) {
for(size_t i=0; i<mNumInputTracks; i++) {
const WaveTrack *const track = mInputTrack[i].GetTrack();
for(j=0; j<mNumChannels; j++)
for(size_t j=0; j<mNumChannels; j++)
channelFlags[j] = 0;
if( mMixerSpec ) {
//ignore left and right when downmixing is not required
for( j = 0; j < mNumChannels; j++ )
for(size_t j = 0; j < mNumChannels; j++ )
channelFlags[ j ] = mMixerSpec->mMap[ i ][ j ] ? 1 : 0;
}
else {
switch(track->GetChannel()) {
case Track::MonoChannel:
default:
for(j=0; j<mNumChannels; j++)
for(size_t j=0; j<mNumChannels; j++)
channelFlags[j] = 1;
break;
case Track::LeftChannel:
@ -657,12 +634,12 @@ size_t Mixer::Process(size_t maxToProcess)
}
if (mbVariableRates || track->GetRate() != mRate)
maxOut = std::max(maxOut,
MixVariableRates(channelFlags, mInputTrack[i],
&mSamplePos[i], mSampleQueue[i],
&mQueueStart[i], &mQueueLen[i], mResample[i]));
MixVariableRates(channelFlags.get(), mInputTrack[i],
&mSamplePos[i], mSampleQueue[i].get(),
&mQueueStart[i], &mQueueLen[i], mResample[i].get()));
else
maxOut = std::max(maxOut,
MixSameRate(channelFlags, mInputTrack[i], &mSamplePos[i]));
MixSameRate(channelFlags.get(), mInputTrack[i], &mSamplePos[i]));
double t = mSamplePos[i].as_double() / (double)track->GetRate();
if (mT0 > mT1)
@ -673,7 +650,7 @@ size_t Mixer::Process(size_t maxToProcess)
mTime = std::min(std::max(t, mTime), mT1);
}
if(mInterleaved) {
for(int c=0; c<mNumChannels; c++) {
for(size_t c=0; c<mNumChannels; c++) {
CopySamples(mTemp[0].ptr() + (c * SAMPLE_SIZE(floatSample)),
floatSample,
mBuffer[0].ptr() + (c * SAMPLE_SIZE(mFormat)),
@ -685,7 +662,7 @@ size_t Mixer::Process(size_t maxToProcess)
}
}
else {
for(int c=0; c<mNumBuffers; c++) {
for(size_t c=0; c<mNumBuffers; c++) {
CopySamples(mTemp[c].ptr(),
floatSample,
mBuffer[c].ptr(),
@ -697,8 +674,6 @@ size_t Mixer::Process(size_t maxToProcess)
// MB: this doesn't take warping into account, replaced with code based on mSamplePos
//mT += (maxOut / mRate);
delete [] channelFlags;
return maxOut;
}
@ -719,14 +694,12 @@ double Mixer::MixGetCurrentTime()
void Mixer::Restart()
{
int i;
mTime = mT0;
for(i=0; i<mNumInputTracks; i++)
for(size_t i=0; i<mNumInputTracks; i++)
mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mT0);
for(i=0; i<mNumInputTracks; i++) {
for(size_t i=0; i<mNumInputTracks; i++) {
mQueueStart[i] = 0;
mQueueLen[i] = 0;
}
@ -734,8 +707,6 @@ void Mixer::Restart()
void Mixer::Reposition(double t)
{
int i;
mTime = t;
const bool backwards = (mT1 < mT0);
if (backwards)
@ -743,7 +714,7 @@ void Mixer::Reposition(double t)
else
mTime = std::max(mT0, (std::min(mT1, mTime)));
for(i=0; i<mNumInputTracks; i++) {
for(size_t i=0; i<mNumInputTracks; i++) {
mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mTime);
mQueueStart[i] = 0;
mQueueLen[i] = 0;
@ -789,22 +760,11 @@ MixerSpec::MixerSpec( const MixerSpec &mixerSpec )
void MixerSpec::Alloc()
{
mMap = new bool*[ mNumTracks ];
for( int i = 0; i < mNumTracks; i++ )
mMap[ i ] = new bool[ mMaxNumChannels ];
mMap.reinit(mNumTracks, mMaxNumChannels);
}
MixerSpec::~MixerSpec()
{
Free();
}
void MixerSpec::Free()
{
for( int i = 0; i < mNumTracks; i++ )
delete[] mMap[ i ];
delete[] mMap;
}
bool MixerSpec::SetNumChannels( unsigned newNumChannels )
@ -830,8 +790,6 @@ bool MixerSpec::SetNumChannels( unsigned newNumChannels )
MixerSpec& MixerSpec::operator=( const MixerSpec &mixerSpec )
{
Free();
mNumTracks = mixerSpec.mNumTracks;
mNumChannels = mixerSpec.mNumChannels;
mMaxNumChannels = mixerSpec.mMaxNumChannels;

View File

@ -51,10 +51,9 @@ class AUDACITY_DLL_API MixerSpec
unsigned mNumTracks, mNumChannels, mMaxNumChannels;
void Alloc();
void Free();
public:
bool **mMap;
public:
ArraysOf<bool> mMap;
MixerSpec( unsigned numTracks, unsigned maxNumChannels );
MixerSpec( const MixerSpec &mixerSpec );
@ -150,38 +149,37 @@ class AUDACITY_DLL_API Mixer {
Resample * pResample);
private:
// Input
int mNumInputTracks;
WaveTrackCache *mInputTrack;
// Input
size_t mNumInputTracks;
ArrayOf<WaveTrackCache> mInputTrack;
bool mbVariableRates;
const TimeTrack *mTimeTrack;
sampleCount *mSamplePos;
ArrayOf<sampleCount> mSamplePos;
bool mApplyTrackGains;
float *mGains;
double *mEnvValues;
Doubles mEnvValues;
double mT0; // Start time
double mT1; // Stop time (none if mT0==mT1)
double mTime; // Current time (renamed from mT to mTime for consistency with AudioIO - mT represented warped time there)
Resample **mResample;
float **mSampleQueue;
int *mQueueStart;
int *mQueueLen;
ArrayOf<std::unique_ptr<Resample>> mResample;
size_t mQueueMaxLen;
FloatBuffers mSampleQueue;
ArrayOf<int> mQueueStart;
ArrayOf<int> mQueueLen;
size_t mProcessLen;
MixerSpec *mMixerSpec;
// Output
size_t mMaxOut;
unsigned mNumChannels;
Floats mGains;
unsigned mNumBuffers;
size_t mBufferSize;
size_t mInterleavedBufferSize;
sampleFormat mFormat;
bool mInterleaved;
SampleBuffer *mBuffer;
SampleBuffer *mTemp;
float *mFloatBuffer;
ArrayOf<SampleBuffer> mBuffer, mTemp;
Floats mFloatBuffer;
double mRate;
double mSpeed;
bool mHighQuality;

View File

@ -568,12 +568,12 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
// stored in blockfiles, rather than calculating them, but for now, changing it to use the
// original Meter::UpdateDisplay(). New code is below the previous (now commented out).
//
//const int kFramesPerBuffer = 4;
//const size_t kFramesPerBuffer = 4;
//float min; // dummy, since it's not shown in meters
//float* maxLeft = new float[kFramesPerBuffer];
//float* rmsLeft = new float[kFramesPerBuffer];
//float* maxRight = new float[kFramesPerBuffer];
//float* rmsRight = new float[kFramesPerBuffer];
//Floats maxLeft{kFramesPerBuffer};
//Floats rmsLeft{kFramesPerBuffer};
//Floats maxRight{kFramesPerBuffer};
//Floats rmsRight{kFramesPerBuffer};
//
//#ifdef EXPERIMENTAL_MIDI_OUT
// bool bSuccess = (mLeftTrack != NULL);
@ -628,10 +628,6 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
// mLeftTrack->TimeToLongSamples(t1 - t0));
//}
//
//delete[] maxLeft;
//delete[] rmsLeft;
//delete[] maxRight;
//delete[] rmsRight;
auto startSample = (sampleCount)((mLeftTrack->GetRate() * t0) + 0.5);
auto scnFrames = (sampleCount)((mLeftTrack->GetRate() * (t1 - t0)) + 0.5);
@ -640,22 +636,22 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
// in about 1/20 second (ticks of TrackPanel timer), so this won't overflow
auto nFrames = scnFrames.as_size_t();
float* meterFloatsArray = NULL;
float* tempFloatsArray = new float[nFrames];
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray, floatSample, startSample, nFrames);
Floats tempFloatsArray{ size_t(nFrames) };
decltype(tempFloatsArray) meterFloatsArray;
bool bSuccess = mLeftTrack->Get((samplePtr)tempFloatsArray.get(), floatSample, startSample, nFrames);
if (bSuccess)
{
// We always pass a stereo sample array to the meter, as it shows 2 channels.
// Mono shows same in both meters.
// Since we're not mixing, need to duplicate same signal for "right" channel in mono case.
meterFloatsArray = new float[2 * nFrames];
meterFloatsArray = Floats{ 2 * nFrames };
// Interleave for stereo. Left/mono first.
for (int index = 0; index < nFrames; index++)
meterFloatsArray[2 * index] = tempFloatsArray[index];
if (mRightTrack)
bSuccess = mRightTrack->Get((samplePtr)tempFloatsArray, floatSample, startSample, nFrames);
bSuccess = mRightTrack->Get((samplePtr)tempFloatsArray.get(), floatSample, startSample, nFrames);
if (bSuccess)
// Interleave right channel, or duplicate same signal for "right" channel in mono case.
@ -686,13 +682,10 @@ void MixerTrackCluster::UpdateMeter(const double t0, const double t1)
else if (meterFloatsArray[index] > 1.0)
meterFloatsArray[index] = 1.0;
mMeter->UpdateDisplay(2, nFrames, meterFloatsArray);
mMeter->UpdateDisplay(2, nFrames, meterFloatsArray.get());
}
else
this->ResetMeter(false);
delete[] meterFloatsArray;
delete[] tempFloatsArray;
}
// private

View File

@ -2794,9 +2794,8 @@ wxString PluginManager::ConvertID(const PluginID & ID)
if (ID.StartsWith(wxT("base64:")))
{
wxString id = ID.Mid(7);
char *buf = new char[id.Length() / 4 * 3];
id = wxString::FromUTF8(buf, b64decode(id, buf));
delete [] buf;
ArrayOf<char> buf{ id.Length() / 4 * 3 };
id = wxString::FromUTF8(buf.get(), b64decode(id, buf.get()));
return id;
}

View File

@ -43,7 +43,7 @@ Profiler::~Profiler()
{
if(mTasks[i]->mNumHits>0)
{
fprintf(log,"Task: %s\n(begins at line %d in %s)\n\n",mTasks[i]->mDescription,mTasks[i]->mLine,mTasks[i]->mFileName);
fprintf(log,"Task: %s\n(begins at line %d in %s)\n\n",mTasks[i]->mDescription.get(), mTasks[i]->mLine, mTasks[i]->mFileName.get());
fprintf(log,"Number of times run: %d\n",mTasks[i]->mNumHits);
fprintf(log,"Total run time (seconds): %f\n", (double)mTasks[i]->mCumTime/CLOCKS_PER_SEC);
fprintf(log,"Average run time (seconds): %f\n",mTasks[i]->ComputeAverageRunTime());
@ -91,7 +91,7 @@ TaskProfile* Profiler::GetOrCreateTaskProfile(const char* fileName, int lineNum)
{
for(int i=0;i<(int)mTasks.size();i++)
{
if(strcmp(fileName,mTasks[i]->mFileName)==0 && lineNum == mTasks[i]->mLine)
if(strcmp(fileName, mTasks[i]->mFileName.get())==0 && lineNum == mTasks[i]->mLine)
return mTasks[i].get();
}
@ -104,7 +104,7 @@ TaskProfile* Profiler::GetTaskProfileByDescription(const char* description)
{
for(int i=0;i<(int)mTasks.size();i++)
{
if(strcmp(description,mTasks[i]->mDescription)==0)
if(strcmp(description, mTasks[i]->mDescription.get())==0)
return mTasks[i].get();
}
@ -116,18 +116,12 @@ TaskProfile* Profiler::GetTaskProfileByDescription(const char* description)
///Task Profile
TaskProfile::TaskProfile()
{
mFileName = NULL;
mCumTime=0;
mNumHits=0;
}
TaskProfile::~TaskProfile()
{
if(mFileName)
{
delete [] mFileName;
delete [] mDescription;
}
}
///start the task timer.
@ -135,10 +129,10 @@ void TaskProfile::Begin(const char* fileName, int lineNum, const char* taskDescr
{
if(!mFileName)
{
mFileName = new char[strlen(fileName)+1];
strcpy(mFileName,fileName);
mDescription = new char[strlen(taskDescription)+1];
strcpy(mDescription,taskDescription);
mFileName.reinit( strlen(fileName) + 1 );
strcpy(mFileName.get(), fileName);
mDescription.reinit( strlen(taskDescription) + 1 );
strcpy(mDescription.get(), taskDescription);
mLine = lineNum;
}

View File

@ -79,9 +79,9 @@ class Profiler
double ComputeAverageRunTime();
char* mFileName;
ArrayOf<char> mFileName;
int mLine;
char* mDescription;
ArrayOf<char> mDescription;
int mNumHits;
clock_t mCumTime;
clock_t mLastTime;

View File

@ -383,19 +383,17 @@ public:
Size dataSize = 0;
GetFlavorDataSize((DragReference)m_currentDrag, theItem, theType, &dataSize);
Ptr theData = new char[dataSize];
GetFlavorData((DragReference)m_currentDrag, theItem, theType, (void*) theData, &dataSize, 0L);
ArrayOf<char> theData{ dataSize };
GetFlavorData((DragReference)m_currentDrag, theItem, theType, (void*) theData.get(), &dataSize, 0L);
wxString name;
if (theType == kDragPromisedFlavorFindFile) {
name = wxMacFSSpec2MacFilename((FSSpec *)theData);
name = wxMacFSSpec2MacFilename((FSSpec *)theData.get());
}
else if (theType == kDragFlavorTypeHFS) {
name = wxMacFSSpec2MacFilename(&((HFSFlavor *)theData)->fileSpec);
name = wxMacFSSpec2MacFilename(&((HFSFlavor *)theData.get())->fileSpec);
}
delete[] theData;
if (!firstFileAdded) {
// reset file list
((wxFileDataObject*)GetDataObject())->SetData(0, "");

View File

@ -94,9 +94,9 @@ void TableUsage(int iMask)
SinCosTable::SinCosTable() :
mSinCosTablePow(13)
{
int tableSize=1<<mSinCosTablePow;
mSinCosTable=new SinCosStruct[tableSize];
for(int i=0;i<tableSize;i++) {
size_t tableSize=1<<mSinCosTablePow;
mSinCosTable.reinit(tableSize);
for(size_t i=0;i<tableSize;i++) {
mSinCosTable[i].mSin=(float)-sin(((float)i)*M_PI/tableSize);
mSinCosTable[i].mCos=(float)-cos(((float)i)*M_PI/tableSize);
}

View File

@ -1,6 +1,8 @@
#ifndef __realfftf48x_h
#define __realfftf48x_h
#include "MemoryX.h"
#define fft_type float
int SmallRB(int bits, int numberBits);
@ -87,9 +89,8 @@ typedef struct {
class SinCosTable {
public:
int mSinCosTablePow;
SinCosStruct *mSinCosTable;
ArrayOf<SinCosStruct> mSinCosTable;
SinCosTable();
~SinCosTable(){ delete [] mSinCosTable; };
};
int SmallRB(int bits, int numberBits);

View File

@ -1308,7 +1308,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
// ... unless the mNumSamples ceiling applies, and then there are other defenses
const auto s1 =
std::min(mNumSamples, std::max(1 + where[len - 1], where[len]));
float *temp = new float[mMaxSamples];
Floats temp{ mMaxSamples };
decltype(len) pixel = 0;
@ -1400,13 +1400,13 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
default:
case 1:
// Read samples
Read((samplePtr)temp, floatSample, seqBlock, startPosition, num);
Read((samplePtr)temp.get(), floatSample, seqBlock, startPosition, num);
break;
case 256:
// Read triples
//check to see if summary data has been computed
if (seqBlock.f->IsSummaryAvailable())
seqBlock.f->Read256(temp, startPosition, num);
seqBlock.f->Read256(temp.get(), startPosition, num);
else
//otherwise, mark the display as not yet computed
blockStatus = -1 - b;
@ -1415,7 +1415,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
// Read triples
//check to see if summary data has been computed
if (seqBlock.f->IsSummaryAvailable())
seqBlock.f->Read64K(temp, startPosition, num);
seqBlock.f->Read64K(temp.get(), startPosition, num);
else
//otherwise, mark the display as not yet computed
blockStatus = -1 - b;
@ -1431,7 +1431,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
auto midPosition = ((whereNow - start) / divisor).as_size_t();
int diff(midPosition - filePosition);
if (diff > 0) {
MinMaxSumsq values(temp, diff, divisor);
MinMaxSumsq values(temp.get(), diff, divisor);
const int lastPixel = pixel - 1;
float &lastMin = min[lastPixel];
lastMin = std::min(lastMin, values.min);
@ -1471,7 +1471,7 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
rmsDenom = (positionX - filePosition);
wxASSERT(rmsDenom > 0);
const float *const pv =
temp + (filePosition - startPosition) * (divisor == 1 ? 1 : 3);
temp.get() + (filePosition - startPosition) * (divisor == 1 ? 1 : 3);
MinMaxSumsq values(pv, rmsDenom, divisor);
// Assign results
@ -1493,8 +1493,6 @@ bool Sequence::GetWaveDisplay(float *min, float *max, float *rms, int* bl,
wxASSERT(pixel == len);
delete[] temp;
return true;
}

View File

@ -291,10 +291,7 @@ bool SnapManager::SnapToPoints(Track *currentTrack,
return true;
}
// indexInThisTrack is ONLY used if count > 0
// and is initialised then, so we can 'initialise' it
// to anything to keep compiler quiet.
size_t indexInThisTrack = left;
size_t indexInThisTrack = 0;
size_t countInThisTrack = 0;
for (i = left; i <= right; ++i)
{

View File

@ -19,6 +19,7 @@
#include "FFT.h"
#include "Experimental.h"
#include "SampleFormat.h"
bool ComputeSpectrum(const float * data, size_t width,
size_t windowSize,
@ -31,15 +32,15 @@ bool ComputeSpectrum(const float * data, size_t width,
if (!data || !output)
return true;
float *processed = new float[windowSize];
Floats processed{ windowSize };
for (size_t i = 0; i < windowSize; i++)
processed[i] = float(0.0);
auto half = windowSize / 2;
float *in = new float[windowSize];
float *out = new float[windowSize];
float *out2 = new float[windowSize];
Floats in{ windowSize };
Floats out{ windowSize };
Floats out2{ windowSize };
size_t start = 0;
unsigned windows = 0;
@ -47,11 +48,11 @@ bool ComputeSpectrum(const float * data, size_t width,
for (size_t i = 0; i < windowSize; i++)
in[i] = data[start + i];
WindowFunc(windowFunc, windowSize, in);
WindowFunc(windowFunc, windowSize, in.get());
if (autocorrelation) {
// Take FFT
RealFFT(windowSize, in, out, out2);
RealFFT(windowSize, in.get(), out.get(), out2.get());
// Compute power
for (size_t i = 0; i < windowSize; i++)
in[i] = (out[i] * out[i]) + (out2[i] * out2[i]);
@ -63,10 +64,10 @@ bool ComputeSpectrum(const float * data, size_t width,
in[i] = powf(in[i], 1.0f / 3.0f);
// Take FFT
RealFFT(windowSize, in, out, out2);
RealFFT(windowSize, in.get(), out.get(), out2.get());
}
else
PowerSpectrum(windowSize, in, out);
PowerSpectrum(windowSize, in.get(), out.get());
// Take real part of result
for (size_t i = 0; i < half; i++)
@ -120,10 +121,6 @@ bool ComputeSpectrum(const float * data, size_t width,
for(size_t i = 0; i < half; i++)
output[i] = processed[i];
delete[]in;
delete[]out;
delete[]out2;
delete[]processed;
return true;
}

View File

@ -251,8 +251,8 @@ void TimeTrack::Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo) cons
mRuler->SetFlip(GetHeight() > 75 ? true : true); // MB: so why don't we just call Invalidate()? :)
mRuler->Draw(dc, this);
double *envValues = new double[mid.width];
GetEnvelope()->GetValues(envValues, mid.width, 0, zoomInfo);
Doubles envValues{ size_t(mid.width) };
GetEnvelope()->GetValues(envValues.get(), mid.width, 0, zoomInfo);
dc.SetPen(AColor::envelopePen);
@ -267,9 +267,6 @@ void TimeTrack::Draw(wxDC & dc, const wxRect & r, const ZoomInfo &zoomInfo) cons
int thisy = r.y + (int)y;
AColor::Line(dc, mid.x + x, thisy - 1, mid.x + x, thisy+2);
}
if (envValues)
delete[]envValues;
}
void TimeTrack::testMe()

View File

@ -1159,13 +1159,13 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[
int lasth2 = std::numeric_limits<int>::min();
int h1;
int h2;
int *r1 = new int[rect.width];
int *r2 = new int[rect.width];
int *clipped = NULL;
ArrayOf<int> r1{ size_t(rect.width) };
ArrayOf<int> r2{ size_t(rect.width) };
ArrayOf<int> clipped;
int clipcnt = 0;
if (mShowClipping) {
clipped = new int[rect.width];
clipped.reinit( size_t(rect.width) );
}
long pixAnimOffset = (long)fabs((double)(wxDateTime::Now().GetTicks() * -10)) +
@ -1296,13 +1296,6 @@ void TrackArtist::DrawMinMaxRMS(wxDC &dc, const wxRect & rect, const double env[
AColor::Line(dc, xx, rect.y, xx, rect.y + rect.height);
}
}
if (mShowClipping) {
delete[] clipped;
}
delete [] r1;
delete [] r2;
}
void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &rect,
@ -1330,16 +1323,16 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &
if (slen <= 0)
return;
float *buffer = new float[slen];
clip->GetSamples((samplePtr)buffer, floatSample, s0, slen);
Floats buffer{ size_t(slen) };
clip->GetSamples((samplePtr)buffer.get(), floatSample, s0, slen);
int *xpos = new int[slen];
int *ypos = new int[slen];
int *clipped = NULL;
ArrayOf<int> xpos{ size_t(slen) };
ArrayOf<int> ypos{ size_t(slen) };
ArrayOf<int> clipped;
int clipcnt = 0;
if (mShowClipping)
clipped = new int[slen];
clipped.reinit( size_t(slen) );
dc.SetPen(muted ? muteSamplePen : samplePen);
@ -1394,14 +1387,6 @@ void TrackArtist::DrawIndividualSamples(wxDC &dc, int leftOffset, const wxRect &
AColor::Line(dc, rect.x + s, rect.y, rect.x + s, rect.y + rect.height);
}
}
if (mShowClipping) {
delete [] clipped;
}
delete[]buffer;
delete[]xpos;
delete[]ypos;
}
void TrackArtist::DrawEnvelope(wxDC &dc, const wxRect &rect, const double env[],
@ -2216,8 +2201,7 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
scale2 = (lmax - lmin) / log2,
lmin2 = lmin / log2;
bool *yGrid;
yGrid = new bool[mid.height];
ArrayOf<bool> yGrid{size_t(mid.height)};
for (int yy = 0; yy < mid.height; ++yy) {
float n = (float(yy) / mid.height*scale2 - lmin2) * 12;
float n2 = (float(yy + 1) / mid.height*scale2 - lmin2) * 12;
@ -2286,8 +2270,8 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
i0 = expf(lmin) / binUnit,
i1 = expf(scale + lmin) / binUnit,
minColor = 0.0f;
const int maxTableSize = 1024;
int *indexes = new int[maxTableSize];
const size_t maxTableSize = 1024;
ArrayOf<int> indexes{ maxTableSize };
#endif //EXPERIMENTAL_FIND_NOTES
#ifdef _OPENMP
@ -2525,10 +2509,6 @@ void TrackArtist::DrawClipSpectrum(WaveTrackCache &waveTrackCache,
memDC.SelectObject(converted);
dc.Blit(mid.x, mid.y, mid.width, mid.height, &memDC, 0, 0, wxCOPY, FALSE);
#ifdef EXPERIMENTAL_FFT_Y_GRID
delete[] yGrid;
#endif //EXPERIMENTAL_FFT_Y_GRID
}
#ifdef USE_MIDI

View File

@ -4553,20 +4553,18 @@ void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event )
// SMOOTHING_PROPORTION_MAX and at the far bounds is SMOOTHING_PROPORTION_MIN
//Get the region of samples around the selected point
int sampleRegionSize = 1 + 2 * (SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS);
float *sampleRegion = new float[sampleRegionSize];
float * newSampleRegion = new float[1 + 2 * SMOOTHING_BRUSH_RADIUS];
size_t sampleRegionSize = 1 + 2 * (SMOOTHING_KERNEL_RADIUS + SMOOTHING_BRUSH_RADIUS);
Floats sampleRegion{ sampleRegionSize };
Floats newSampleRegion{ 1 + 2 * (size_t)SMOOTHING_BRUSH_RADIUS };
//Get a sample from the track to do some tricks on.
mDrawingTrack->Get((samplePtr)sampleRegion, floatSample,
mDrawingTrack->Get((samplePtr)sampleRegion.get(), floatSample,
mDrawingStartSample - SMOOTHING_KERNEL_RADIUS - SMOOTHING_BRUSH_RADIUS,
sampleRegionSize);
int i, j;
//Go through each point of the smoothing brush and apply a smoothing operation.
for(j = -SMOOTHING_BRUSH_RADIUS; j <= SMOOTHING_BRUSH_RADIUS; j++){
for(auto j = -SMOOTHING_BRUSH_RADIUS; j <= SMOOTHING_BRUSH_RADIUS; j++){
float sumOfSamples = 0;
for (i= -SMOOTHING_KERNEL_RADIUS; i <= SMOOTHING_KERNEL_RADIUS; i++){
for (auto i = -SMOOTHING_KERNEL_RADIUS; i <= SMOOTHING_KERNEL_RADIUS; i++){
//Go through each point of the smoothing kernel and find the average
//The average is a weighted average, scaled by a weighting kernel that is simply triangular
@ -4591,7 +4589,7 @@ void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event )
float prob;
for(j=-SMOOTHING_BRUSH_RADIUS; j <= SMOOTHING_BRUSH_RADIUS; j++){
for(auto j = -SMOOTHING_BRUSH_RADIUS; j <= SMOOTHING_BRUSH_RADIUS; j++){
prob = SMOOTHING_PROPORTION_MAX - (float)abs(j)/SMOOTHING_BRUSH_RADIUS * (SMOOTHING_PROPORTION_MAX - SMOOTHING_PROPORTION_MIN);
@ -4600,11 +4598,7 @@ void TrackPanel::HandleSampleEditingClick( wxMouseEvent & event )
sampleRegion[SMOOTHING_BRUSH_RADIUS + SMOOTHING_KERNEL_RADIUS + j] * (1 - prob);
}
//Set the sample to the point of the mouse event
mDrawingTrack->Set((samplePtr)newSampleRegion, floatSample, mDrawingStartSample - SMOOTHING_BRUSH_RADIUS, 1 + 2 * SMOOTHING_BRUSH_RADIUS);
//Clean this up right away to avoid a memory leak
delete[] sampleRegion;
delete[] newSampleRegion;
mDrawingTrack->Set((samplePtr)newSampleRegion.get(), floatSample, mDrawingStartSample - SMOOTHING_BRUSH_RADIUS, 1 + 2 * SMOOTHING_BRUSH_RADIUS);
mDrawingLastDragSampleValue = 0;
}

View File

@ -149,8 +149,9 @@ sampleCount VoiceKey::OnForward (
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
//Only go through the first SignalWindowSizeInt samples, and choose the first that trips the key.
float *buffer = new float[remaining];
t.Get((samplePtr)buffer, floatSample, lastsubthresholdsample, remaining);
Floats buffer{ remaining };
t.Get((samplePtr)buffer.get(), floatSample,
lastsubthresholdsample, remaining);
@ -226,7 +227,6 @@ sampleCount VoiceKey::OnForward (
}
//When we get here, i+lastsubthresholdsample is the best guess for where the word starts
delete [] buffer;
return i + lastsubthresholdsample;
}
else {
@ -299,8 +299,9 @@ sampleCount VoiceKey::OnBackward (
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
//Only go through the first mSilentWindowSizeInt samples, and choose the first that trips the key.
float *buffer = new float[remaining];
t.Get((samplePtr)buffer, floatSample, lastsubthresholdsample-remaining, remaining);
Floats buffer{ remaining };
t.Get((samplePtr)buffer.get(), floatSample,
lastsubthresholdsample - remaining, remaining);
//Initialize these trend markers atrend and ztrend. They keep track of the
//up/down trends at the start and end of the evaluation window.
@ -364,7 +365,6 @@ sampleCount VoiceKey::OnBackward (
}
//When we get here, i+lastsubthresholdsample is the best guess for where the word starts
delete [] buffer;
return lastsubthresholdsample - remaining + i;
}
else {
@ -435,8 +435,9 @@ sampleCount VoiceKey::OffForward (
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
//Only go through the first SilentWindowSizeInt samples, and choose the first that trips the key.
float *buffer = new float[remaining];
t.Get((samplePtr)buffer, floatSample, lastsubthresholdsample, remaining);
Floats buffer{ remaining };
t.Get((samplePtr)buffer.get(), floatSample,
lastsubthresholdsample, remaining);
//Initialize these trend markers atrend and ztrend. They keep track of the
//up/down trends at the start and end of the evaluation window.
@ -500,7 +501,6 @@ sampleCount VoiceKey::OffForward (
}
//When we get here, i+lastsubthresholdsample is the best guess for where the word starts
delete [] buffer;
return i + lastsubthresholdsample;
}
else {
@ -572,8 +572,8 @@ sampleCount VoiceKey::OffBackward (
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
//Only go through the first SilentWindowSizeInt samples, and choose the first that trips the key.
float *buffer = new float[remaining];
t.Get((samplePtr)buffer, floatSample,
Floats buffer{ remaining };
t.Get((samplePtr)buffer.get(), floatSample,
lastsubthresholdsample - remaining, remaining);
//Initialize these trend markers atrend and ztrend. They keep track of the
@ -641,7 +641,6 @@ sampleCount VoiceKey::OffBackward (
}
//When we get here, i+lastsubthresholdsample is the best guess for where the word starts
delete [] buffer;
return lastsubthresholdsample - remaining + i;
}
else {
@ -849,14 +848,14 @@ double VoiceKey::TestEnergy (
auto originalLen = len; //Keep track of the length of block to process (its not the length of t)
const auto blockSize = limitSampleBufferSize(
t.GetMaxBlockSize(), len); //Determine size of sampling buffer
float *buffer = new float[blockSize]; //Get a sampling buffer
Floats buffer{ blockSize }; //Get a sampling buffer
while(len > 0)
{
//Figure out how much to grab
auto block = limitSampleBufferSize ( t.GetBestBlockSize(s), len );
t.Get((samplePtr)buffer,floatSample, s,block); //grab the block;
t.Get((samplePtr)buffer.get(), floatSample, s,block); //grab the block;
//Now, go through the block and calculate energy
for(decltype(block) i = 0; i< block; i++)
@ -868,7 +867,6 @@ double VoiceKey::TestEnergy (
s += block;
}
delete [] buffer;
return sum / originalLen.as_double();
}
@ -894,13 +892,13 @@ double VoiceKey::TestSignChanges(
unsigned long signchanges = 1;
int currentsign=0;
float *buffer = new float[blockSize]; //Get a sampling buffer
Floats buffer{ blockSize }; //Get a sampling buffer
while(len > 0) {
//Figure out how much to grab
auto block = limitSampleBufferSize ( t.GetBestBlockSize(s), len );
t.Get((samplePtr)buffer,floatSample, s,block); //grab the block;
t.Get((samplePtr)buffer.get(), floatSample, s, block); //grab the block;
if (len == originalLen)
{
@ -922,7 +920,6 @@ double VoiceKey::TestSignChanges(
len -= block;
s += block;
}
delete [] buffer;
return (double)signchanges / originalLen.as_double();
}
@ -952,13 +949,13 @@ double VoiceKey::TestDirectionChanges(
float lastval=float(0);
int lastdirection=1;
float *buffer = new float[blockSize]; //Get a sampling buffer
Floats buffer{ blockSize }; //Get a sampling buffer
while(len > 0) {
//Figure out how much to grab
auto block = limitSampleBufferSize ( t.GetBestBlockSize(s), len );
t.Get((samplePtr)buffer,floatSample, s,block); //grab the block;
t.Get((samplePtr)buffer.get(), floatSample, s, block); //grab the block;
if (len == originalLen) {
//The first time through, set stuff up special.
@ -980,7 +977,6 @@ double VoiceKey::TestDirectionChanges(
len -= block;
s += block;
}
delete [] buffer;
return (double)directionchanges/originalLen.as_double();
}

View File

@ -691,29 +691,31 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
//wxCriticalSectionLocker locker(mAppendCriticalSection);
if (right > left) {
float *b;
Floats b;
float *pb{};
// left is nonnegative and at most mAppendBufferLen:
auto sLeft = left.as_size_t();
// The difference is at most mAppendBufferLen:
size_t len = ( right - left ).as_size_t();
if (seqFormat == floatSample)
b = &((float *)mAppendBuffer.ptr())[sLeft];
pb = &((float *)mAppendBuffer.ptr())[sLeft];
else {
b = new float[len];
b.reinit(len);
pb = b.get();
CopySamples(mAppendBuffer.ptr() + sLeft * SAMPLE_SIZE(seqFormat),
seqFormat,
(samplePtr)b, floatSample, len);
(samplePtr)pb, floatSample, len);
}
float theMax, theMin, sumsq;
{
const float val = b[0];
const float val = pb[0];
theMax = theMin = val;
sumsq = val * val;
}
for(decltype(len) j = 1; j < len; j++) {
const float val = b[j];
const float val = pb[j];
theMax = std::max(theMax, val);
theMin = std::min(theMin, val);
sumsq += val * val;
@ -724,9 +726,6 @@ bool WaveClip::GetWaveDisplay(WaveDisplay &display, double t0,
rms[i] = (float)sqrt(sumsq / len);
bl[i] = 1; //for now just fake it.
if (seqFormat != floatSample)
delete[] b;
didUpdate=true;
}
}
@ -934,21 +933,21 @@ bool SpecCache::CalculateOneSpectrum
std::copy(scratch, scratch2, scratch3);
{
const float *const window = settings.window;
const float *const window = settings.window.get();
for (size_t ii = 0; ii < fftLen; ++ii)
scratch[ii] *= window[ii];
RealFFTf(scratch, hFFT);
}
{
const float *const dWindow = settings.dWindow;
const float *const dWindow = settings.dWindow.get();
for (size_t ii = 0; ii < fftLen; ++ii)
scratch2[ii] *= dWindow[ii];
RealFFTf(scratch2, hFFT);
}
{
const float *const tWindow = settings.tWindow;
const float *const tWindow = settings.tWindow.get();
for (size_t ii = 0; ii < fftLen; ++ii)
scratch3[ii] *= tWindow[ii];
RealFFTf(scratch3, hFFT);
@ -1025,7 +1024,7 @@ bool SpecCache::CalculateOneSpectrum
// This function mutates useBuffer
ComputeSpectrumUsingRealFFTf
(useBuffer, settings.hFFT, settings.window, fftLen, results);
(useBuffer, settings.hFFT, settings.window.get(), fftLen, results);
if (!gainFactors.empty()) {
// Apply a frequency-dependant gain factor
for (size_t ii = 0; ii < nBins; ++ii)
@ -1825,9 +1824,9 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
double factor = (double)rate / (double)mRate;
::Resample resample(true, factor, factor); // constant rate resampling
size_t bufsize = 65536;
float* inBuffer = new float[bufsize];
float* outBuffer = new float[bufsize];
const size_t bufsize = 65536;
Floats inBuffer{ bufsize };
Floats outBuffer{ bufsize };
sampleCount pos = 0;
bool error = false;
int outGenerated = 0;
@ -1847,14 +1846,14 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
bool isLast = ((pos + inLen) == numSamples);
if (!mSequence->Get((samplePtr)inBuffer, floatSample, pos, inLen))
if (!mSequence->Get((samplePtr)inBuffer.get(), floatSample, pos, inLen))
{
error = true;
break;
}
const auto results = resample.Process(factor, inBuffer, inLen, isLast,
outBuffer, bufsize);
const auto results = resample.Process(factor, inBuffer.get(), inLen, isLast,
outBuffer.get(), bufsize);
outGenerated = results.second;
pos += results.first;
@ -1865,7 +1864,7 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
break;
}
if (!newSequence->Append((samplePtr)outBuffer, floatSample,
if (!newSequence->Append((samplePtr)outBuffer.get(), floatSample,
outGenerated))
{
error = true;
@ -1886,9 +1885,6 @@ bool WaveClip::Resample(int rate, ProgressDialog *progress)
}
}
delete[] inBuffer;
delete[] outBuffer;
if (!error)
{
mSequence = std::move(newSequence);

View File

@ -118,22 +118,17 @@ public:
class SpecPxCache {
public:
SpecPxCache(size_t cacheLen)
: len{ cacheLen }
, values{ len }
{
len = cacheLen;
values = new float[len];
valid = false;
scaleType = 0;
range = gain = -1;
minFreq = maxFreq = -1;
}
~SpecPxCache()
{
delete[] values;
}
size_t len;
float *values;
Floats values;
bool valid;
int scaleType;

View File

@ -1425,8 +1425,8 @@ bool WaveTrack::InsertSilence(double t, double len)
bool WaveTrack::Disjoin(double t0, double t1)
{
auto minSamples = TimeToLongSamples( WAVETRACK_MERGE_POINT_TOLERANCE );
size_t maxAtOnce = 1048576;
float *buffer = new float[ maxAtOnce ];
const size_t maxAtOnce = 1048576;
Floats buffer{ maxAtOnce };
Regions regions;
wxBusyCursor busy;
@ -1457,7 +1457,7 @@ bool WaveTrack::Disjoin(double t0, double t1)
{
auto numSamples = limitSampleBufferSize( maxAtOnce, len - done );
clip->GetSamples( ( samplePtr )buffer, floatSample, start + done,
clip->GetSamples( ( samplePtr )buffer.get(), floatSample, start + done,
numSamples );
for( decltype(numSamples) i = 0; i < numSamples; i++ )
{
@ -1498,7 +1498,6 @@ bool WaveTrack::Disjoin(double t0, double t1)
SplitDelete(region.start, region.end );
}
delete[] buffer;
return true;
}
@ -2609,7 +2608,6 @@ void WaveTrack::SetAutoSaveIdent(int ident)
WaveTrackCache::~WaveTrackCache()
{
Free();
}
void WaveTrackCache::SetTrack(const WaveTrack *pTrack)
@ -2620,8 +2618,8 @@ void WaveTrackCache::SetTrack(const WaveTrack *pTrack)
if (!mPTrack ||
mPTrack->GetMaxBlockSize() != mBufferSize) {
Free();
mBuffers[0].data = new float[mBufferSize];
mBuffers[1].data = new float[mBufferSize];
mBuffers[0].data = Floats{ mBufferSize };
mBuffers[1].data = Floats{ mBufferSize };
}
}
else
@ -2682,7 +2680,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
if (start0 >= 0) {
const auto len0 = mPTrack->GetBestBlockSize(start0);
wxASSERT(len0 <= mBufferSize);
if (!mPTrack->Get(samplePtr(mBuffers[0].data), floatSample, start0, len0))
if (!mPTrack->Get(samplePtr(mBuffers[0].data.get()), floatSample, start0, len0))
return 0;
mBuffers[0].start = start0;
mBuffers[0].len = len0;
@ -2708,7 +2706,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
if (start1 == end0) {
const auto len1 = mPTrack->GetBestBlockSize(start1);
wxASSERT(len1 <= mBufferSize);
if (!mPTrack->Get(samplePtr(mBuffers[1].data), floatSample, start1, len1))
if (!mPTrack->Get(samplePtr(mBuffers[1].data.get()), floatSample, start1, len1))
return 0;
mBuffers[1].start = start1;
mBuffers[1].len = len1;
@ -2755,7 +2753,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
// All is contiguous already. We can completely avoid copying
// leni is nonnegative, therefore start falls within mBuffers[ii],
// so starti is bounded between 0 and buffer length
return samplePtr(mBuffers[ii].data + starti.as_size_t() );
return samplePtr(mBuffers[ii].data.get() + starti.as_size_t() );
}
else if (leni > 0) {
// leni is nonnegative, therefore start falls within mBuffers[ii]
@ -2767,7 +2765,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
// leni is positive and not more than remaining
const size_t size = sizeof(float) * leni.as_size_t();
// starti is less than mBuffers[ii].len and nonnegative
memcpy(buffer, mBuffers[ii].data + starti.as_size_t(), size);
memcpy(buffer, mBuffers[ii].data.get() + starti.as_size_t(), size);
wxASSERT( leni <= remaining );
remaining -= leni.as_size_t();
start += leni;

View File

@ -622,7 +622,15 @@ class AUDACITY_DLL_API WaveTrack final : public Track {
// one block file).
class WaveTrackCache {
public:
explicit WaveTrackCache(const WaveTrack *pTrack = 0)
WaveTrackCache()
: mPTrack(0)
, mBufferSize(0)
, mOverlapBuffer()
, mNValidBuffers(0)
{
}
explicit WaveTrackCache(const WaveTrack *pTrack)
: mPTrack(0)
, mBufferSize(0)
, mOverlapBuffer()
@ -645,17 +653,17 @@ private:
void Free();
struct Buffer {
float *data;
Floats data;
sampleCount start;
sampleCount len;
Buffer() : data(0), start(0), len(0) {}
void Free() { delete[] data; data = 0; start = 0; len = 0; }
Buffer() : start(0), len(0) {}
void Free() { data.reset(); start = 0; len = 0; }
sampleCount end() const { return start + len; }
void swap ( Buffer &other )
{
std::swap( data, other.data );
data .swap ( other.data );
std::swap( start, other.start );
std::swap( len, other.len );
}

View File

@ -68,7 +68,7 @@ void ComputeLegacySummaryInfo(const wxFileName &fileName,
// 64K summary data
//
float *summary = new float[info->frames64K * fields];
Floats summary{ info->frames64K * fields };
SampleBuffer data(info->frames64K * fields,
info->format);
@ -100,7 +100,7 @@ void ComputeLegacySummaryInfo(const wxFileName &fileName,
int count = read / info->bytesPerFrame;
CopySamples(data.ptr(), info->format,
(samplePtr)summary, floatSample, count);
(samplePtr)summary.get(), floatSample, count);
(*min) = FLT_MAX;
(*max) = FLT_MIN;
@ -118,8 +118,6 @@ void ComputeLegacySummaryInfo(const wxFileName &fileName,
(*rms) = sqrt(sumsq / count);
else
(*rms) = 0;
delete[] summary;
}
/// Construct a LegacyBlockFile memory structure that will point to an

View File

@ -369,9 +369,8 @@ void ODDecodeBlockFile::SetFileName(wxFileNameWrapper &&name)
mFileName=std::move(name);
/* mchinen oct 9 2009 don't think we need the char* but leaving it in for now just as a reminder that we might
if wxFileName isn't threadsafe.
delete [] mFileNameChar;
mFileNameChar = new char[strlen(mFileName.GetFullPath().mb_str(wxConvUTF8))+1];
strcpy(mFileNameChar,mFileName.GetFullPath().mb_str(wxConvUTF8)); */
mFileNameChar.reinit(strlen(mFileName.GetFullPath().mb_str(wxConvUTF8))+1);
strcpy(mFileNameChar.get(), mFileName.GetFullPath().mb_str(wxConvUTF8)); */
mFileNameMutex.Unlock();
}
@ -409,6 +408,7 @@ void *ODDecodeBlockFile::CalcSummary(samplePtr buffer, size_t len,
float *summary64K = (float *)(localFullSummary + mSummaryInfo.offset64K);
float *summary256 = (float *)(localFullSummary + mSummaryInfo.offset256);
Floats floats;
float *fbuffer;
//mchinen: think we can hack this - don't allocate and copy if we don't need to.,
@ -418,18 +418,14 @@ void *ODDecodeBlockFile::CalcSummary(samplePtr buffer, size_t len,
}
else
{
fbuffer = new float[len];
floats.reinit(len);
fbuffer = floats.get();
CopySamples(buffer, format,
(samplePtr)fbuffer, floatSample, len);
}
BlockFile::CalcSummaryFromBuffer(fbuffer, len, summary256, summary64K);
//if we've used the float sample..
if(format!=floatSample)
{
delete[] fbuffer;
}
return localFullSummary;
}

View File

@ -379,24 +379,25 @@ void ODPCMAliasBlockFile::WriteSummary()
// wxFFile summaryFile(mFileName.GetFullPath(), wxT("wb"));
// ...and we use fopen instead.
FILE* summaryFile{};
wxString sFullPath = mFileName.GetFullPath();
char* fileNameChar = new char[strlen(sFullPath.mb_str(wxConvFile)) + 1];
strcpy(fileNameChar, sFullPath.mb_str(wxConvFile));
FILE* summaryFile = fopen(fileNameChar, "wb");
{
ArrayOf < char > fileNameChar{ strlen(sFullPath.mb_str(wxConvFile)) + 1 };
strcpy(fileNameChar.get(), sFullPath.mb_str(wxConvFile));
summaryFile = fopen(fileNameChar.get(), "wb");
mFileNameMutex.Unlock();
mFileNameMutex.Unlock();
// JKC ANSWER-ME: Whay is IsOpened() commented out?
if( !summaryFile){//.IsOpened() ){
// JKC ANSWER-ME: Whay is IsOpened() commented out?
if (!summaryFile){//.IsOpened() ){
// Never silence the Log w.r.t write errors; they always count
//however, this is going to be called from a non-main thread,
//and wxLog calls are not thread safe.
printf("Unable to write summary data to file: %s", fileNameChar);
delete [] fileNameChar;
return;
// Never silence the Log w.r.t write errors; they always count
//however, this is going to be called from a non-main thread,
//and wxLog calls are not thread safe.
printf("Unable to write summary data to file: %s", fileNameChar.get());
return;
}
}
delete [] fileNameChar;
// To build the summary data, call ReadData (implemented by the
// derived classes) to get the sample data
@ -449,6 +450,7 @@ void *ODPCMAliasBlockFile::CalcSummary(samplePtr buffer, size_t len,
float *summary64K = (float *)(localFullSummary + mSummaryInfo.offset64K);
float *summary256 = (float *)(localFullSummary + mSummaryInfo.offset256);
Floats floats;
float *fbuffer;
//mchinen: think we can hack this - don't allocate and copy if we don't need to.,
@ -458,18 +460,14 @@ void *ODPCMAliasBlockFile::CalcSummary(samplePtr buffer, size_t len,
}
else
{
fbuffer = new float[len];
floats.reinit(len);
fbuffer = floats.get();
CopySamples(buffer, format,
(samplePtr)fbuffer, floatSample, len);
}
BlockFile::CalcSummaryFromBuffer(fbuffer, len, summary256, summary64K);
//if we've used the float sample..
if(format!=floatSample)
{
delete[] fbuffer;
}
return localFullSummary;
}

View File

@ -124,13 +124,13 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName,
mCache.needWrite = true;
mCache.format = format;
const auto sampleDataSize = sampleLen * SAMPLE_SIZE(format);
mCache.sampleData = new char[sampleDataSize];
memcpy(mCache.sampleData, sampleData, sampleDataSize);
mCache.sampleData.reinit(sampleDataSize);
memcpy(mCache.sampleData.get(), sampleData, sampleDataSize);
ArrayOf<char> cleanup;
void* summaryData = BlockFile::CalcSummary(sampleData, sampleLen,
format, cleanup);
mCache.summaryData = new char[mSummaryInfo.totalSummaryBytes];
memcpy(mCache.summaryData, summaryData,
format, cleanup);
mCache.summaryData.reinit(mSummaryInfo.totalSummaryBytes);
memcpy(mCache.summaryData.get(), summaryData,
mSummaryInfo.totalSummaryBytes);
}
}
@ -155,11 +155,6 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&existingFile, size_t len,
SimpleBlockFile::~SimpleBlockFile()
{
if (mCache.active)
{
delete[] mCache.sampleData;
delete[] (char *)mCache.summaryData;
}
}
bool SimpleBlockFile::WriteSimpleBlockFile(
@ -317,18 +312,18 @@ void SimpleBlockFile::FillCache()
file.Close();
// Read samples into cache
mCache.sampleData = new char[mLen * SAMPLE_SIZE(mCache.format)];
if (ReadData(mCache.sampleData, mCache.format, 0, mLen) != mLen)
mCache.sampleData.reinit(mLen * SAMPLE_SIZE(mCache.format));
if (ReadData(mCache.sampleData.get(), mCache.format, 0, mLen) != mLen)
{
// Could not read all samples
delete mCache.sampleData;
mCache.sampleData.reset();
return;
}
// Read summary data into cache
mCache.summaryData = new char[mSummaryInfo.totalSummaryBytes];
if (!ReadSummary(mCache.summaryData))
memset(mCache.summaryData, 0, mSummaryInfo.totalSummaryBytes);
mCache.summaryData.reinit(mSummaryInfo.totalSummaryBytes);
if (!ReadSummary(mCache.summaryData.get()))
memset(mCache.summaryData.get(), 0, mSummaryInfo.totalSummaryBytes);
// Cache is active but already on disk
mCache.active = true;
@ -346,7 +341,7 @@ bool SimpleBlockFile::ReadSummary(void *data)
if (mCache.active)
{
//wxLogDebug("SimpleBlockFile::ReadSummary(): Summary is already in cache.");
memcpy(data, mCache.summaryData, mSummaryInfo.totalSummaryBytes);
memcpy(data, mCache.summaryData.get(), mSummaryInfo.totalSummaryBytes);
return true;
}
else
@ -398,7 +393,7 @@ size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format,
len = std::min(len, std::max(start, mLen) - start);
CopySamples(
(samplePtr)(((char*)mCache.sampleData) +
(samplePtr)(mCache.sampleData.get() +
start * SAMPLE_SIZE(mCache.format)),
mCache.format, data, format, len);
return len;
@ -540,7 +535,6 @@ auto SimpleBlockFile::GetSpaceUsage() const -> DiskByteCount
void SimpleBlockFile::Recover(){
wxFFile file(mFileName.GetFullPath(), wxT("wb"));
//int i;
if( !file.IsOpened() ){
// Can't do anything else.
@ -572,8 +566,8 @@ void SimpleBlockFile::WriteCacheToDisk()
if (!GetNeedWriteCacheToDisk())
return;
if (WriteSimpleBlockFile(mCache.sampleData, mLen, mCache.format,
mCache.summaryData))
if (WriteSimpleBlockFile(mCache.sampleData.get(), mLen, mCache.format,
mCache.summaryData.get()))
mCache.needWrite = false;
}

View File

@ -22,8 +22,9 @@ struct SimpleBlockFileCache {
bool active;
bool needWrite;
sampleFormat format;
samplePtr sampleData;
void* summaryData;
ArrayOf<char> sampleData, summaryData;
SimpleBlockFileCache() {}
};
// The AU formats we care about

View File

@ -99,8 +99,9 @@ bool CompareAudioCommand::Apply(CommandExecutionContext context)
// Initialize buffers for track data to be analyzed
auto buffSize = std::min(mTrack0->GetMaxBlockSize(), mTrack1->GetMaxBlockSize());
float *buff0 = new float[buffSize];
float *buff1 = new float[buffSize];
Floats buff0{ buffSize };
Floats buff1{ buffSize };
// Compare tracks block by block
auto s0 = mTrack0->TimeToLongSamples(mT0);
@ -113,8 +114,8 @@ bool CompareAudioCommand::Apply(CommandExecutionContext context)
auto block = limitSampleBufferSize(
mTrack0->GetBestBlockSize(position), s1 - position
);
mTrack0->Get((samplePtr)buff0, floatSample, position, block);
mTrack1->Get((samplePtr)buff1, floatSample, position, block);
mTrack0->Get((samplePtr)buff0.get(), floatSample, position, block);
mTrack1->Get((samplePtr)buff1.get(), floatSample, position, block);
for (decltype(block) buffPos = 0; buffPos < block; ++buffPos)
{
@ -131,9 +132,6 @@ bool CompareAudioCommand::Apply(CommandExecutionContext context)
);
}
delete [] buff0;
delete [] buff1;
// Output the results
double errorSeconds = mTrack0->LongSamplesToTime(errorCount);
Status(wxString::Format(wxT("%li"), errorCount));

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

@ -114,11 +114,6 @@ Effect::Effect()
mNumAudioIn = 0;
mNumAudioOut = 0;
mInBuffer = NULL;
mOutBuffer = NULL;
mInBufPos = NULL;
mOutBufPos = NULL;
mBufferSize = 0;
mBlockSize = 0;
mNumChannels = 0;
@ -1290,8 +1285,8 @@ bool Effect::ProcessPass()
bool editClipCanMove;
gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove, true);
mInBuffer = NULL;
mOutBuffer = NULL;
mInBuffer.reset();
mOutBuffer.reset();
ChannelName map[3];
@ -1391,28 +1386,10 @@ bool Effect::ProcessPass()
// If the buffer size has changed, then (re)allocate the buffers
if (prevBufferSize != mBufferSize)
{
// Get rid of any previous buffers
if (mInBuffer)
{
for (size_t i = 0; i < mNumAudioIn; i++)
{
if (mInBuffer[i])
{
delete [] mInBuffer[i];
}
}
delete [] mInBuffer;
delete [] mInBufPos;
}
// Always create the number of input buffers the client expects even if we don't have
// the same number of channels.
mInBufPos = new float *[mNumAudioIn];
mInBuffer = new float *[mNumAudioIn];
for (size_t i = 0; i < mNumAudioIn; i++)
{
mInBuffer[i] = new float[mBufferSize];
}
mInBufPos.reinit( mNumAudioIn );
mInBuffer.reinit( mNumAudioIn, mBufferSize );
// We won't be using more than the first 2 buffers, so clear the rest (if any)
for (size_t i = 2; i < mNumAudioIn; i++)
@ -1423,42 +1400,24 @@ bool Effect::ProcessPass()
}
}
// Get rid of any previous buffers
if (mOutBuffer)
{
for (size_t i = 0; i < mNumAudioOut; i++)
{
if (mOutBuffer[i])
{
delete [] mOutBuffer[i];
}
}
delete [] mOutBuffer;
delete [] mOutBufPos;
}
// Always create the number of output buffers the client expects even if we don't have
// the same number of channels.
mOutBufPos = new float *[mNumAudioOut];
mOutBuffer = new float *[mNumAudioOut];
for (size_t i = 0; i < mNumAudioOut; i++)
{
// Output buffers get an extra mBlockSize worth to give extra room if
// the plugin adds latency
mOutBuffer[i] = new float[mBufferSize + mBlockSize];
}
mOutBufPos.reinit( mNumAudioOut );
// Output buffers get an extra mBlockSize worth to give extra room if
// the plugin adds latency
mOutBuffer.reinit( mNumAudioOut, mBufferSize + mBlockSize );
}
// (Re)Set the input buffer positions
for (size_t i = 0; i < mNumAudioIn; i++)
{
mInBufPos[i] = mInBuffer[i];
mInBufPos[i] = mInBuffer[i].get();
}
// (Re)Set the output buffer positions
for (size_t i = 0; i < mNumAudioOut; i++)
{
mOutBufPos[i] = mOutBuffer[i];
mOutBufPos[i] = mOutBuffer[i].get();
}
// Clear unused input buffers
@ -1481,29 +1440,10 @@ bool Effect::ProcessPass()
count++;
}
if (mOutBuffer)
{
for (size_t i = 0; i < mNumAudioOut; i++)
{
delete [] mOutBuffer[i];
}
delete [] mOutBuffer;
delete [] mOutBufPos;
mOutBuffer = NULL;
mOutBufPos = NULL;
}
if (mInBuffer)
{
for (size_t i = 0; i < mNumAudioIn; i++)
{
delete [] mInBuffer[i];
}
delete [] mInBuffer;
delete [] mInBufPos;
mInBuffer = NULL;
mInBufPos = NULL;
}
mOutBuffer.reset();
mOutBufPos.reset();
mInBuffer.reset();
mInBufPos.reset();
if (bGoodResult && GetType() == EffectTypeGenerate)
{
@ -1598,16 +1538,16 @@ bool Effect::ProcessTrack(int count,
limitSampleBufferSize( mBufferSize, inputRemaining );
// Fill the input buffers
left->Get((samplePtr) mInBuffer[0], floatSample, inLeftPos, inputBufferCnt);
left->Get((samplePtr) mInBuffer[0].get(), floatSample, inLeftPos, inputBufferCnt);
if (right)
{
right->Get((samplePtr) mInBuffer[1], floatSample, inRightPos, inputBufferCnt);
right->Get((samplePtr) mInBuffer[1].get(), floatSample, inRightPos, inputBufferCnt);
}
// Reset the input buffer positions
for (size_t i = 0; i < mNumChannels; i++)
{
mInBufPos[i] = mInBuffer[i];
mInBufPos[i] = mInBuffer[i].get();
}
}
@ -1654,7 +1594,7 @@ bool Effect::ProcessTrack(int count,
// Reset the input buffer positions
for (size_t i = 0; i < mNumChannels; i++)
{
mInBufPos[i] = mInBuffer[i];
mInBufPos[i] = mInBuffer[i].get();
// And clear
for (size_t j = 0; j < mBlockSize; j++)
@ -1670,7 +1610,7 @@ bool Effect::ProcessTrack(int count,
decltype(curBlockSize) processed;
try
{
processed = ProcessBlock(mInBufPos, mOutBufPos, curBlockSize);
processed = ProcessBlock(mInBufPos.get(), mOutBufPos.get(), curBlockSize);
}
catch(...)
{
@ -1745,32 +1685,32 @@ bool Effect::ProcessTrack(int count,
if (isProcessor)
{
// Write them out
left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt);
left->Set((samplePtr) mOutBuffer[0].get(), floatSample, outLeftPos, outputBufferCnt);
if (right)
{
if (chans >= 2)
{
right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt);
right->Set((samplePtr) mOutBuffer[1].get(), floatSample, outRightPos, outputBufferCnt);
}
else
{
right->Set((samplePtr) mOutBuffer[0], floatSample, outRightPos, outputBufferCnt);
right->Set((samplePtr) mOutBuffer[0].get(), floatSample, outRightPos, outputBufferCnt);
}
}
}
else if (isGenerator)
{
genLeft->Append((samplePtr) mOutBuffer[0], floatSample, outputBufferCnt);
genLeft->Append((samplePtr) mOutBuffer[0].get(), floatSample, outputBufferCnt);
if (genRight)
{
genRight->Append((samplePtr) mOutBuffer[1], floatSample, outputBufferCnt);
genRight->Append((samplePtr) mOutBuffer[1].get(), floatSample, outputBufferCnt);
}
}
// Reset the output buffer positions
for (size_t i = 0; i < chans; i++)
{
mOutBufPos[i] = mOutBuffer[i];
mOutBufPos[i] = mOutBuffer[i].get();
}
// Bump to the next track position
@ -1806,25 +1746,25 @@ bool Effect::ProcessTrack(int count,
{
if (isProcessor)
{
left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt);
left->Set((samplePtr) mOutBuffer[0].get(), floatSample, outLeftPos, outputBufferCnt);
if (right)
{
if (chans >= 2)
{
right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt);
right->Set((samplePtr) mOutBuffer[1].get(), floatSample, outRightPos, outputBufferCnt);
}
else
{
right->Set((samplePtr) mOutBuffer[0], floatSample, outRightPos, outputBufferCnt);
right->Set((samplePtr) mOutBuffer[0].get(), floatSample, outRightPos, outputBufferCnt);
}
}
}
else if (isGenerator)
{
genLeft->Append((samplePtr) mOutBuffer[0], floatSample, outputBufferCnt);
genLeft->Append((samplePtr) mOutBuffer[0].get(), floatSample, outputBufferCnt);
if (genRight)
{
genRight->Append((samplePtr) mOutBuffer[1], floatSample, outputBufferCnt);
genRight->Append((samplePtr) mOutBuffer[1].get(), floatSample, outputBufferCnt);
}
}
}

View File

@ -32,6 +32,7 @@ class wxWindow;
#include "audacity/EffectInterface.h"
#include "../Experimental.h"
#include "../SampleFormat.h"
#include "../SelectedRegion.h"
#include "../Shuttle.h"
#include "../Internat.h"
@ -504,10 +505,10 @@ private:
size_t mNumAudioIn;
size_t mNumAudioOut;
float **mInBuffer;
float **mOutBuffer;
float **mInBufPos;
float **mOutBufPos;
FloatBuffers mInBuffer, mOutBuffer;
using Positions = ArrayOf < float* > ; // Array of non-owning pointers into the above
Positions mInBufPos, mOutBufPos;
size_t mBufferSize;
size_t mBlockSize;

View File

@ -11,6 +11,7 @@
#include "../Audacity.h"
#include <algorithm>
#include <wx/msgdlg.h>
#include <wx/stopwatch.h>
#include <wx/tokenzr.h>
@ -397,6 +398,7 @@ void EffectManager::RealtimeSetEffects(const EffectArray & effects)
}
}
// Get rid of the old chain
// And install the NEW one
mRealtimeEffects = effects;
@ -407,7 +409,7 @@ void EffectManager::RealtimeSetEffects(const EffectArray & effects)
bool EffectManager::RealtimeIsActive()
{
return mRealtimeEffects.GetCount() != 0;
return mRealtimeEffects.size() != 0;
}
bool EffectManager::RealtimeIsSuspended()
@ -434,7 +436,7 @@ void EffectManager::RealtimeAddEffect(Effect *effect)
}
// Add to list of active effects
mRealtimeEffects.Add(effect);
mRealtimeEffects.push_back(effect);
// Allow RealtimeProcess() to, well, process
RealtimeResume();
@ -452,7 +454,10 @@ void EffectManager::RealtimeRemoveEffect(Effect *effect)
}
// Remove from list of active effects
mRealtimeEffects.Remove(effect);
auto end = mRealtimeEffects.end();
auto found = std::find(mRealtimeEffects.begin(), end, effect);
if (found != end)
mRealtimeEffects.erase(found);
// Allow RealtimeProcess() to, well, process
RealtimeResume();
@ -472,10 +477,8 @@ void EffectManager::RealtimeInitialize()
mRealtimeActive = true;
// Tell each effect to get ready for action
for (int i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
{
mRealtimeEffects[i]->RealtimeInitialize();
}
for (auto e : mRealtimeEffects)
e->RealtimeInitialize();
// Get things moving
RealtimeResume();
@ -483,10 +486,8 @@ void EffectManager::RealtimeInitialize()
void EffectManager::RealtimeAddProcessor(int group, unsigned chans, float rate)
{
for (size_t i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
{
mRealtimeEffects[i]->RealtimeAddProcessor(group, chans, rate);
}
for (auto e : mRealtimeEffects)
e->RealtimeAddProcessor(group, chans, rate);
mRealtimeChans.push_back(chans);
mRealtimeRates.Add(rate);
@ -501,10 +502,8 @@ void EffectManager::RealtimeFinalize()
mRealtimeLatency = 0;
// Tell each effect to clean up as well
for (int i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
{
mRealtimeEffects[i]->RealtimeFinalize();
}
for (auto e : mRealtimeEffects)
e->RealtimeFinalize();
// Reset processor parameters
mRealtimeChans.clear();
@ -529,10 +528,8 @@ void EffectManager::RealtimeSuspend()
mRealtimeSuspended = true;
// And make sure the effects don't either
for (int i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
{
mRealtimeEffects[i]->RealtimeSuspend();
}
for (auto e : mRealtimeEffects)
e->RealtimeSuspend();
mRealtimeLock.Leave();
}
@ -549,10 +546,8 @@ void EffectManager::RealtimeResume()
}
// Tell the effects to get ready for more action
for (int i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
{
mRealtimeEffects[i]->RealtimeResume();
}
for (auto e : mRealtimeEffects)
e->RealtimeResume();
// And we should too
mRealtimeSuspended = false;
@ -572,12 +567,10 @@ void EffectManager::RealtimeProcessStart()
// have been suspended.
if (!mRealtimeSuspended)
{
for (size_t i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
for (auto e : mRealtimeEffects)
{
if (mRealtimeEffects[i]->IsRealtimeActive())
{
mRealtimeEffects[i]->RealtimeProcessStart();
}
if (e->IsRealtimeActive())
e->RealtimeProcessStart();
}
}
@ -594,7 +587,7 @@ size_t EffectManager::RealtimeProcess(int group, unsigned chans, float **buffers
// Can be suspended because of the audio stream being paused or because effects
// have been suspended, so allow the samples to pass as-is.
if (mRealtimeSuspended || mRealtimeEffects.IsEmpty())
if (mRealtimeSuspended || mRealtimeEffects.empty())
{
mRealtimeLock.Leave();
return numSamples;
@ -619,11 +612,11 @@ size_t EffectManager::RealtimeProcess(int group, unsigned chans, float **buffers
// Now call each effect in the chain while swapping buffer pointers to feed the
// output of one effect as the input to the next effect
size_t called = 0;
for (size_t i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
for (auto e : mRealtimeEffects)
{
if (mRealtimeEffects[i]->IsRealtimeActive())
if (e->IsRealtimeActive())
{
mRealtimeEffects[i]->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
e->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
called++;
}
@ -671,12 +664,10 @@ void EffectManager::RealtimeProcessEnd()
// have been suspended.
if (!mRealtimeSuspended)
{
for (size_t i = 0, cnt = mRealtimeEffects.GetCount(); i < cnt; i++)
for (auto e : mRealtimeEffects)
{
if (mRealtimeEffects[i]->IsRealtimeActive())
{
mRealtimeEffects[i]->RealtimeProcessEnd();
}
if (e->IsRealtimeActive())
e->RealtimeProcessEnd();
}
}

View File

@ -23,6 +23,7 @@ effects.
#include "../Experimental.h"
#include <vector>
#include <wx/choice.h>
#include <wx/dialog.h>
#include <wx/event.h>
@ -33,7 +34,7 @@ effects.
#include "../PluginManager.h"
#include "Effect.h"
WX_DEFINE_USER_EXPORTED_ARRAY(Effect *, EffectArray, class AUDACITY_DLL_API);
using EffectArray = std::vector <Effect*> ;
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(Effect *, EffectMap, class AUDACITY_DLL_API);
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(std::shared_ptr<Effect>, EffectOwnerMap, class AUDACITY_DLL_API);

View File

@ -16,6 +16,7 @@
#if defined(EXPERIMENTAL_EFFECTS_RACK)
#include "../MemoryX.h"
#include <wx/access.h>
#include <wx/defs.h>
#include <wx/bmpbuttn.h>
@ -162,7 +163,7 @@ EffectRack::~EffectRack()
{
gPrefs->DeleteGroup(wxT("/EffectsRack"));
for (size_t i = 0, cnt = mEffects.GetCount(); i < cnt; i++)
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
{
if (mFavState[i])
{
@ -177,7 +178,7 @@ EffectRack::~EffectRack()
void EffectRack::Add(Effect *effect, bool active, bool favorite)
{
if (mEffects.Index(effect) != wxNOT_FOUND)
if (mEffects.end() != std::find(mEffects.begin(), mEffects.end(), effect))
{
return;
}
@ -254,7 +255,7 @@ void EffectRack::Add(Effect *effect, bool active, bool favorite)
Fit();
Update();
mEffects.Add(effect);
mEffects.push_back(effect);
mNumEffects++;
if (!mTimer.IsRunning())
@ -289,7 +290,7 @@ void EffectRack::OnApply(wxCommandEvent & WXUNUSED(evt))
{
AudacityProject *project = GetActiveProject();
for (size_t i = 0, cnt = mEffects.GetCount(); i < cnt; i++)
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
{
if (mPowerState[i])
{
@ -408,11 +409,11 @@ void EffectRack::OnRemove(wxCommandEvent & evt)
return;
}
mEffects.RemoveAt(index);
mEffects.erase(mEffects.begin() + index);
mPowerState.RemoveAt(index);
mFavState.RemoveAt(index);
if (mEffects.GetCount() == 0)
if (mEffects.size() == 0)
{
if (mTimer.IsRunning())
{
@ -489,8 +490,8 @@ int EffectRack::GetEffectIndex(wxWindow *win)
void EffectRack::MoveRowUp(int row)
{
Effect *effect = mEffects[row];
mEffects.RemoveAt(row);
mEffects.Insert(effect, row - 1);
mEffects.erase(mEffects.begin() + row);
mEffects.insert(mEffects.begin() + row - 1, effect);
int state = mPowerState[row];
mPowerState.RemoveAt(row);
@ -525,11 +526,11 @@ void EffectRack::UpdateActive()
if (!mBypassing)
{
for (size_t i = 0, cnt = mEffects.GetCount(); i < cnt; i++)
for (size_t i = 0, cnt = mEffects.size(); i < cnt; i++)
{
if (mPowerState[i])
{
mActive.Add(mEffects[i]);
mActive.push_back(mEffects[i]);
}
}
}

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

@ -121,16 +121,16 @@ bool BlockGenerator::GenerateTrack(WaveTrack *tmp,
bool bGoodResult = true;
numSamples = track.TimeToLongSamples(GetDuration());
decltype(numSamples) i = 0;
float *data = new float[tmp->GetMaxBlockSize()];
Floats data{ tmp->GetMaxBlockSize() };
while ((i < numSamples) && bGoodResult) {
const auto block =
limitSampleBufferSize( tmp->GetBestBlockSize(i), numSamples - i );
GenerateBlock(data, track, block);
GenerateBlock(data.get(), track, block);
// Add the generated data to the temporary track
tmp->Append((samplePtr)data, floatSample, block);
tmp->Append((samplePtr)data.get(), floatSample, block);
i += block;
// Update the progress meter
@ -139,6 +139,5 @@ bool BlockGenerator::GenerateTrack(WaveTrack *tmp,
numSamples.as_double()))
bGoodResult = false;
}
delete[] data;
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;

View File

@ -1108,10 +1108,6 @@ VSTEffect::VSTEffect(const wxString & path, VSTEffect *master)
// UI
mGui = false;
mNames = NULL;
mSliders = NULL;
mDisplays = NULL;
mLabels = NULL;
mContainer = NULL;
// If we're a slave then go ahead a load immediately
@ -1128,26 +1124,6 @@ VSTEffect::~VSTEffect()
mDialog->Close();
}
if (mNames)
{
delete [] mNames;
}
if (mSliders)
{
delete [] mSliders;
}
if (mDisplays)
{
delete [] mDisplays;
}
if (mLabels)
{
delete [] mLabels;
}
Unload();
}
@ -1289,7 +1265,9 @@ bool VSTEffect::SetHost(EffectHostInterface *host)
if (mHost)
{
mHost->GetSharedConfig(wxT("Options"), wxT("BufferSize"), mUserBlockSize, 8192);
int userBlockSize;
mHost->GetSharedConfig(wxT("Options"), wxT("BufferSize"), userBlockSize, 8192);
mUserBlockSize = std::max( 1, userBlockSize );
mHost->GetSharedConfig(wxT("Options"), wxT("UseLatency"), mUseLatency, true);
mBlockSize = mUserBlockSize;
@ -1330,7 +1308,7 @@ int VSTEffect::GetMidiOutCount()
size_t VSTEffect::SetBlockSize(size_t maxBlockSize)
{
mBlockSize = std::min((int)maxBlockSize, mUserBlockSize);
mBlockSize = std::min( maxBlockSize, mUserBlockSize );
return mBlockSize;
}
@ -1424,26 +1402,16 @@ void VSTEffect::SetChannelCount(unsigned numChannels)
bool VSTEffect::RealtimeInitialize()
{
mMasterIn = new float *[mAudioIns];
for (int i = 0; i < mAudioIns; i++)
{
mMasterIn[i] = new float[mBlockSize];
memset(mMasterIn[i], 0, mBlockSize * sizeof(float));
}
mMasterOut = new float *[mAudioOuts];
for (int i = 0; i < mAudioOuts; i++)
{
mMasterOut[i] = new float[mBlockSize];
}
mMasterIn.reinit( mAudioIns, mBlockSize, true );
mMasterOut.reinit( mAudioOuts, mBlockSize );
return ProcessInitialize(0, NULL);
}
bool VSTEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRate)
{
VSTEffect *slave = new VSTEffect(mPath, this);
mSlaves.Add(slave);
mSlaves.push_back(make_movable<VSTEffect>(mPath, this));
VSTEffect *const slave = mSlaves.back().get();
slave->SetBlockSize(mBlockSize);
slave->SetChannelCount(numChannels);
@ -1478,24 +1446,13 @@ bool VSTEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRate)
bool VSTEffect::RealtimeFinalize()
{
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->ProcessFinalize();
delete mSlaves[i];
}
mSlaves.Clear();
for (const auto &slave : mSlaves)
slave->ProcessFinalize();
mSlaves.clear();
for (int i = 0; i < mAudioIns; i++)
{
delete [] mMasterIn[i];
}
delete [] mMasterIn;
mMasterIn.reset();
for (int i = 0; i < mAudioOuts; i++)
{
delete [] mMasterOut[i];
}
delete [] mMasterOut;
mMasterOut.reset();
return ProcessFinalize();
}
@ -1504,10 +1461,8 @@ bool VSTEffect::RealtimeSuspend()
{
PowerOff();
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->PowerOff();
}
for (const auto &slave : mSlaves)
slave->PowerOff();
return true;
}
@ -1516,10 +1471,8 @@ bool VSTEffect::RealtimeResume()
{
PowerOn();
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->PowerOn();
}
for (const auto &slave : mSlaves)
slave->PowerOn();
return true;
}
@ -1527,9 +1480,7 @@ bool VSTEffect::RealtimeResume()
bool VSTEffect::RealtimeProcessStart()
{
for (int i = 0; i < mAudioIns; i++)
{
memset(mMasterIn[i], 0, mBlockSize * sizeof(float));
}
memset(mMasterIn[i].get(), 0, mBlockSize * sizeof(float));
mNumSamples = 0;
@ -1554,7 +1505,11 @@ size_t VSTEffect::RealtimeProcess(int group, float **inbuf, float **outbuf, size
bool VSTEffect::RealtimeProcessEnd()
{
ProcessBlock(mMasterIn, mMasterOut, mNumSamples);
// These casts to float** should be safe...
ProcessBlock(
reinterpret_cast <float**> (mMasterIn.get()),
reinterpret_cast <float**> (mMasterOut.get()),
mNumSamples);
return true;
}
@ -1646,8 +1601,6 @@ bool VSTEffect::GetAutomationParameters(EffectAutomationParameters & parms)
bool VSTEffect::SetAutomationParameters(EffectAutomationParameters & parms)
{
size_t slaveCnt = mSlaves.GetCount();
callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
for (int i = 0; i < mAEffect->numParams; i++)
{
@ -1666,10 +1619,8 @@ bool VSTEffect::SetAutomationParameters(EffectAutomationParameters & parms)
if (d >= -1.0 && d <= 1.0)
{
callSetParameter(i, d);
for (size_t i = 0; i < slaveCnt; i++)
{
mSlaves[i]->callSetParameter(i, d);
}
for (const auto &slave : mSlaves)
slave->callSetParameter(i, d);
}
}
callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
@ -1817,29 +1768,10 @@ bool VSTEffect::CloseUI()
RemoveHandler();
if (mNames)
{
delete [] mNames;
mNames = NULL;
}
if (mSliders)
{
delete [] mSliders;
mSliders = NULL;
}
if (mDisplays)
{
delete [] mDisplays;
mDisplays = NULL;
}
if (mLabels)
{
delete [] mLabels;
mLabels = NULL;
}
mNames.reset();
mSliders.reset();
mDisplays.reset();
mLabels.reset();
mUIHost = NULL;
mParent = NULL;
@ -1978,7 +1910,9 @@ void VSTEffect::ShowOptions()
if (dlg.ShowModal())
{
// Reinitialize configuration settings
mHost->GetSharedConfig(wxT("Options"), wxT("BufferSize"), mUserBlockSize, 8192);
int userBlockSize;
mHost->GetSharedConfig(wxT("Options"), wxT("BufferSize"), userBlockSize, 8192);
mUserBlockSize = std::max( 1, userBlockSize );
mHost->GetSharedConfig(wxT("Options"), wxT("UseLatency"), mUseLatency, true);
}
}
@ -2328,14 +2262,13 @@ bool VSTEffect::LoadParameters(const wxString & group)
if (mHost->GetPrivateConfig(group, wxT("Chunk"), value, wxEmptyString))
{
char *buf = new char[value.length() / 4 * 3];
ArrayOf<char> buf{ value.length() / 4 * 3 };
int len = VSTEffect::b64decode(value, buf);
int len = VSTEffect::b64decode(value, buf.get());
if (len)
{
callSetChunk(true, len, buf, &info);
callSetChunk(true, len, buf.get(), &info);
}
delete [] buf;
return true;
}
@ -2513,10 +2446,8 @@ void VSTEffect::Automate(int index, float value)
return;
}
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->callSetParameter(index, value);
}
for (const auto &slave : mSlaves)
slave->callSetParameter(index, value);
return;
}
@ -2587,10 +2518,8 @@ void VSTEffect::callSetParameter(int index, float value)
{
mAEffect->setParameter(mAEffect, index, value);
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->callSetParameter(index, value);
}
for (const auto &slave : mSlaves)
slave->callSetParameter(index, value);
}
}
@ -2599,10 +2528,8 @@ void VSTEffect::callSetProgram(int index)
callDispatcher(effBeginSetProgram, 0, 0, NULL, 0.0);
callDispatcher(effSetProgram, 0, index, NULL, 0.0);
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->callSetProgram(index);
}
for (const auto &slave : mSlaves)
slave->callSetProgram(index);
callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
}
@ -2643,10 +2570,8 @@ void VSTEffect::callSetChunk(bool isPgm, int len, void *buf, VstPatchChunkInfo *
callDispatcher(effSetChunk, isPgm ? 1 : 0, len, buf, 0.0);
callDispatcher(effEndSetProgram, 0, 0, NULL, 0.0);
for (size_t i = 0, cnt = mSlaves.GetCount(); i < cnt; i++)
{
mSlaves[i]->callSetChunk(isPgm, len, buf, info);
}
for (const auto &slave : mSlaves)
slave->callSetChunk(isPgm, len, buf, info);
}
////////////////////////////////////////////////////////////////////////////////
@ -2847,10 +2772,10 @@ void VSTEffect::BuildPlain()
mParent->SetSizer(mainSizer.release());
}
mNames = new wxStaticText *[mAEffect->numParams];
mSliders = new wxSlider *[mAEffect->numParams];
mDisplays = new wxStaticText *[mAEffect->numParams];
mLabels = new wxStaticText *[mAEffect->numParams];
mNames.reinit(static_cast<size_t>(mAEffect->numParams));
mSliders.reinit(static_cast<size_t>(mAEffect->numParams));
mDisplays.reinit(static_cast<size_t>(mAEffect->numParams));
mLabels.reinit(static_cast<size_t>(mAEffect->numParams));
{
auto paramSizer = std::make_unique<wxStaticBoxSizer>(wxVERTICAL, scroller, _("Effect Settings"));
@ -3062,7 +2987,7 @@ bool VSTEffect::LoadFXB(const wxFileName & fn)
}
// Allocate memory for the contents
unsigned char *data = new unsigned char[f.Length()];
ArrayOf<unsigned char> data{ size_t(f.Length()) };
if (!data)
{
wxMessageBox(_("Unable to allocate memory when loading presets file."),
@ -3071,7 +2996,7 @@ bool VSTEffect::LoadFXB(const wxFileName & fn)
mParent);
return false;
}
unsigned char *bptr = data;
unsigned char *bptr = data.get();
do
{
@ -3218,9 +3143,6 @@ bool VSTEffect::LoadFXB(const wxFileName & fn)
}
} while (false);
// Get rid of the data
delete [] data;
return ret;
}
@ -3236,7 +3158,7 @@ bool VSTEffect::LoadFXP(const wxFileName & fn)
}
// Allocate memory for the contents
unsigned char *data = new unsigned char[f.Length()];
ArrayOf<unsigned char> data{ size_t(f.Length()) };
if (!data)
{
wxMessageBox(_("Unable to allocate memory when loading presets file."),
@ -3245,7 +3167,7 @@ bool VSTEffect::LoadFXP(const wxFileName & fn)
mParent);
return false;
}
unsigned char *bptr = data;
unsigned char *bptr = data.get();
do
{
@ -3271,9 +3193,6 @@ bool VSTEffect::LoadFXP(const wxFileName & fn)
ret = LoadFXProgram(&bptr, len, i, false);
} while (false);
// Get rid of the data
delete [] data;
return ret;
}
@ -3947,15 +3866,14 @@ void VSTEffect::HandleXMLEndTag(const wxChar *tag)
{
if (mChunk.length())
{
char *buf = new char[mChunk.length() / 4 * 3];
ArrayOf<char> buf{ mChunk.length() / 4 * 3 };
int len = VSTEffect::b64decode(mChunk, buf);
int len = VSTEffect::b64decode(mChunk, buf.get());
if (len)
{
callSetChunk(true, len, buf, &mXMLInfo);
callSetChunk(true, len, buf.get(), &mXMLInfo);
}
delete [] buf;
mChunk.clear();
}
mInChunk = false;

View File

@ -16,6 +16,7 @@
#include "audacity/ModuleInterface.h"
#include "audacity/PluginInterface.h"
#include "../../SampleFormat.h"
#include "../../widgets/NumericTextCtrl.h"
#include "VSTControl.h"
@ -61,7 +62,7 @@ struct __CFBundle;
//
///////////////////////////////////////////////////////////////////////////////
WX_DEFINE_ARRAY_PTR(VSTEffect *, VSTEffectArray);
using VSTEffectArray = std::vector < movable_ptr<VSTEffect> > ;
DECLARE_LOCAL_EVENT_TYPE(EVT_SIZEWINDOW, -1);
DECLARE_LOCAL_EVENT_TYPE(EVT_UPDATEDISPLAY, -1);
@ -268,7 +269,7 @@ private:
int mMidiOuts;
bool mAutomatable;
float mSampleRate;
int mUserBlockSize;
size_t mUserBlockSize;
wxString mName;
wxString mVendor;
wxString mDescription;
@ -313,7 +314,7 @@ private:
bool mUseLatency;
int mBufferDelay;
int mBlockSize;
unsigned mBlockSize;
int mProcessLevel;
bool mHasPower;
@ -329,8 +330,7 @@ private:
VSTEffect *mMaster; // non-NULL if a slave
VSTEffectArray mSlaves;
unsigned mNumChannels;
float **mMasterIn;
float **mMasterOut;
FloatBuffers mMasterIn, mMasterOut;
size_t mNumSamples;
// UI
@ -343,10 +343,10 @@ private:
VSTControl *mControl;
NumericTextCtrl *mDuration;
wxStaticText **mNames;
wxSlider **mSliders;
wxStaticText **mDisplays;
wxStaticText **mLabels;
ArrayOf<wxStaticText *> mNames;
ArrayOf<wxSlider *> mSliders;
ArrayOf<wxStaticText *> mDisplays;
ArrayOf<wxStaticText *> mLabels;
bool mInSet;
bool mInChunk;

View File

@ -831,9 +831,6 @@ AudioUnitEffect::AudioUnitEffect(const wxString & path,
mDialog = NULL;
mParent = NULL;
mInputList = NULL;
mOutputList = NULL;
mUnitInitialized = false;
mEventListenerRef = NULL;
@ -965,17 +962,16 @@ bool AudioUnitEffect::SupportsAutomation()
}
UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
AudioUnitParameterID *array = new AudioUnitParameterID[cnt];
ArrayOf < AudioUnitParameterID > array{cnt};
result = AudioUnitGetProperty(mUnit,
kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global,
0,
array,
array.get(),
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
@ -991,20 +987,16 @@ bool AudioUnitEffect::SupportsAutomation()
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
if (info.flags & kAudioUnitParameterFlag_IsWritable)
{
// All we need is one
delete [] array;
return true;
}
}
delete [] array;
return false;
}
@ -1096,17 +1088,16 @@ bool AudioUnitEffect::SetHost(EffectHostInterface *host)
// And get them
UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
AudioUnitParameterID *array = new AudioUnitParameterID[cnt];
ArrayOf<AudioUnitParameterID> array {cnt};
result = AudioUnitGetProperty(mUnit,
kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global,
0,
array,
array.get(),
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
@ -1119,13 +1110,10 @@ bool AudioUnitEffect::SetHost(EffectHostInterface *host)
&event);
if (result != noErr)
{
delete [] array;
return false;
}
}
delete [] array;
event.mEventType = kAudioUnitEvent_PropertyChange;
event.mArgument.mProperty.mAudioUnit = mUnit;
event.mArgument.mProperty.mPropertyID = kAudioUnitProperty_Latency;
@ -1246,11 +1234,11 @@ bool AudioUnitEffect::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelN
{
OSStatus result;
mInputList = new AudioBufferList[mAudioIns];
mInputList->mNumberBuffers = mAudioIns;
mInputList.reinit( mAudioIns );
mInputList[0].mNumberBuffers = mAudioIns;
mOutputList = new AudioBufferList[mAudioOuts];
mOutputList->mNumberBuffers = mAudioOuts;
mOutputList.reinit( mAudioOuts );
mOutputList[0].mNumberBuffers = mAudioOuts;
memset(&mTimeStamp, 0, sizeof(AudioTimeStamp));
mTimeStamp.mSampleTime = 0; // This is a double-precision number that should
@ -1294,35 +1282,26 @@ bool AudioUnitEffect::ProcessFinalize()
{
mReady = false;
if (mOutputList)
{
delete [] mOutputList;
mOutputList = NULL;
}
if (mInputList)
{
delete [] mInputList;
mInputList = NULL;
}
mOutputList.reset();
mInputList.reset();
return true;
}
size_t AudioUnitEffect::ProcessBlock(float **inBlock, float **outBlock, size_t blockLen)
{
for (int i = 0; i < mAudioIns; i++)
for (size_t i = 0; i < mAudioIns; i++)
{
mInputList->mBuffers[i].mNumberChannels = 1;
mInputList->mBuffers[i].mData = inBlock[i];
mInputList->mBuffers[i].mDataByteSize = sizeof(float) * blockLen;
mInputList[0].mBuffers[i].mNumberChannels = 1;
mInputList[0].mBuffers[i].mData = inBlock[i];
mInputList[0].mBuffers[i].mDataByteSize = sizeof(float) * blockLen;
}
for (int i = 0; i < mAudioOuts; i++)
for (size_t i = 0; i < mAudioOuts; i++)
{
mOutputList->mBuffers[i].mNumberChannels = 1;
mOutputList->mBuffers[i].mData = outBlock[i];
mOutputList->mBuffers[i].mDataByteSize = sizeof(float) * blockLen;
mOutputList[0].mBuffers[i].mNumberChannels = 1;
mOutputList[0].mBuffers[i].mData = outBlock[i];
mOutputList[0].mBuffers[i].mDataByteSize = sizeof(float) * blockLen;
}
AudioUnitRenderActionFlags flags = 0;
@ -1333,7 +1312,7 @@ size_t AudioUnitEffect::ProcessBlock(float **inBlock, float **outBlock, size_t b
&mTimeStamp,
0,
blockLen,
mOutputList);
mOutputList.get());
if (result != noErr)
{
printf("Render failed: %d %4.4s\n", (int)result, (char *)&result);
@ -1347,20 +1326,8 @@ size_t AudioUnitEffect::ProcessBlock(float **inBlock, float **outBlock, size_t b
bool AudioUnitEffect::RealtimeInitialize()
{
mMasterIn = new float *[mAudioIns];
for (int i = 0; i < mAudioIns; i++)
{
mMasterIn[i] = new float[mBlockSize];
memset(mMasterIn[i], 0, mBlockSize * sizeof(float));
}
mMasterOut = new float *[mAudioOuts];
for (int i = 0; i < mAudioOuts; i++)
{
mMasterOut[i] = new float[mBlockSize];
}
mMasterIn.reinit(mAudioIns, mBlockSize, true);
mMasterOut.reinit( mAudioOuts, mBlockSize );
return ProcessInitialize(0);
}
@ -1389,17 +1356,8 @@ bool AudioUnitEffect::RealtimeFinalize()
mSlaves[i]->ProcessFinalize();
mSlaves.clear();
for (int i = 0; i < mAudioIns; i++)
{
delete [] mMasterIn[i];
}
delete [] mMasterIn;
for (int i = 0; i < mAudioOuts; i++)
{
delete [] mMasterOut[i];
}
delete [] mMasterOut;
mMasterIn.reset();
mMasterOut.reset();
return ProcessFinalize();
}
@ -1424,10 +1382,8 @@ bool AudioUnitEffect::RealtimeResume()
bool AudioUnitEffect::RealtimeProcessStart()
{
for (int i = 0; i < mAudioIns; i++)
{
memset(mMasterIn[i], 0, mBlockSize * sizeof(float));
}
for (size_t i = 0; i < mAudioIns; i++)
memset(mMasterIn[i].get(), 0, mBlockSize * sizeof(float));
mNumSamples = 0;
@ -1441,7 +1397,7 @@ size_t AudioUnitEffect::RealtimeProcess(int group,
{
wxASSERT(numSamples <= mBlockSize);
for (int c = 0; c < mAudioIns; c++)
for (size_t c = 0; c < mAudioIns; c++)
{
for (decltype(numSamples) s = 0; s < numSamples; s++)
{
@ -1455,7 +1411,10 @@ size_t AudioUnitEffect::RealtimeProcess(int group,
bool AudioUnitEffect::RealtimeProcessEnd()
{
ProcessBlock(mMasterIn, mMasterOut, mNumSamples);
ProcessBlock(
reinterpret_cast<float**>(mMasterIn.get()),
reinterpret_cast<float**>(mMasterOut.get()),
mNumSamples);
return true;
}
@ -1505,17 +1464,16 @@ bool AudioUnitEffect::GetAutomationParameters(EffectAutomationParameters & parms
}
UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
AudioUnitParameterID *array = new AudioUnitParameterID[cnt];
ArrayOf<AudioUnitParameterID> array {cnt};
result = AudioUnitGetProperty(mUnit,
kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global,
0,
array,
array.get(),
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
@ -1531,7 +1489,6 @@ bool AudioUnitEffect::GetAutomationParameters(EffectAutomationParameters & parms
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
@ -1554,14 +1511,11 @@ bool AudioUnitEffect::GetAutomationParameters(EffectAutomationParameters & parms
&value);
if (result != noErr)
{
delete [] array;
return false;
}
parms.Write(name, value);
}
delete [] array;
return true;
}
@ -1583,17 +1537,16 @@ bool AudioUnitEffect::SetAutomationParameters(EffectAutomationParameters & parms
}
UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
AudioUnitParameterID *array = new AudioUnitParameterID[cnt];
ArrayOf<AudioUnitParameterID> array {cnt};
result = AudioUnitGetProperty(mUnit,
kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global,
0,
array,
array.get(),
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
@ -1609,7 +1562,6 @@ bool AudioUnitEffect::SetAutomationParameters(EffectAutomationParameters & parms
&dataSize);
if (result != noErr)
{
delete [] array;
return false;
}
@ -1628,7 +1580,6 @@ bool AudioUnitEffect::SetAutomationParameters(EffectAutomationParameters & parms
double d = 0.0;
if (!parms.Read(name, &d))
{
delete [] array;
return false;
}
@ -1641,13 +1592,10 @@ bool AudioUnitEffect::SetAutomationParameters(EffectAutomationParameters & parms
0);
if (result != noErr)
{
delete [] array;
return false;
}
}
delete [] array;
AudioUnitParameter aup;
aup.mAudioUnit = mUnit;
aup.mParameterID = kAUParameterListener_AnyParameter;
@ -2064,8 +2012,6 @@ bool AudioUnitEffect::SetRateAndChannels()
bool AudioUnitEffect::CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit)
{
OSStatus result;
int numParameters, i;
AudioUnitParameterID *parameters;
Float32 parameterValue;
UInt32 size;
@ -2087,25 +2033,24 @@ bool AudioUnitEffect::CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit)
// Now get the list of all parameter IDs
numParameters = size / sizeof(AudioUnitParameterID);
parameters = new AudioUnitParameterID[numParameters];
auto numParameters = size / sizeof(AudioUnitParameterID);
ArrayOf<AudioUnitParameterID> parameters{ numParameters };
result = AudioUnitGetProperty(srcUnit,
kAudioUnitProperty_ParameterList,
kAudioUnitScope_Global,
0,
parameters,
parameters.get(),
&size);
if (result != 0)
{
printf("Couldn't get parameter list\n");
delete[] parameters;
return false;
}
// Copy the parameters from the main unit to the unit specific to
// this track
for (i = 0; i < numParameters; i++)
for (unsigned i = 0; i < numParameters; i++)
{
result = AudioUnitGetParameter(srcUnit,
parameters[i],
@ -2130,8 +2075,6 @@ bool AudioUnitEffect::CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit)
}
}
delete[] parameters;
return true;
}
@ -2152,9 +2095,7 @@ OSStatus AudioUnitEffect::Render(AudioUnitRenderActionFlags *inActionFlags,
AudioBufferList *ioData)
{
for (int i = 0; i < ioData->mNumberBuffers; i++)
{
ioData->mBuffers[i].mData = mInputList->mBuffers[i].mData;
}
ioData->mBuffers[i].mData = mInputList[0].mBuffers[i].mData;
return 0;
}

View File

@ -182,7 +182,7 @@ private:
EffectHostInterface *mHost;
unsigned mAudioIns;
int mAudioOuts;
unsigned mAudioOuts;
bool mInteractive;
bool mLatencyDone;
UInt32 mBlockSize;
@ -194,8 +194,8 @@ private:
AudioTimeStamp mTimeStamp;
bool mReady;
AudioBufferList *mInputList;
AudioBufferList *mOutputList;
ArrayOf<AudioBufferList> mInputList;
ArrayOf<AudioBufferList> mOutputList;
EffectUIHostInterface *mUIHost;
wxWindow *mParent;
@ -206,10 +206,9 @@ private:
AudioUnitEffect *mMaster; // non-NULL if a slave
AudioUnitEffectArray mSlaves;
unsigned mNumChannels;
float **mMasterIn;
float **mMasterOut;
ArraysOf<float> mMasterIn, mMasterOut;
size_t mNumSamples;
AUEventListenerRef mEventListenerRef;
friend class AudioUnitEffectExportDialog;

View File

@ -556,62 +556,14 @@ LadspaEffect::LadspaEffect(const wxString & path, int index)
mSampleRate = 44100;
mBlockSize = 0;
mInputPorts = NULL;
mOutputPorts = NULL;
mInputControls = NULL;
mOutputControls = NULL;
mLatencyPort = -1;
mDialog = NULL;
mParent = NULL;
mSliders = NULL;
mFields = NULL;
mLabels = NULL;
mToggles = NULL;
}
LadspaEffect::~LadspaEffect()
{
if (mInputPorts)
{
delete [] mInputPorts;
}
if (mOutputPorts)
{
delete [] mOutputPorts;
}
if (mInputControls)
{
delete [] mInputControls;
}
if (mOutputControls)
{
delete [] mOutputControls;
}
if (mToggles)
{
delete [] mToggles;
}
if (mSliders)
{
delete [] mSliders;
}
if (mFields)
{
delete [] mFields;
}
if (mLabels)
{
delete [] mLabels;
}
}
// ============================================================================
@ -715,10 +667,10 @@ bool LadspaEffect::SetHost(EffectHostInterface *host)
return false;
}
mInputPorts = new unsigned long [mData->PortCount];
mOutputPorts = new unsigned long [mData->PortCount];
mInputControls = new float [mData->PortCount];
mOutputControls = new float [mData->PortCount];
mInputPorts.reinit( mData->PortCount );
mOutputPorts.reinit( mData->PortCount );
mInputControls.reinit( mData->PortCount );
mOutputControls.reinit( mData->PortCount );
for (unsigned long p = 0; p < mData->PortCount; p++)
{
@ -1165,13 +1117,11 @@ bool LadspaEffect::PopulateUI(wxWindow *parent)
mParent->PushEventHandler(this);
mToggles = new wxCheckBox *[mData->PortCount];
mSliders = new wxSlider *[mData->PortCount];
mFields = new wxTextCtrl *[mData->PortCount];
mLabels = new wxStaticText *[mData->PortCount];
mMeters = new LadspaEffectMeter *[mData->PortCount];
memset(mFields, 0, mData->PortCount * sizeof(wxTextCtrl *));
mToggles.reinit( mData->PortCount );
mSliders.reinit( mData->PortCount );
mFields.reinit( mData->PortCount, true);
mLabels.reinit( mData->PortCount );
mMeters.reinit( mData->PortCount );
wxASSERT(mParent); // To justify safenew
wxScrolledWindow *const w = safenew wxScrolledWindow(mParent,
@ -1505,29 +1455,10 @@ bool LadspaEffect::CloseUI()
{
mParent->RemoveEventHandler(this);
if (mToggles)
{
delete [] mToggles;
mToggles = NULL;
}
if (mSliders)
{
delete [] mSliders;
mSliders = NULL;
}
if (mFields)
{
delete [] mFields;
mFields = NULL;
}
if (mLabels)
{
delete [] mLabels;
mLabels = NULL;
}
mToggles.reset();
mSliders.reset();
mFields.reset();
mLabels.reset();
mUIHost = NULL;
mParent = NULL;

View File

@ -13,6 +13,7 @@ class wxStaticText;
class wxTextCtrl;
class wxCheckBox;
#include "../../MemoryX.h"
#include <wx/dialog.h>
#include "audacity/EffectInterface.h"
@ -22,6 +23,7 @@ class wxCheckBox;
#include "../../widgets/NumericTextCtrl.h"
#include "ladspa.h"
#include "../../SampleFormat.h"
#define LADSPAEFFECTS_VERSION wxT("1.0.0.0")
#define LADSPAEFFECTS_FAMILY wxT("LADSPA")
@ -158,20 +160,19 @@ private:
double mSampleRate;
size_t mBlockSize;
int mUserBlockSize;
bool mInteractive;
unsigned mAudioIns;
unsigned long *mInputPorts;
ArrayOf<unsigned long> mInputPorts;
unsigned mAudioOuts;
unsigned long *mOutputPorts;
ArrayOf<unsigned long> mOutputPorts;
int mNumInputControls;
float *mInputControls;
Floats mInputControls;
int mNumOutputControls;
float *mOutputControls;
Floats mOutputControls;
bool mUseLatency;
int mLatencyPort;
@ -185,11 +186,11 @@ private:
NumericTextCtrl *mDuration;
wxDialog *mDialog;
wxWindow *mParent;
wxSlider **mSliders;
wxTextCtrl **mFields;
wxStaticText **mLabels;
wxCheckBox **mToggles;
LadspaEffectMeter **mMeters;
ArrayOf<wxSlider*> mSliders;
ArrayOf<wxTextCtrl*> mFields;
ArrayOf<wxStaticText*> mLabels;
ArrayOf<wxCheckBox*> mToggles;
ArrayOf<LadspaEffectMeter *> mMeters;
DECLARE_EVENT_TABLE()

View File

@ -315,15 +315,11 @@ LV2Effect::LV2Effect(const LilvPlugin *plug)
mLatency = 0.0;
mDialog = NULL;
mSliders = NULL;
mFields = NULL;
mURIMap = NULL;
mNumURIMap = 0;
mOptions = NULL;
mNumOptions = 0;
mFeatures = NULL;
mNumFeatures = 0;
mIdleFeature = NULL;
mOptionsInterface = NULL;
@ -342,15 +338,6 @@ LV2Effect::~LV2Effect()
free(mURIMap);
}
if (mFeatures)
{
for (int i = 0; mFeatures[i] != NULL; i++)
{
delete mFeatures[i];
}
free(mFeatures);
}
if (mOptions)
{
free(mOptions);
@ -460,10 +447,10 @@ bool LV2Effect::SetHost(EffectHostInterface *host)
{
mHost = host;
int numPorts = lilv_plugin_get_num_ports(mPlug);
auto numPorts = lilv_plugin_get_num_ports(mPlug);
// Fail if we don't grok the port types
for (int i = 0; i < numPorts; i++)
for (size_t i = 0; i < numPorts; i++)
{
const LilvPort *port = lilv_plugin_get_port_by_index(mPlug, i);
@ -474,176 +461,174 @@ bool LV2Effect::SetHost(EffectHostInterface *host)
}
}
// Allocate buffers for the port indices and the default control values
float *minimumVals = new float [numPorts];
float *maximumVals = new float [numPorts];
float *defaultValues = new float [numPorts];
// Retrieve the port ranges for all ports (some values may be NaN)
lilv_plugin_get_port_ranges_float(mPlug,
minimumVals,
maximumVals,
defaultValues);
// Get info about all ports
for (int i = 0; i < numPorts; i++)
{
const LilvPort *port = lilv_plugin_get_port_by_index(mPlug, i);
int index = lilv_port_get_index(mPlug, port);
// Allocate buffers for the port indices and the default control values
Floats minimumVals{ numPorts };
Floats maximumVals{ numPorts };
Floats defaultValues{ numPorts };
// Quick check for audio ports
if (lilv_port_is_a(mPlug, port, gAudio))
// Retrieve the port ranges for all ports (some values may be NaN)
lilv_plugin_get_port_ranges_float(mPlug,
minimumVals.get(),
maximumVals.get(),
defaultValues.get());
// Get info about all ports
for (size_t i = 0; i < numPorts; i++)
{
const LilvPort *port = lilv_plugin_get_port_by_index(mPlug, i);
int index = lilv_port_get_index(mPlug, port);
// Quick check for audio ports
if (lilv_port_is_a(mPlug, port, gAudio))
{
if (lilv_port_is_a(mPlug, port, gInput))
{
mAudioInputs.Add(index);
}
else if (lilv_port_is_a(mPlug, port, gOutput))
{
mAudioOutputs.Add(index);
}
continue;
}
// Only control ports from this point
if (!lilv_port_is_a(mPlug, port, gControl))
{
continue;
}
LV2Port ctrl;
ctrl.mIndex = index;
// Get the port name
ctrl.mSymbol = LilvString(lilv_port_get_symbol(mPlug, port));
LilvNode *tmpName = lilv_port_get_name(mPlug, port);
ctrl.mName = LilvString(tmpName);
lilv_node_free(tmpName);
// Get any unit descriptor
LilvNode *unit = lilv_port_get(mPlug, port, gUnit);
if (unit)
{
ctrl.mUnits = LilvString(lilv_world_get(gWorld, unit, gUnitSymbol, NULL));
}
// Get the group to which this port belongs or default to the main group
ctrl.mGroup = wxEmptyString;
LilvNode *group = lilv_port_get(mPlug, port, gGroup);
if (group)
{
ctrl.mGroup = LilvString(lilv_world_get(gWorld, group, gLabel, NULL));
if (ctrl.mGroup.IsEmpty())
{
ctrl.mGroup = LilvString(lilv_world_get(gWorld, group, gName, NULL));
}
if (ctrl.mGroup.IsEmpty())
{
ctrl.mGroup = LilvString(group);
}
}
// Add it if not previously done
if (mGroups.Index(ctrl.mGroup) == wxNOT_FOUND)
{
mGroups.Add(ctrl.mGroup);
}
// Get the scale points
LilvScalePoints *points = lilv_port_get_scale_points(mPlug, port);
LILV_FOREACH(scale_points, j, points)
{
const LilvScalePoint *point = lilv_scale_points_get(points, j);
ctrl.mScaleValues.Add(lilv_node_as_float(lilv_scale_point_get_value(point)));
ctrl.mScaleLabels.Add(LilvString(lilv_scale_point_get_label(point)));
}
lilv_scale_points_free(points);
// Collect the value and range info
ctrl.mHasLo = !std::isnan(minimumVals[i]);
ctrl.mHasHi = !std::isnan(maximumVals[i]);
ctrl.mMin = ctrl.mHasLo ? minimumVals[i] : 0.0;
ctrl.mMax = ctrl.mHasHi ? maximumVals[i] : 1.0;
ctrl.mLo = ctrl.mMin;
ctrl.mHi = ctrl.mMax;
ctrl.mDef = !std::isnan(defaultValues[i]) ?
defaultValues[i] :
ctrl.mHasLo ?
ctrl.mLo :
ctrl.mHasHi ?
ctrl.mHi :
0.0;
ctrl.mVal = ctrl.mDef;
// Figure out the type of port we have
if (lilv_port_is_a(mPlug, port, gInput))
{
mAudioInputs.Add(index);
}
else if (lilv_port_is_a(mPlug, port, gOutput))
{
mAudioOutputs.Add(index);
}
continue;
}
ctrl.mInput = true;
if (lilv_port_has_property(mPlug, port, gToggled))
{
ctrl.mToggle = true;
}
else if (lilv_port_has_property(mPlug, port, gEnumeration))
{
ctrl.mEnumeration = true;
}
else if (lilv_port_has_property(mPlug, port, gInteger))
{
ctrl.mInteger = true;
}
else if (lilv_port_has_property(mPlug, port, gSampleRate))
{
ctrl.mSampleRate = true;
}
// Only control ports from this point
if (!lilv_port_is_a(mPlug, port, gControl))
{
continue;
}
// Trigger properties can be combined with other types, but it
// seems mostly to be combined with toggle. So, we turn the
// checkbox into a button.
if (lilv_port_has_property(mPlug, port, gTrigger))
{
ctrl.mTrigger = true;
}
LV2Port ctrl;
ctrl.mIndex = index;
// We'll make the slider logarithmic
if (lilv_port_has_property(mPlug, port, gLogarithmic))
{
ctrl.mLogarithmic = true;
}
// Get the port name
ctrl.mSymbol = LilvString(lilv_port_get_symbol(mPlug, port));
LilvNode *tmpName = lilv_port_get_name(mPlug, port);
ctrl.mName = LilvString(tmpName);
lilv_node_free(tmpName);
if (lilv_port_has_property(mPlug, port, gEnumeration))
{
ctrl.mEnumeration = true;
}
// Get any unit descriptor
LilvNode *unit = lilv_port_get(mPlug, port, gUnit);
if (unit)
{
ctrl.mUnits = LilvString(lilv_world_get(gWorld, unit, gUnitSymbol, NULL));
}
// Get the group to which this port belongs or default to the main group
ctrl.mGroup = wxEmptyString;
LilvNode *group = lilv_port_get(mPlug, port, gGroup);
if (group)
{
ctrl.mGroup = LilvString(lilv_world_get(gWorld, group, gLabel, NULL));
if (ctrl.mGroup.IsEmpty())
{
ctrl.mGroup = LilvString(lilv_world_get(gWorld, group, gName, NULL));
}
if (ctrl.mGroup.IsEmpty())
{
ctrl.mGroup = LilvString(group);
}
}
// Add it if not previously done
if (mGroups.Index(ctrl.mGroup) == wxNOT_FOUND)
{
mGroups.Add(ctrl.mGroup);
}
// Get the scale points
LilvScalePoints *points = lilv_port_get_scale_points(mPlug, port);
LILV_FOREACH(scale_points, j, points)
{
const LilvScalePoint *point = lilv_scale_points_get(points, j);
ctrl.mScaleValues.Add(lilv_node_as_float(lilv_scale_point_get_value(point)));
ctrl.mScaleLabels.Add(LilvString(lilv_scale_point_get_label(point)));
}
lilv_scale_points_free(points);
// Collect the value and range info
ctrl.mHasLo = !std::isnan(minimumVals[i]);
ctrl.mHasHi = !std::isnan(maximumVals[i]);
ctrl.mMin = ctrl.mHasLo ? minimumVals[i] : 0.0;
ctrl.mMax = ctrl.mHasHi ? maximumVals[i] : 1.0;
ctrl.mLo = ctrl.mMin;
ctrl.mHi = ctrl.mMax;
ctrl.mDef = !std::isnan(defaultValues[i]) ?
defaultValues[i] :
ctrl.mHasLo ?
ctrl.mLo :
ctrl.mHasHi ?
ctrl.mHi :
0.0;
ctrl.mVal = ctrl.mDef;
// Figure out the type of port we have
if (lilv_port_is_a(mPlug, port, gInput))
{
ctrl.mInput = true;
if (lilv_port_has_property(mPlug, port, gToggled))
{
ctrl.mToggle = true;
}
else if (lilv_port_has_property(mPlug, port, gEnumeration))
{
ctrl.mEnumeration = true;
}
else if (lilv_port_has_property(mPlug, port, gInteger))
{
ctrl.mInteger = true;
}
else if (lilv_port_has_property(mPlug, port, gSampleRate))
{
ctrl.mSampleRate = true;
}
// Trigger properties can be combined with other types, but it
// seems mostly to be combined with toggle. So, we turn the
// checkbox into a button.
if (lilv_port_has_property(mPlug, port, gTrigger))
{
ctrl.mTrigger = true;
}
// We'll make the slider logarithmic
if (lilv_port_has_property(mPlug, port, gLogarithmic))
{
ctrl.mLogarithmic = true;
}
if (lilv_port_has_property(mPlug, port, gEnumeration))
{
ctrl.mEnumeration = true;
}
mControlsMap[ctrl.mIndex] = mControls.GetCount();
mGroupMap[ctrl.mGroup].Add(mControls.GetCount());
mControls.Add(ctrl);
}
else if (lilv_port_is_a(mPlug, port, gOutput))
{
ctrl.mInput = false;
if (lilv_port_has_property(mPlug, port, gLatency))
{
mLatencyPort = i;
}
else
{
mControlsMap[ctrl.mIndex] = mControls.GetCount();
mGroupMap[ctrl.mGroup].Add(mControls.GetCount());
mControls.Add(ctrl);
}
}
else
{
// Just ignore it for now
else if (lilv_port_is_a(mPlug, port, gOutput))
{
ctrl.mInput = false;
if (lilv_port_has_property(mPlug, port, gLatency))
{
mLatencyPort = i;
}
else
{
mGroupMap[ctrl.mGroup].Add(mControls.GetCount());
mControls.Add(ctrl);
}
}
else
{
// Just ignore it for now
}
}
}
delete [] minimumVals;
delete [] maximumVals;
delete [] defaultValues;
// mHost will be null during registration
if (mHost)
{
@ -747,7 +732,7 @@ void LV2Effect::SetSampleRate(double rate)
size_t LV2Effect::SetBlockSize(size_t maxBlockSize)
{
mBlockSize = (int) maxBlockSize;
mBlockSize = maxBlockSize;
if (mOptionsInterface && mOptionsInterface->set)
{
@ -837,19 +822,13 @@ size_t LV2Effect::ProcessBlock(float **inbuf, float **outbuf, size_t size)
bool LV2Effect::RealtimeInitialize()
{
mMasterIn = new float *[mAudioInputs.GetCount()];
mMasterIn.reinit( mAudioInputs.GetCount(), mBlockSize );
for (size_t p = 0, cnt = mAudioInputs.GetCount(); p < cnt; p++)
{
mMasterIn[p] = new float[mBlockSize];
lilv_instance_connect_port(mMaster, mAudioInputs[p], mMasterIn[p]);
}
lilv_instance_connect_port(mMaster, mAudioInputs[p], mMasterIn[p].get());
mMasterOut = new float *[mAudioOutputs.GetCount()];
mMasterOut.reinit( mAudioOutputs.GetCount(), mBlockSize );
for (size_t p = 0, cnt = mAudioOutputs.GetCount(); p < cnt; p++)
{
mMasterOut[p] = new float[mBlockSize];
lilv_instance_connect_port(mMaster, mAudioOutputs[p], mMasterOut[p]);
}
lilv_instance_connect_port(mMaster, mAudioOutputs[p], mMasterOut[p].get());
lilv_instance_activate(mMaster);
@ -868,17 +847,9 @@ bool LV2Effect::RealtimeFinalize()
lilv_instance_deactivate(mMaster);
for (size_t p = 0, cnt = mAudioInputs.GetCount(); p < cnt; p++)
{
delete [] mMasterIn[p];
}
delete [] mMasterIn;
for (size_t p = 0, cnt = mAudioOutputs.GetCount(); p < cnt; p++)
{
delete [] mMasterOut[p];
}
delete [] mMasterOut;
mMasterIn.reset();
mMasterOut.reset();
return true;
}
@ -896,9 +867,7 @@ bool LV2Effect::RealtimeResume()
bool LV2Effect::RealtimeProcessStart()
{
for (size_t p = 0, cnt = mAudioInputs.GetCount(); p < cnt; p++)
{
memset(mMasterIn[p], 0, mBlockSize * sizeof(float));
}
memset(mMasterIn[p].get(), 0, mBlockSize * sizeof(float));
mNumSamples = 0;
@ -1072,8 +1041,6 @@ bool LV2Effect::PopulateUI(wxWindow *parent)
mParent->PushEventHandler(this);
mSliders = NULL;
mFields = NULL;
mSuilHost = NULL;
mSuilInstance = NULL;
@ -1145,17 +1112,8 @@ bool LV2Effect::CloseUI()
mParent->RemoveEventHandler(this);
if (mSliders)
{
delete [] mSliders;
mSliders = NULL;
}
if (mFields)
{
delete [] mFields;
mFields = NULL;
}
mSliders.reset();
mFields.reset();
if (mSuilInstance)
{
@ -1365,27 +1323,26 @@ size_t LV2Effect::AddOption(const char *key, uint32_t size, const char *type, vo
LV2_Feature *LV2Effect::AddFeature(const char *uri, void *data)
{
int ndx = mNumFeatures;
mFeatures.resize(mFeatures.size() + 1);
mNumFeatures += 1;
mFeatures = (LV2_Feature **) realloc(mFeatures, mNumFeatures * sizeof(LV2_Feature *));
mFeatures[ndx] = NULL;
auto &pFeature = mFeatures.back();
if (uri != NULL)
{
mFeatures[ndx] = new LV2_Feature;
mFeatures[ndx]->URI = uri;
mFeatures[ndx]->data = data;
pFeature = make_movable<LV2_Feature>();
pFeature->URI = uri;
pFeature->data = data;
}
return mFeatures[ndx];
mFeaturePtrs.push_back(pFeature.get());
return pFeature.get();
}
LilvInstance *LV2Effect::InitInstance(float sampleRate)
{
LilvInstance *handle = lilv_plugin_instantiate(mPlug,
sampleRate,
mFeatures);
mFeaturePtrs.data());
if (!handle)
{
return NULL;
@ -1521,7 +1478,7 @@ bool LV2Effect::BuildFancy()
lilv_node_as_uri(uiType),
lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_bundle_uri(ui))),
lilv_uri_to_path(lilv_node_as_uri(lilv_ui_get_binary_uri(ui))),
mFeatures);
mFeaturePtrs.data());
lilv_uis_free(uis);
@ -1586,9 +1543,9 @@ bool LV2Effect::BuildPlain()
int numCols = 5;
// Allocate memory for the user parameter controls
int ctrlcnt = (int) mControls.GetCount();
mSliders = new wxSlider *[ctrlcnt];
mFields = new wxTextCtrl *[ctrlcnt];
auto ctrlcnt = mControls.GetCount();
mSliders.reinit(ctrlcnt);
mFields.reinit(ctrlcnt);
wxSizer *innerSizer;

View File

@ -13,6 +13,9 @@
#if USE_LV2
#include "../../MemoryX.h"
#include <vector>
#include <wx/checkbox.h>
#include <wx/dialog.h>
#include <wx/dynarray.h>
@ -32,6 +35,7 @@
#include <lilv/lilv.h>
#include <suil/suil.h>
#include "../../SampleFormat.h"
#include "../../widgets/NumericTextCtrl.h"
#include "LoadLV2.h"
@ -254,7 +258,7 @@ private:
EffectHostInterface *mHost;
int mBlockSize;
size_t mBlockSize;
double mSampleRate;
wxLongToLongHashMap mControlsMap;
@ -274,8 +278,7 @@ private:
LilvInstance *mProcess;
LV2SlaveArray mSlaves;
float **mMasterIn;
float **mMasterOut;
FloatBuffers mMasterIn, mMasterOut;
size_t mNumSamples;
double mLength;
@ -302,8 +305,8 @@ private:
LV2_Options_Option *mOptions;
int mNumOptions;
LV2_Feature **mFeatures;
int mNumFeatures;
std::vector<movable_ptr<LV2_Feature>> mFeatures;
std::vector<LV2_Feature*> mFeaturePtrs;
LV2_Feature *mInstanceAccessFeature;
LV2_Feature *mParentFeature;
@ -314,8 +317,8 @@ private:
SuilInstance *mSuilInstance;
NumericTextCtrl *mDuration;
wxSlider **mSliders;
wxTextCtrl **mFields;
ArrayOf<wxSlider*> mSliders;
ArrayOf<wxTextCtrl*> mFields;
bool mFactoryPresetsLoaded;
wxArrayString mFactoryPresetNames;

View File

@ -81,46 +81,10 @@ VampEffect::VampEffect(std::unique_ptr<Vamp::Plugin> &&plugin,
{
mKey = mPath.BeforeLast(wxT('/')).ToUTF8();
mName = mPath.AfterLast(wxT('/'));
mSliders = NULL;
mFields = NULL;
mLabels = NULL;
mToggles = NULL;
mChoices = NULL;
mValues = NULL;
}
VampEffect::~VampEffect()
{
if (mValues)
{
delete [] mValues;
}
if (mSliders)
{
delete [] mSliders;
}
if (mFields)
{
delete [] mFields;
}
if (mLabels)
{
delete [] mLabels;
}
if (mToggles)
{
delete [] mToggles;
}
if (mChoices)
{
delete [] mChoices;
}
}
// ============================================================================
@ -486,11 +450,7 @@ bool VampEffect::Process()
));
LabelTrack *ltrack = addedTracks.back()->get();
float **data = new float *[channels]; // ANSWER-ME: Vigilant Sentry marks this as memory leak, var "data" not deleted.
for (int c = 0; c < channels; ++c)
{
data[c] = new float[block];
}
FloatBuffers data{ channels, block };
auto originalLen = len;
auto ls = lstart;
@ -502,12 +462,12 @@ bool VampEffect::Process()
if (left)
{
left->Get((samplePtr)data[0], floatSample, ls, request);
left->Get((samplePtr)data[0].get(), floatSample, ls, request);
}
if (right)
{
right->Get((samplePtr)data[1], floatSample, rs, request);
right->Get((samplePtr)data[1].get(), floatSample, rs, request);
}
if (request < block)
@ -528,7 +488,8 @@ bool VampEffect::Process()
(int)(mRate + 0.5)
);
Vamp::Plugin::FeatureSet features = mPlugin->process(data, timestamp);
Vamp::Plugin::FeatureSet features = mPlugin->process(
reinterpret_cast< float** >( data.get() ), timestamp);
AddFeatures(ltrack, features);
if (len > (int)step)
@ -589,14 +550,14 @@ void VampEffect::PopulateOrExchange(ShuttleGui & S)
mParameters = mPlugin->getParameterDescriptors();
int count = mParameters.size();
auto count = mParameters.size();
mToggles = new wxCheckBox *[count];
mSliders = new wxSlider *[count];
mFields = new wxTextCtrl *[count];
mLabels = new wxStaticText *[count];
mChoices = new wxChoice *[count];
mValues = new float[count];
mToggles.reinit( count );
mSliders.reinit( count );
mFields.reinit( count );
mLabels.reinit( count );
mChoices.reinit( count );
mValues.reinit( count );
S.SetStyle(wxVSCROLL | wxTAB_TRAVERSAL);
wxScrolledWindow *scroller = S.StartScroller(2);
@ -631,10 +592,10 @@ void VampEffect::PopulateOrExchange(ShuttleGui & S)
S.AddSpace(1, 1);
}
for (int p = 0; p < count; p++)
for (size_t p = 0; p < count; p++)
{
wxString tip = wxString::FromUTF8(mParameters[p].description.c_str());
wxString unit = wxString::FromUTF8(mParameters[p].unit.c_str());
wxString tip = wxString::FromUTF8(mParameters[p].description.c_str());
wxString unit = wxString::FromUTF8(mParameters[p].unit.c_str());
float value = mPlugin->getParameter(mParameters[p].identifier);

View File

@ -25,6 +25,7 @@
#include <vamp-hostsdk/PluginLoader.h>
#include "../../SampleFormat.h"
#include "../Effect.h"
class LabelTrack;
@ -99,13 +100,13 @@ private:
Vamp::Plugin::ParameterList mParameters;
float *mValues;
Floats mValues;
wxSlider **mSliders;
wxTextCtrl **mFields;
wxStaticText **mLabels;
wxCheckBox **mToggles;
wxChoice **mChoices;
ArrayOf<wxSlider *> mSliders;
ArrayOf<wxTextCtrl *> mFields;
ArrayOf<wxStaticText *> mLabels;
ArrayOf<wxCheckBox *> mToggles;
ArrayOf<wxChoice *> mChoices;
wxChoice *mProgram;
DECLARE_EVENT_TABLE()

View File

@ -996,23 +996,20 @@ ExportMixerPanel::ExportMixerPanel( MixerSpec *mixerSpec,
wxArrayString trackNames,wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size):
wxPanelWrapper(parent, id, pos, size)
, mMixerSpec{mixerSpec}
, mChannelRects{ mMixerSpec->GetMaxNumChannels() }
, mTrackRects{ mMixerSpec->GetNumTracks() }
{
mBitmap = NULL;
mWidth = 0;
mHeight = 0;
mMixerSpec = mixerSpec;
mSelectedTrack = mSelectedChannel = -1;
mTrackRects = new wxRect[ mMixerSpec->GetNumTracks() ];
mChannelRects = new wxRect[ mMixerSpec->GetMaxNumChannels() ];
mTrackNames = trackNames;
}
ExportMixerPanel::~ExportMixerPanel()
{
delete[] mTrackRects;
delete[] mChannelRects;
}
//set the font on memDC such that text can fit in specified width and height

View File

@ -234,8 +234,8 @@ private:
int mWidth;
int mHeight;
MixerSpec *mMixerSpec;
wxRect *mChannelRects;
wxRect *mTrackRects;
ArrayOf<wxRect> mChannelRects;
ArrayOf<wxRect> mTrackRects;
int mSelectedTrack, mSelectedChannel;
wxArrayString mTrackNames;
int mBoxWidth, mChannelHeight, mTrackHeight;

View File

@ -139,7 +139,7 @@ bool ExportFLACOptions::TransferDataFromWindow()
// ExportFLAC Class
//----------------------------------------------------------------------------
#define SAMPLES_PER_RUN 8192
#define SAMPLES_PER_RUN 8192u
/* FLACPP_API_VERSION_CURRENT is 6 for libFLAC++ from flac-1.1.3 (see <FLAC++/export.h>) */
#if !defined FLACPP_API_VERSION_CURRENT || FLACPP_API_VERSION_CURRENT < 6
@ -311,11 +311,7 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
numChannels, SAMPLES_PER_RUN, false,
rate, format, true, mixerSpec);
int i;
FLAC__int32 **tmpsmplbuf = new FLAC__int32*[numChannels];
for (i = 0; i < numChannels; i++) {
tmpsmplbuf[i] = (FLAC__int32 *) calloc(SAMPLES_PER_RUN, sizeof(FLAC__int32));
}
ArraysOf<FLAC__int32> tmpsmplbuf{ numChannels, SAMPLES_PER_RUN, true };
{
ProgressDialog progress(wxFileName(fName).GetName(),
@ -329,7 +325,7 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
break;
}
else {
for (i = 0; i < numChannels; i++) {
for (size_t i = 0; i < numChannels; i++) {
samplePtr mixed = mixer->GetBuffer(i);
if (format == int24Sample) {
for (decltype(samplesThisRun) j = 0; j < samplesThisRun; j++) {
@ -342,7 +338,7 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
}
}
}
encoder.process(tmpsmplbuf, samplesThisRun);
encoder.process(reinterpret_cast<const FLAC__int32**>(tmpsmplbuf.get()), samplesThisRun);
}
updateResult = progress.Update(mixer->MixGetCurrentTime() - t0, t1 - t0);
}
@ -350,12 +346,6 @@ ProgressResult ExportFLAC::Export(AudacityProject *project,
encoder.finish();
}
for (i = 0; i < numChannels; i++) {
free(tmpsmplbuf[i]);
}
delete[] tmpsmplbuf;
return updateResult;
}

View File

@ -251,12 +251,12 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
// Values taken from the twolame simple encoder sample
const int pcmBufferSize = 9216 / 2; // number of samples
const int mp2BufferSize = 16384; // bytes
const size_t mp2BufferSize = 16384u; // bytes
// We allocate a buffer which is twice as big as the
// input buffer, which should always be enough.
// We have to multiply by 4 because one sample is 2 bytes wide!
unsigned char* mp2Buffer = new unsigned char[mp2BufferSize];
ArrayOf<unsigned char> mp2Buffer{ mp2BufferSize };
const WaveTrackConstArray waveTracks =
tracks->GetWaveTrackConstArray(selectionOnly, false);
@ -285,10 +285,10 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
encodeOptions,
pcmBuffer,
pcmNumSamples,
mp2Buffer,
mp2Buffer.get(),
mp2BufferSize);
outFile.Write(mp2Buffer, mp2BufferNumBytes);
outFile.Write(mp2Buffer.get(), mp2BufferNumBytes);
updateResult = progress.Update(mixer->MixGetCurrentTime() - t0, t1 - t0);
}
@ -296,16 +296,14 @@ ProgressResult ExportMP2::Export(AudacityProject *project,
int mp2BufferNumBytes = twolame_encode_flush(
encodeOptions,
mp2Buffer,
mp2Buffer.get(),
mp2BufferSize);
if (mp2BufferNumBytes > 0)
outFile.Write(mp2Buffer, mp2BufferNumBytes);
outFile.Write(mp2Buffer.get(), mp2BufferNumBytes);
twolame_close(&encodeOptions);
delete[] mp2Buffer;
/* Write ID3 tag if it was supposed to be at the end of the file */
if (id3len && endOfFile)

View File

@ -1808,8 +1808,8 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
auto updateResult = ProgressResult::Success;
long bytes;
int bufferSize = exporter.GetOutBufferSize();
unsigned char *buffer = new unsigned char[bufferSize];
size_t bufferSize = std::max(0, exporter.GetOutBufferSize());
ArrayOf<unsigned char> buffer{ bufferSize };
wxASSERT(buffer);
const WaveTrackConstArray waveTracks =
@ -1854,18 +1854,18 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
if (blockLen < inSamples) {
if (channels > 1) {
bytes = exporter.EncodeRemainder(mixed, blockLen, buffer);
bytes = exporter.EncodeRemainder(mixed, blockLen, buffer.get());
}
else {
bytes = exporter.EncodeRemainderMono(mixed, blockLen, buffer);
bytes = exporter.EncodeRemainderMono(mixed, blockLen, buffer.get());
}
}
else {
if (channels > 1) {
bytes = exporter.EncodeBuffer(mixed, buffer);
bytes = exporter.EncodeBuffer(mixed, buffer.get());
}
else {
bytes = exporter.EncodeBufferMono(mixed, buffer);
bytes = exporter.EncodeBufferMono(mixed, buffer.get());
}
}
@ -1876,16 +1876,16 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
break;
}
outFile.Write(buffer, bytes);
outFile.Write(buffer.get(), bytes);
updateResult = progress.Update(mixer->MixGetCurrentTime() - t0, t1 - t0);
}
}
bytes = exporter.FinishStream(buffer);
bytes = exporter.FinishStream(buffer.get());
if (bytes) {
outFile.Write(buffer, bytes);
outFile.Write(buffer.get(), bytes);
}
// Write ID3 tag if it was supposed to be at the end of the file
@ -1908,8 +1908,6 @@ ProgressResult ExportMP3::Export(AudacityProject *project,
// Close the file
outFile.Close();
delete [] buffer;
return updateResult;
}

View File

@ -263,7 +263,7 @@ ProgressResult ExportOGG::Export(AudacityProject *project,
}
else {
for (int i = 0; i < numChannels; i++) {
for (size_t i = 0; i < numChannels; i++) {
float *temp = (float *)mixer->GetBuffer(i);
memcpy(vorbis_buffer[i], temp, sizeof(float)*SAMPLES_PER_RUN);
}

View File

@ -36,11 +36,6 @@ FormatClassifier::FormatClassifier(const char* filename) :
{
FormatClassT fClass;
// Build buffers
mSigBuffer = new float[cSiglen];
mAuxBuffer = new float[cSiglen];
mRawBuffer = new uint8_t[cSiglen * 8];
// Define the classification classes
fClass.endian = MachineEndianness::Little;
fClass.format = MultiFormatReader::Int8;
@ -71,8 +66,8 @@ FormatClassifier::FormatClassifier(const char* filename) :
mClasses.push_back(fClass);
// Build feature vectors
mMonoFeat = new float[mClasses.size()];
mStereoFeat = new float[mClasses.size()];
mMonoFeat = Floats{ mClasses.size() };
mStereoFeat = Floats{ mClasses.size() };
#ifdef FORMATCLASSIFIER_SIGNAL_DEBUG
// Build a debug writer
@ -95,12 +90,6 @@ FormatClassifier::FormatClassifier(const char* filename) :
FormatClassifier::~FormatClassifier()
{
delete[] mSigBuffer;
delete[] mAuxBuffer;
delete[] mRawBuffer;
delete[] mMonoFeat;
delete[] mStereoFeat;
}
FormatClassifier::FormatClassT FormatClassifier::GetResultFormat()
@ -168,17 +157,17 @@ void FormatClassifier::Run()
// Do some simple preprocessing
// Remove DC offset
float smean = Mean(mSigBuffer, cSiglen);
Sub(mSigBuffer, smean, cSiglen);
float smean = Mean(mSigBuffer.get(), cSiglen);
Sub(mSigBuffer.get(), smean, cSiglen);
// Normalize to +- 1.0
Abs(mSigBuffer, mAuxBuffer, cSiglen);
float smax = Max(mAuxBuffer, cSiglen);
Div(mSigBuffer, smax, cSiglen);
Abs(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
float smax = Max(mAuxBuffer.get(), cSiglen);
Div(mSigBuffer.get(), smax, cSiglen);
// Now actually fill the feature vector
// Low to high band power ratio
float pLo = mMeter.CalcPower(mSigBuffer, 0.15f, 0.3f);
float pHi = mMeter.CalcPower(mSigBuffer, 0.45f, 0.1f);
float pLo = mMeter.CalcPower(mSigBuffer.get(), 0.15f, 0.3f);
float pHi = mMeter.CalcPower(mSigBuffer.get(), 0.45f, 0.1f);
mMonoFeat[n] = pLo / pHi;
}
@ -193,24 +182,24 @@ void FormatClassifier::Run()
// Do some simple preprocessing
// Remove DC offset
float smean = Mean(mSigBuffer, cSiglen);
Sub(mSigBuffer, smean, cSiglen);
float smean = Mean(mSigBuffer.get(), cSiglen);
Sub(mSigBuffer.get(), smean, cSiglen);
// Normalize to +- 1.0
Abs(mSigBuffer, mAuxBuffer, cSiglen);
float smax = Max(mAuxBuffer, cSiglen);
Div(mSigBuffer, smax, cSiglen);
Abs(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
float smax = Max(mAuxBuffer.get(), cSiglen);
Div(mSigBuffer.get(), smax, cSiglen);
// Now actually fill the feature vector
// Low to high band power ratio
float pLo = mMeter.CalcPower(mSigBuffer, 0.15f, 0.3f);
float pHi = mMeter.CalcPower(mSigBuffer, 0.45f, 0.1f);
float pLo = mMeter.CalcPower(mSigBuffer.get(), 0.15f, 0.3f);
float pHi = mMeter.CalcPower(mSigBuffer.get(), 0.45f, 0.1f);
mStereoFeat[n] = pLo / pHi;
}
// Get the results
size_t midx, sidx;
float monoMax = Max(mMonoFeat, mClasses.size(), &midx);
float stereoMax = Max(mStereoFeat, mClasses.size(), &sidx);
float monoMax = Max(mMonoFeat.get(), mClasses.size(), &midx);
float stereoMax = Max(mStereoFeat.get(), mClasses.size(), &sidx);
if (monoMax > stereoMax)
{
@ -233,27 +222,27 @@ void FormatClassifier::ReadSignal(FormatClassT format, size_t stride)
mReader.Reset();
// Do a dummy read of 1024 bytes to skip potential header information
mReader.ReadSamples(mRawBuffer, 1024, MultiFormatReader::Uint8, MachineEndianness::Little);
mReader.ReadSamples(mRawBuffer.get(), 1024, MultiFormatReader::Uint8, MachineEndianness::Little);
do
{
actRead = mReader.ReadSamples(mRawBuffer, cSiglen, stride, format.format, format.endian);
actRead = mReader.ReadSamples(mRawBuffer.get(), cSiglen, stride, format.format, format.endian);
if (n == 0)
{
ConvertSamples(mRawBuffer, mSigBuffer, format);
ConvertSamples(mRawBuffer.get(), mSigBuffer.get(), format);
}
else
{
if (actRead == cSiglen)
{
ConvertSamples(mRawBuffer, mAuxBuffer, format);
ConvertSamples(mRawBuffer.get(), mAuxBuffer.get(), format);
// Integrate signals
Add(mSigBuffer, mAuxBuffer, cSiglen);
Add(mSigBuffer.get(), mAuxBuffer.get(), cSiglen);
// Do some dummy reads to break signal coherence
mReader.ReadSamples(mRawBuffer, n + 1, stride, format.format, format.endian);
mReader.ReadSamples(mRawBuffer.get(), n + 1, stride, format.format, format.endian);
}
}

View File

@ -82,12 +82,12 @@ private:
std::unique_ptr<DebugWriter> mpWriter;
#endif
float* mSigBuffer;
float* mAuxBuffer;
uint8_t* mRawBuffer;
Floats mSigBuffer{ cSiglen };
Floats mAuxBuffer{ cSiglen };
ArrayOf<uint8_t> mRawBuffer{ cSiglen * 8 };
float* mMonoFeat;
float* mStereoFeat;
Floats mMonoFeat;
Floats mStereoFeat;
FormatClassT mResultFormat;
unsigned mResultChannels { 0 };

View File

@ -252,7 +252,7 @@ void MyFLACFile::error_callback(FLAC__StreamDecoderErrorStatus WXUNUSED(status))
FLAC__StreamDecoderWriteStatus MyFLACFile::write_callback(const FLAC__Frame *frame,
const FLAC__int32 * const buffer[])
{
short *tmp=new short[frame->header.blocksize];
ArrayOf<short> tmp{ frame->header.blocksize };
auto iter = mFile->mChannels.begin();
for (unsigned int chn=0; chn<mFile->mNumChannels; ++iter, ++chn) {
@ -261,7 +261,7 @@ FLAC__StreamDecoderWriteStatus MyFLACFile::write_callback(const FLAC__Frame *fra
tmp[s]=buffer[chn][s];
}
iter->get()->Append((samplePtr)tmp,
iter->get()->Append((samplePtr)tmp.get(),
int16Sample,
frame->header.blocksize);
}
@ -272,8 +272,6 @@ FLAC__StreamDecoderWriteStatus MyFLACFile::write_callback(const FLAC__Frame *fra
}
}
delete [] tmp;
mFile->mSamplesDone += frame->header.blocksize;
mFile->mUpdateResult = mFile->mProgress->Update((wxULongLong_t) mFile->mSamplesDone, mFile->mNumSamples != 0 ? (wxULongLong_t)mFile->mNumSamples : 1);
@ -452,7 +450,7 @@ ProgressResult FLACImportFileHandle::Import(TrackFactory *trackFactory,
mChannels.resize(mNumChannels);
auto iter = mChannels.begin();
for (int c = 0; c < mNumChannels; ++iter, ++c) {
for (size_t c = 0; c < mNumChannels; ++iter, ++c) {
*iter = trackFactory->NewWaveTrack(mFormat, mSampleRate);
if (mNumChannels == 2) {
@ -500,7 +498,7 @@ ProgressResult FLACImportFileHandle::Import(TrackFactory *trackFactory,
limitSampleBufferSize( maxBlockSize, fileTotalFrames - i );
auto iter = mChannels.begin();
for (int c = 0; c < mNumChannels; ++c, ++iter)
for (size_t c = 0; c < mNumChannels; ++c, ++iter)
iter->get()->AppendCoded(mFilename, i, blockLen, c, ODTask::eODFLAC);
mUpdateResult = mProgress->Update(
@ -540,7 +538,7 @@ ProgressResult FLACImportFileHandle::Import(TrackFactory *trackFactory,
tags->Clear();
size_t cnt = mFile->mComments.GetCount();
for (int c = 0; c < cnt; c++) {
for (size_t c = 0; c < cnt; c++) {
wxString name = mFile->mComments[c].BeforeFirst(wxT('='));
wxString value = mFile->mComments[c].AfterFirst(wxT('='));
if (name.Upper() == wxT("DATE") && !tags->HasTag(TAG_YEAR)) {

View File

@ -86,7 +86,7 @@ extern "C" {
#include "../WaveTrack.h"
#define INPUT_BUFFER_SIZE 65535
#define INPUT_BUFFER_SIZE 65535u
#define PROGRESS_SCALING_FACTOR 100000
/* this is a private structure we can use for whatever we like, and it will get
@ -94,7 +94,7 @@ extern "C" {
* things. */
struct private_data {
wxFile *file; /* the file containing the mp3 data we're feeding the encoder */
unsigned char *inputBuffer;
ArrayOf<unsigned char> inputBuffer{ INPUT_BUFFER_SIZE };
int inputBufferFill; /* amount of data in inputBuffer */
TrackFactory *trackFactory;
TrackHolders channels;
@ -152,7 +152,6 @@ private:
std::unique_ptr<wxFile> mFile;
void *mUserData;
struct private_data mPrivateData;
mad_decoder mDecoder;
};
@ -217,33 +216,31 @@ ProgressResult MP3ImportFileHandle::Import(TrackFactory *trackFactory, TrackHold
/* Prepare decoder data, initialize decoder */
mPrivateData.file = mFile.get();
mPrivateData.inputBuffer = new unsigned char [INPUT_BUFFER_SIZE];
mPrivateData.inputBufferFill = 0;
mPrivateData.progress = mProgress.get();
mPrivateData.updateResult= ProgressResult::Success;
mPrivateData.id3checked = false;
mPrivateData.numChannels = 0;
mPrivateData.trackFactory= trackFactory;
mPrivateData.eof = false;
private_data privateData;
privateData.file = mFile.get();
privateData.inputBufferFill = 0;
privateData.progress = mProgress.get();
privateData.updateResult= ProgressResult::Success;
privateData.id3checked = false;
privateData.numChannels = 0;
privateData.trackFactory= trackFactory;
privateData.eof = false;
mad_decoder_init(&mDecoder, &mPrivateData, input_cb, 0, 0, output_cb, error_cb, 0);
mad_decoder_init(&mDecoder, &privateData, input_cb, 0, 0, output_cb, error_cb, 0);
/* and send the decoder on its way! */
bool res = (mad_decoder_run(&mDecoder, MAD_DECODER_MODE_SYNC) == 0) &&
(mPrivateData.numChannels > 0) &&
!(mPrivateData.updateResult == ProgressResult::Cancelled) &&
!(mPrivateData.updateResult == ProgressResult::Failed);
(privateData.numChannels > 0) &&
!(privateData.updateResult == ProgressResult::Cancelled) &&
!(privateData.updateResult == ProgressResult::Failed);
mad_decoder_finish(&mDecoder);
delete[] mPrivateData.inputBuffer;
if (!res) {
/* failure */
/* printf("failure\n"); */
return (mPrivateData.updateResult);
return (privateData.updateResult);
}
/* success */
@ -251,15 +248,15 @@ ProgressResult MP3ImportFileHandle::Import(TrackFactory *trackFactory, TrackHold
/* copy the WaveTrack pointers into the Track pointer list that
* we are expected to fill */
for(const auto &channel : mPrivateData.channels) {
for(const auto &channel : privateData.channels) {
channel->Flush();
}
outTracks.swap(mPrivateData.channels);
outTracks.swap(privateData.channels);
/* Read in any metadata */
ImportID3(tags);
return mPrivateData.updateResult;
return privateData.updateResult;
}
MP3ImportFileHandle::~MP3ImportFileHandle()
@ -418,8 +415,8 @@ enum mad_flow input_cb(void *_data, struct mad_stream *stream)
#ifdef USE_LIBID3TAG
if (!data->id3checked) {
data->file->Read(data->inputBuffer, ID3_TAG_QUERYSIZE);
int len = id3_tag_query(data->inputBuffer, ID3_TAG_QUERYSIZE);
data->file->Read(data->inputBuffer.get(), ID3_TAG_QUERYSIZE);
int len = id3_tag_query(data->inputBuffer.get(), ID3_TAG_QUERYSIZE);
if (len > 0) {
data->file->Seek(len, wxFromStart);
}
@ -440,14 +437,15 @@ enum mad_flow input_cb(void *_data, struct mad_stream *stream)
* -- Rob Leslie, on the mad-dev mailing list */
int unconsumedBytes;
if (stream->next_frame) {
if(stream->next_frame ) {
/* we must use inputBufferFill instead of INPUT_BUFFER_SIZE here
because the final buffer of the file may be only partially
filled, and we would otherwise be providing too much input
after eof */
unconsumedBytes = data->inputBuffer + data->inputBufferFill
- stream->next_frame;
memmove(data->inputBuffer, stream->next_frame, unconsumedBytes);
unconsumedBytes = data->inputBuffer.get() + data->inputBufferFill
- stream->next_frame;
if (unconsumedBytes > 0)
memmove(data->inputBuffer.get(), stream->next_frame, unconsumedBytes);
}
else
unconsumedBytes = 0;
@ -458,19 +456,19 @@ enum mad_flow input_cb(void *_data, struct mad_stream *stream)
/* supply the requisite MAD_BUFFER_GUARD zero bytes to ensure
the final frame gets decoded properly, then finish */
memset(data->inputBuffer + unconsumedBytes, 0, MAD_BUFFER_GUARD);
memset(data->inputBuffer.get() + unconsumedBytes, 0, MAD_BUFFER_GUARD);
mad_stream_buffer
(stream, data->inputBuffer, MAD_BUFFER_GUARD + unconsumedBytes);
(stream, data->inputBuffer.get(), MAD_BUFFER_GUARD + unconsumedBytes);
data->eof = true; /* so on next call, we will tell mad to stop */
return MAD_FLOW_CONTINUE;
}
off_t read = data->file->Read(data->inputBuffer + unconsumedBytes,
off_t read = data->file->Read(data->inputBuffer.get() + unconsumedBytes,
INPUT_BUFFER_SIZE - unconsumedBytes);
mad_stream_buffer(stream, data->inputBuffer, read + unconsumedBytes);
mad_stream_buffer(stream, data->inputBuffer.get(), read + unconsumedBytes);
data->inputBufferFill = int(read + unconsumedBytes);
@ -486,7 +484,6 @@ enum mad_flow output_cb(void *_data,
{
int samplerate;
struct private_data *data = (struct private_data *)_data;
int smpl;
samplerate= pcm->samplerate;
auto channels = pcm->channels;
@ -526,24 +523,17 @@ enum mad_flow output_cb(void *_data,
* point samples into something we can feed to the WaveTrack. Allocating
* big blocks of data like this isn't a great idea, but it's temporary.
*/
float **channelBuffers = new float* [channels];
for(int chn = 0; chn < channels; chn++)
channelBuffers[chn] = new float [samples];
FloatBuffers channelBuffers{ channels, samples };
for(smpl = 0; smpl < samples; smpl++)
for (size_t smpl = 0; smpl < samples; smpl++)
for(int chn = 0; chn < channels; chn++)
channelBuffers[chn][smpl] = scale(pcm->samples[chn][smpl]);
auto iter = data->channels.begin();
for (int chn = 0; chn < channels; ++iter, ++chn)
iter->get()->Append((samplePtr)channelBuffers[chn],
for (int chn = 0; chn < channels; chn++)
data->channels[chn]->Append((samplePtr)channelBuffers[chn].get(),
floatSample,
samples);
for(int chn = 0; chn < channels; chn++)
delete[] channelBuffers[chn];
delete[] channelBuffers;
return MAD_FLOW_CONTINUE;
}

View File

@ -106,11 +106,11 @@ public:
: ImportFileHandle(filename),
mFile(std::move(file)),
mVorbisFile(std::move(vorbisFile))
, mStreamUsage{ static_cast<size_t>(mVorbisFile->links) }
{
mFormat = (sampleFormat)
gPrefs->Read(wxT("/SamplingRate/DefaultProjectSampleFormat"), floatSample);
mStreamUsage = new int[mVorbisFile->links];
for (int i = 0; i < mVorbisFile->links; i++)
{
wxString strinfo;
@ -153,7 +153,7 @@ private:
std::unique_ptr<wxFFile> mFile;
std::unique_ptr<OggVorbis_File> mVorbisFile;
int *mStreamUsage;
ArrayOf<int> mStreamUsage;
wxArrayString mStreamInfo;
std::list<TrackHolders> mChannels;
@ -243,7 +243,7 @@ ProgressResult OggImportFileHandle::Import(TrackFactory *trackFactory, TrackHold
mChannels.resize(mVorbisFile->links);
int i = -1;
for (auto &link: mChannels)
for (auto &link : mChannels)
{
++i;
@ -259,7 +259,7 @@ ProgressResult OggImportFileHandle::Import(TrackFactory *trackFactory, TrackHold
link.resize(vi->channels);
int c = - 1;
int c = -1;
for (auto &channel : link) {
++c;
@ -267,13 +267,13 @@ ProgressResult OggImportFileHandle::Import(TrackFactory *trackFactory, TrackHold
if (vi->channels == 2) {
switch (c) {
case 0:
channel->SetChannel(Track::LeftChannel);
channel->SetLinked(true);
break;
case 1:
channel->SetChannel(Track::RightChannel);
break;
case 0:
channel->SetChannel(Track::LeftChannel);
channel->SetLinked(true);
break;
case 1:
channel->SetChannel(Track::RightChannel);
break;
}
}
else {
@ -282,88 +282,88 @@ ProgressResult OggImportFileHandle::Import(TrackFactory *trackFactory, TrackHold
}
}
/* The number of bytes to get from the codec in each run */
#define CODEC_TRANSFER_SIZE 4096
/* The number of bytes to get from the codec in each run */
#define CODEC_TRANSFER_SIZE 4096u
/* The number of samples to read between calls to the callback.
* Balance between responsiveness of the GUI and throughput of import. */
/* The number of samples to read between calls to the callback.
* Balance between responsiveness of the GUI and throughput of import. */
#define SAMPLES_PER_CALLBACK 100000
short *mainBuffer = new short[CODEC_TRANSFER_SIZE];
/* determine endianness (clever trick courtesy of Nicholas Devillard,
* (http://www.eso.org/~ndevilla/endian/) */
int testvar = 1, endian;
if(*(char *)&testvar)
endian = 0; // little endian
else
endian = 1; // big endian
/* number of samples currently in each channel's buffer */
auto updateResult = ProgressResult::Success;
long bytesRead = 0;
long samplesRead = 0;
int bitstream = 0;
int samplesSinceLastCallback = 0;
{
ArrayOf<short> mainBuffer{ CODEC_TRANSFER_SIZE };
// You would think that the stream would already be seeked to 0, and
// indeed it is if the file is legit. But I had several ogg files on
// my hard drive that have malformed headers, and this added call
// causes them to be read correctly. Otherwise they have lots of
// zeros inserted at the beginning
ov_pcm_seek(mVorbisFile.get(), 0);
/* determine endianness (clever trick courtesy of Nicholas Devillard,
* (http://www.eso.org/~ndevilla/endian/) */
int testvar = 1, endian;
if (*(char *)&testvar)
endian = 0; // little endian
else
endian = 1; // big endian
do {
/* get data from the decoder */
bytesRead = ov_read(mVorbisFile.get(), (char *) mainBuffer,
CODEC_TRANSFER_SIZE,
endian,
2, // word length (2 for 16 bit samples)
1, // signed
&bitstream);
/* number of samples currently in each channel's buffer */
long samplesRead = 0;
int bitstream = 0;
int samplesSinceLastCallback = 0;
if (bytesRead == OV_HOLE) {
wxFileName ff(mFilename);
wxLogError(wxT("Ogg Vorbis importer: file %s is malformed, ov_read() reported a hole"),
ff.GetFullName().c_str());
/* http://lists.xiph.org/pipermail/vorbis-dev/2001-February/003223.html
* is the justification for doing this - best effort for malformed file,
* hence the message.
*/
continue;
} else if (bytesRead < 0) {
/* Malformed Ogg Vorbis file. */
/* TODO: Return some sort of meaningful error. */
wxLogError(wxT("Ogg Vorbis importer: ov_read() returned error %i"),
bytesRead);
break;
}
// You would think that the stream would already be seeked to 0, and
// indeed it is if the file is legit. But I had several ogg files on
// my hard drive that have malformed headers, and this added call
// causes them to be read correctly. Otherwise they have lots of
// zeros inserted at the beginning
ov_pcm_seek(mVorbisFile.get(), 0);
samplesRead = bytesRead / mVorbisFile->vi[bitstream].channels / sizeof(short);
do {
/* get data from the decoder */
bytesRead = ov_read(mVorbisFile.get(), (char *)mainBuffer.get(),
CODEC_TRANSFER_SIZE,
endian,
2, // word length (2 for 16 bit samples)
1, // signed
&bitstream);
/* give the data to the wavetracks */
auto iter = mChannels.begin();
std::advance(iter, bitstream);
if (mStreamUsage[bitstream] != 0)
{
auto iter2 = iter->begin();
for (int c = 0; c < mVorbisFile->vi[bitstream].channels; ++iter2, ++c)
iter2->get()->Append((char *)(mainBuffer + c),
int16Sample,
samplesRead,
mVorbisFile->vi[bitstream].channels);
}
if (bytesRead == OV_HOLE) {
wxFileName ff(mFilename);
wxLogError(wxT("Ogg Vorbis importer: file %s is malformed, ov_read() reported a hole"),
ff.GetFullName().c_str());
/* http://lists.xiph.org/pipermail/vorbis-dev/2001-February/003223.html
* is the justification for doing this - best effort for malformed file,
* hence the message.
*/
continue;
}
else if (bytesRead < 0) {
/* Malformed Ogg Vorbis file. */
/* TODO: Return some sort of meaningful error. */
wxLogError(wxT("Ogg Vorbis importer: ov_read() returned error %i"),
bytesRead);
break;
}
samplesSinceLastCallback += samplesRead;
if (samplesSinceLastCallback > SAMPLES_PER_CALLBACK) {
updateResult = mProgress->Update(ov_time_tell(mVorbisFile.get()),
ov_time_total(mVorbisFile.get(), bitstream));
samplesSinceLastCallback -= SAMPLES_PER_CALLBACK;
samplesRead = bytesRead / mVorbisFile->vi[bitstream].channels / sizeof(short);
}
} while (updateResult == ProgressResult::Success && bytesRead != 0);
/* give the data to the wavetracks */
auto iter = mChannels.begin();
std::advance(iter, bitstream);
if (mStreamUsage[bitstream] != 0)
{
auto iter2 = iter->begin();
for (int c = 0; c < mVorbisFile->vi[bitstream].channels; ++iter2, ++c)
iter2->get()->Append((char *)(mainBuffer.get() + c),
int16Sample,
samplesRead,
mVorbisFile->vi[bitstream].channels);
}
delete[]mainBuffer;
samplesSinceLastCallback += samplesRead;
if (samplesSinceLastCallback > SAMPLES_PER_CALLBACK) {
updateResult = mProgress->Update(ov_time_tell(mVorbisFile.get()),
ov_time_total(mVorbisFile.get(), bitstream));
samplesSinceLastCallback -= SAMPLES_PER_CALLBACK;
}
} while (updateResult == ProgressResult::Success && bytesRead != 0);
}
auto res = updateResult;
if (bytesRead < 0)
@ -406,7 +406,6 @@ OggImportFileHandle::~OggImportFileHandle()
ov_clear(mVorbisFile.get());
mFile->Detach(); // so that it doesn't try to close the file (ov_clear()
// did that already)
delete[] mStreamUsage;
}
#endif /* USE_LIBVORBIS */

View File

@ -87,7 +87,7 @@ class ImportRawDialog final : public wxDialogWrapper {
wxTextCtrl *mRateText;
int mNumEncodings;
int *mEncodingSubtype;
ArrayOf<int> mEncodingSubtype;
DECLARE_EVENT_TABLE()
};
@ -340,7 +340,7 @@ ImportRawDialog::ImportRawDialog(wxWindow * parent,
num = sf_num_encodings();
mNumEncodings = 0;
mEncodingSubtype = new int[num];
mEncodingSubtype.reinit(static_cast<size_t>(num));
selection = 0;
for (i=0; i<num; i++) {
@ -464,7 +464,6 @@ ImportRawDialog::ImportRawDialog(wxWindow * parent,
ImportRawDialog::~ImportRawDialog()
{
delete[] mEncodingSubtype;
}
void ImportRawDialog::OnOK(wxCommandEvent & WXUNUSED(event))

View File

@ -26,23 +26,14 @@ measurements in subbands or in the entire signal band.
SpecPowerMeter::SpecPowerMeter(size_t sigLen)
: mSigLen(sigLen)
, mSigI{ sigLen, true }
, mSigFR{ sigLen }
, mSigFI{ sigLen }
{
// Init buffers
mSigI = new float[sigLen];
mSigFR = new float[sigLen];
mSigFI = new float[sigLen];
for (int n = 0; n < sigLen; n++)
{
mSigI[n] = 0.0f;
}
}
SpecPowerMeter::~SpecPowerMeter()
{
delete[] mSigI;
delete[] mSigFR;
delete[] mSigFI;
}
float SpecPowerMeter::CalcPower(float* sig, float fc, float bw)
@ -59,10 +50,10 @@ float SpecPowerMeter::CalcPower(float* sig, float fc, float bw)
}
// Calc the FFT
FFT(mSigLen, 0, sig, mSigI, mSigFR, mSigFI);
FFT(mSigLen, 0, sig, mSigI.get(), mSigFR.get(), mSigFI.get());
// Calc the in-band power
pwr = CalcBinPower(mSigFR, mSigFI, loBin, hiBin);
pwr = CalcBinPower(mSigFR.get(), mSigFI.get(), loBin, hiBin);
return pwr;
}

View File

@ -12,14 +12,15 @@
#define __AUDACITY_SPECPOWERMETER_H_
#include <cstddef>
#include "../SampleFormat.h"
class SpecPowerMeter
{
const size_t mSigLen;
float* mSigI;
float* mSigFR;
float* mSigFI;
Floats mSigI;
Floats mSigFR;
Floats mSigFI;
float CalcBinPower(float* sig_f_r, float* sig_f_i, int loBin, int hiBin);
int Freq2Bin(float fc);

View File

@ -124,7 +124,7 @@ FLAC__StreamDecoderWriteStatus ODFLACFile::write_callback(const FLAC__Frame *fra
mDecoder->mDecodeBufferWritePosition+=bytesToCopy;
/*
short *tmp=new short[frame->header.blocksize];
ArrayOf<short> tmp{ frame->header.blocksize };
for (unsigned int chn=0; chn<mDecoder->mNumChannels; chn++) {
if (frame->header.bits_per_sample == 16) {
@ -132,7 +132,7 @@ FLAC__StreamDecoderWriteStatus ODFLACFile::write_callback(const FLAC__Frame *fra
tmp[s]=buffer[chn][s];
}
mDecoder->mChannels[chn]->Append((samplePtr)tmp,
mDecoder->mChannels[chn]->Append((samplePtr)tmp.get(),
int16Sample,
frame->header.blocksize);
}
@ -142,8 +142,6 @@ FLAC__StreamDecoderWriteStatus ODFLACFile::write_callback(const FLAC__Frame *fra
frame->header.blocksize);
}
}
delete [] tmp;
*/
mDecoder->mSamplesDone += frame->header.blocksize;

View File

@ -352,18 +352,9 @@ void SpectrogramSettings::DestroyWindows()
EndFFT(hFFT);
hFFT = NULL;
}
if (window != NULL) {
delete[] window;
window = NULL;
}
if (dWindow != NULL) {
delete[] dWindow;
dWindow = NULL;
}
if (tWindow != NULL) {
delete[] tWindow;
tWindow = NULL;
}
window.reset();
dWindow.reset();
tWindow.reset();
}
@ -371,13 +362,11 @@ namespace
{
enum { WINDOW, TWINDOW, DWINDOW };
void RecreateWindow(
float *&window, int which, size_t fftLen,
Floats &window, int which, size_t fftLen,
size_t padding, int windowType, size_t windowSize, double &scale)
{
if (window != NULL)
delete[] window;
// Create the requested window function
window = new float[fftLen];
window = Floats{ fftLen };
int ii;
const bool extra = padding > 0;
@ -397,16 +386,15 @@ namespace
// Overwrite middle as needed
switch (which) {
case WINDOW:
NewWindowFunc(windowType, windowSize, extra, window + padding);
NewWindowFunc(windowType, windowSize, extra, window.get() + padding);
break;
// Future, reassignment
case TWINDOW:
NewWindowFunc(windowType, windowSize, extra, window + padding);
NewWindowFunc(windowType, windowSize, extra, window.get() + padding);
for (int ii = padding, multiplier = -(int)windowSize / 2; ii < endOfWindow; ++ii, ++multiplier)
window[ii] *= multiplier;
break;
case DWINDOW:
DerivativeOfWindowFunc(windowType, windowSize, extra, window + padding);
DerivativeOfWindowFunc(windowType, windowSize, extra, window.get() + padding);
break;
default:
wxASSERT(false);

View File

@ -12,6 +12,7 @@ Paul Licameli
#define __AUDACITY_SPECTROGRAM_SETTINGS__
#include "../Experimental.h"
#include "../SampleFormat.h"
#undef SPECTRAL_SELECTION_GLOBAL_SWITCH
@ -153,10 +154,10 @@ public:
// Variables used for computing the spectrum
mutable FFTParam *hFFT{};
mutable float *window{};
mutable Floats window;
// Two other windows for computing reassigned spectrogram
mutable float *tWindow{}; // Window times time parameter
mutable float *dWindow{}; // Derivative of window
mutable Floats tWindow; // Window times time parameter
mutable Floats dWindow; // Derivative of window
};
#endif

Some files were not shown because too many files have changed in this diff Show More