mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-15 07:40:23 +02:00
Fix memory leak from alloca
fix
* Rework `alloca` fix to use new helper class for buffer allocations. * Add missing `delete[]` for cleanup of the temporary playback buffer. Signed-off-by: Emily Mabrey <emabrey@tenacityaudio.org> Reference-to: https://github.com/tenacityteam/tenacity/issues/416 Reference-to: https://github.com/tenacityteam/tenacity/pull/412 Helped-by: Paul Licameli
This commit is contained in:
parent
cabd66d8e7
commit
3e4a2cf316
@ -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<AudioIOBufferHelper> bufHelper = std::make_unique<AudioIOBufferHelper>(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;
|
||||
}
|
||||
|
||||
|
@ -580,8 +580,7 @@ protected:
|
||||
PlaybackSchedule mPlaybackSchedule;
|
||||
};
|
||||
|
||||
class AUDACITY_DLL_API AudioIO final
|
||||
: public AudioIoCallback
|
||||
class AUDACITY_DLL_API AudioIO final : public AudioIoCallback
|
||||
{
|
||||
|
||||
AudioIO();
|
||||
|
42
src/AudioIOBufferHelper.h
Normal file
42
src/AudioIOBufferHelper.h
Normal file
@ -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
|
@ -100,6 +100,7 @@ list( APPEND SOURCES
|
||||
AudioIO.h
|
||||
AudioIOBase.cpp
|
||||
AudioIOBase.h
|
||||
AudioIOBufferHelper.h
|
||||
AudioIOListener.h
|
||||
AutoRecoveryDialog.cpp
|
||||
AutoRecoveryDialog.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user