diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 1c7eb90f0..234c4c625 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -464,6 +464,7 @@ time warp info and AudioIOListener and whether the playback is looped. #include "DBConnection.h" #include "ProjectFileIO.h" #include "WaveTrack.h" +#include "AudioIOBufferHelper.h" #include "effects/RealtimeEffectManager.h" #include "prefs/QualitySettings.h" @@ -3843,14 +3844,7 @@ bool AudioIoCallback::FillOutputBuffers( } // ------ MEMORY ALLOCATION ---------------------- - // These are small structures. - auto chans = new WaveTrack * [numPlaybackChannels]; - auto tempBufs = new float* [numPlaybackChannels]; - - // And these are larger structures.... - for (unsigned int c = 0; c < numPlaybackChannels; c++) { - tempBufs[c] = new float[framesPerBuffer]; - } + std::unique_ptr bufHelper = std::make_unique(numPlaybackChannels, framesPerBuffer); // ------ End of MEMORY ALLOCATION --------------- auto & em = RealtimeEffectManager::Get(); @@ -3882,7 +3876,7 @@ bool AudioIoCallback::FillOutputBuffers( for (unsigned t = 0; t < numPlaybackTracks; t++) { WaveTrack *vt = mPlaybackTracks[t].get(); - chans[chanCnt] = vt; + bufHelper.get()->chans[chanCnt] = vt; // TODO: more-than-two-channels auto nextTrack = @@ -3901,7 +3895,7 @@ bool AudioIoCallback::FillOutputBuffers( // IF mono THEN clear 'the other' channel. if ( lastChannel && (numPlaybackChannels>1)) { // TODO: more-than-two-channels - memset(tempBufs[1], 0, framesPerBuffer * sizeof(float)); + memset(bufHelper.get()->tempBufs[1], 0, framesPerBuffer * sizeof(float)); } drop = TrackShouldBeSilent( *vt ); dropQuickly = drop; @@ -3920,7 +3914,7 @@ bool AudioIoCallback::FillOutputBuffers( } else { - len = mPlaybackBuffers[t]->Get((samplePtr)tempBufs[chanCnt], + len = mPlaybackBuffers[t]->Get((samplePtr)bufHelper.get()->tempBufs[chanCnt], floatSample, toGet); // wxASSERT( len == toGet ); @@ -3931,7 +3925,7 @@ bool AudioIoCallback::FillOutputBuffers( // real-time demand in this thread (see bug 1932). We // must supply something to the sound card, so pad it with // zeroes and not random garbage. - memset((void*)&tempBufs[chanCnt][len], 0, + memset((void*)&bufHelper.get()->tempBufs[chanCnt][len], 0, (framesPerBuffer - len) * sizeof(float)); chanCnt++; } @@ -3952,7 +3946,7 @@ bool AudioIoCallback::FillOutputBuffers( len = mMaxFramesOutput; if( !dropQuickly && selected ) - len = em.RealtimeProcess(group, chanCnt, tempBufs, len); + len = em.RealtimeProcess(group, chanCnt, bufHelper.get()->tempBufs, len); group++; CallbackCheckCompletion(mCallbackReturn, len); @@ -3971,17 +3965,13 @@ bool AudioIoCallback::FillOutputBuffers( // For example mono channels output to both left and right output channels. if (len > 0) for (int c = 0; c < chanCnt; c++) { - vt = chans[c]; + vt = bufHelper.get()->chans[c]; - if (vt->GetChannelIgnoringPan() == Track::LeftChannel || - vt->GetChannelIgnoringPan() == Track::MonoChannel ) - AddToOutputChannel( 0, outputMeterFloats, outputFloats, - tempBufs[c], drop, len, vt); + if (vt->GetChannelIgnoringPan() == Track::LeftChannel || vt->GetChannelIgnoringPan() == Track::MonoChannel ) + AddToOutputChannel( 0, outputMeterFloats, outputFloats, bufHelper.get()->tempBufs[c], drop, len, vt); - if (vt->GetChannelIgnoringPan() == Track::RightChannel || - vt->GetChannelIgnoringPan() == Track::MonoChannel ) - AddToOutputChannel( 1, outputMeterFloats, outputFloats, - tempBufs[c], drop, len, vt); + if (vt->GetChannelIgnoringPan() == Track::RightChannel || vt->GetChannelIgnoringPan() == Track::MonoChannel ) + AddToOutputChannel( 1, outputMeterFloats, outputFloats, bufHelper.get()->tempBufs[c], drop, len, vt); } chanCnt = 0; @@ -4002,8 +3992,6 @@ bool AudioIoCallback::FillOutputBuffers( if (outputMeterFloats != outputFloats) ClampBuffer( outputMeterFloats, framesPerBuffer*numPlaybackChannels ); - delete[] chans; - delete[] tempBufs; return false; } diff --git a/src/AudioIO.h b/src/AudioIO.h index 7f030af98..fb837cc8b 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -580,8 +580,7 @@ protected: PlaybackSchedule mPlaybackSchedule; }; -class AUDACITY_DLL_API AudioIO final - : public AudioIoCallback +class AUDACITY_DLL_API AudioIO final : public AudioIoCallback { AudioIO(); diff --git a/src/AudioIOBufferHelper.h b/src/AudioIOBufferHelper.h new file mode 100644 index 000000000..cf1c95a17 --- /dev/null +++ b/src/AudioIOBufferHelper.h @@ -0,0 +1,42 @@ +#ifndef AUDIOIO_BUFFER_HELPER_H +#define AUDIOIO_BUFFER_HELPER_H + +#include "AudioIO.h" +#include "../libraries/lib-utility/MemoryX.h" + +class AudioIOBufferHelper +{ + + private: + + unsigned int numPlaybackChannels; + unsigned long framesPerBuffer; + + public: + WaveTrack** chans; + float** tempBufs; + + AudioIOBufferHelper(const unsigned int numPlaybackChannels, const unsigned long framesPerBuffer) { + this->numPlaybackChannels = numPlaybackChannels; + this->framesPerBuffer = framesPerBuffer; + + this->chans = safenew WaveTrack * [numPlaybackChannels]; + this->tempBufs = safenew float* [numPlaybackChannels]; + + for (unsigned int c = 0; c < numPlaybackChannels; c++) { + tempBufs[c] = safenew float[framesPerBuffer]; + } + } + + ~AudioIOBufferHelper() { + for (unsigned int c = 0; c < numPlaybackChannels; c++) { + delete[] tempBufs[c]; + } + + delete[] tempBufs; + + delete[] chans; + } +}; + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed4263ec4..2805eb388 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -100,6 +100,7 @@ list( APPEND SOURCES AudioIO.h AudioIOBase.cpp AudioIOBase.h + AudioIOBufferHelper.h AudioIOListener.h AutoRecoveryDialog.cpp AutoRecoveryDialog.h