mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-15 15:49:36 +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 "DBConnection.h"
|
||||||
#include "ProjectFileIO.h"
|
#include "ProjectFileIO.h"
|
||||||
#include "WaveTrack.h"
|
#include "WaveTrack.h"
|
||||||
|
#include "AudioIOBufferHelper.h"
|
||||||
|
|
||||||
#include "effects/RealtimeEffectManager.h"
|
#include "effects/RealtimeEffectManager.h"
|
||||||
#include "prefs/QualitySettings.h"
|
#include "prefs/QualitySettings.h"
|
||||||
@ -3843,14 +3844,7 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------ MEMORY ALLOCATION ----------------------
|
// ------ MEMORY ALLOCATION ----------------------
|
||||||
// These are small structures.
|
std::unique_ptr<AudioIOBufferHelper> bufHelper = std::make_unique<AudioIOBufferHelper>(numPlaybackChannels, framesPerBuffer);
|
||||||
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];
|
|
||||||
}
|
|
||||||
// ------ End of MEMORY ALLOCATION ---------------
|
// ------ End of MEMORY ALLOCATION ---------------
|
||||||
|
|
||||||
auto & em = RealtimeEffectManager::Get();
|
auto & em = RealtimeEffectManager::Get();
|
||||||
@ -3882,7 +3876,7 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
for (unsigned t = 0; t < numPlaybackTracks; t++)
|
for (unsigned t = 0; t < numPlaybackTracks; t++)
|
||||||
{
|
{
|
||||||
WaveTrack *vt = mPlaybackTracks[t].get();
|
WaveTrack *vt = mPlaybackTracks[t].get();
|
||||||
chans[chanCnt] = vt;
|
bufHelper.get()->chans[chanCnt] = vt;
|
||||||
|
|
||||||
// TODO: more-than-two-channels
|
// TODO: more-than-two-channels
|
||||||
auto nextTrack =
|
auto nextTrack =
|
||||||
@ -3901,7 +3895,7 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
// IF mono THEN clear 'the other' channel.
|
// IF mono THEN clear 'the other' channel.
|
||||||
if ( lastChannel && (numPlaybackChannels>1)) {
|
if ( lastChannel && (numPlaybackChannels>1)) {
|
||||||
// TODO: more-than-two-channels
|
// TODO: more-than-two-channels
|
||||||
memset(tempBufs[1], 0, framesPerBuffer * sizeof(float));
|
memset(bufHelper.get()->tempBufs[1], 0, framesPerBuffer * sizeof(float));
|
||||||
}
|
}
|
||||||
drop = TrackShouldBeSilent( *vt );
|
drop = TrackShouldBeSilent( *vt );
|
||||||
dropQuickly = drop;
|
dropQuickly = drop;
|
||||||
@ -3920,7 +3914,7 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = mPlaybackBuffers[t]->Get((samplePtr)tempBufs[chanCnt],
|
len = mPlaybackBuffers[t]->Get((samplePtr)bufHelper.get()->tempBufs[chanCnt],
|
||||||
floatSample,
|
floatSample,
|
||||||
toGet);
|
toGet);
|
||||||
// wxASSERT( len == toGet );
|
// wxASSERT( len == toGet );
|
||||||
@ -3931,7 +3925,7 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
// real-time demand in this thread (see bug 1932). We
|
// real-time demand in this thread (see bug 1932). We
|
||||||
// must supply something to the sound card, so pad it with
|
// must supply something to the sound card, so pad it with
|
||||||
// zeroes and not random garbage.
|
// zeroes and not random garbage.
|
||||||
memset((void*)&tempBufs[chanCnt][len], 0,
|
memset((void*)&bufHelper.get()->tempBufs[chanCnt][len], 0,
|
||||||
(framesPerBuffer - len) * sizeof(float));
|
(framesPerBuffer - len) * sizeof(float));
|
||||||
chanCnt++;
|
chanCnt++;
|
||||||
}
|
}
|
||||||
@ -3952,7 +3946,7 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
len = mMaxFramesOutput;
|
len = mMaxFramesOutput;
|
||||||
|
|
||||||
if( !dropQuickly && selected )
|
if( !dropQuickly && selected )
|
||||||
len = em.RealtimeProcess(group, chanCnt, tempBufs, len);
|
len = em.RealtimeProcess(group, chanCnt, bufHelper.get()->tempBufs, len);
|
||||||
group++;
|
group++;
|
||||||
|
|
||||||
CallbackCheckCompletion(mCallbackReturn, len);
|
CallbackCheckCompletion(mCallbackReturn, len);
|
||||||
@ -3971,17 +3965,13 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
// For example mono channels output to both left and right output channels.
|
// For example mono channels output to both left and right output channels.
|
||||||
if (len > 0) for (int c = 0; c < chanCnt; c++)
|
if (len > 0) for (int c = 0; c < chanCnt; c++)
|
||||||
{
|
{
|
||||||
vt = chans[c];
|
vt = bufHelper.get()->chans[c];
|
||||||
|
|
||||||
if (vt->GetChannelIgnoringPan() == Track::LeftChannel ||
|
if (vt->GetChannelIgnoringPan() == Track::LeftChannel || vt->GetChannelIgnoringPan() == Track::MonoChannel )
|
||||||
vt->GetChannelIgnoringPan() == Track::MonoChannel )
|
AddToOutputChannel( 0, outputMeterFloats, outputFloats, bufHelper.get()->tempBufs[c], drop, len, vt);
|
||||||
AddToOutputChannel( 0, outputMeterFloats, outputFloats,
|
|
||||||
tempBufs[c], drop, len, vt);
|
|
||||||
|
|
||||||
if (vt->GetChannelIgnoringPan() == Track::RightChannel ||
|
if (vt->GetChannelIgnoringPan() == Track::RightChannel || vt->GetChannelIgnoringPan() == Track::MonoChannel )
|
||||||
vt->GetChannelIgnoringPan() == Track::MonoChannel )
|
AddToOutputChannel( 1, outputMeterFloats, outputFloats, bufHelper.get()->tempBufs[c], drop, len, vt);
|
||||||
AddToOutputChannel( 1, outputMeterFloats, outputFloats,
|
|
||||||
tempBufs[c], drop, len, vt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chanCnt = 0;
|
chanCnt = 0;
|
||||||
@ -4002,8 +3992,6 @@ bool AudioIoCallback::FillOutputBuffers(
|
|||||||
if (outputMeterFloats != outputFloats)
|
if (outputMeterFloats != outputFloats)
|
||||||
ClampBuffer( outputMeterFloats, framesPerBuffer*numPlaybackChannels );
|
ClampBuffer( outputMeterFloats, framesPerBuffer*numPlaybackChannels );
|
||||||
|
|
||||||
delete[] chans;
|
|
||||||
delete[] tempBufs;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,8 +580,7 @@ protected:
|
|||||||
PlaybackSchedule mPlaybackSchedule;
|
PlaybackSchedule mPlaybackSchedule;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AUDACITY_DLL_API AudioIO final
|
class AUDACITY_DLL_API AudioIO final : public AudioIoCallback
|
||||||
: public AudioIoCallback
|
|
||||||
{
|
{
|
||||||
|
|
||||||
AudioIO();
|
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
|
AudioIO.h
|
||||||
AudioIOBase.cpp
|
AudioIOBase.cpp
|
||||||
AudioIOBase.h
|
AudioIOBase.h
|
||||||
|
AudioIOBufferHelper.h
|
||||||
AudioIOListener.h
|
AudioIOListener.h
|
||||||
AutoRecoveryDialog.cpp
|
AutoRecoveryDialog.cpp
|
||||||
AutoRecoveryDialog.h
|
AutoRecoveryDialog.h
|
||||||
|
Loading…
x
Reference in New Issue
Block a user