1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

feat(audio): don't use dynamic memory allocation and remove resource leak

This commit is contained in:
sudden6 2017-04-12 00:10:55 +02:00
parent d33b7eb76d
commit b68ad4ced2
No known key found for this signature in database
GPG Key ID: 279509B499E032B9

View File

@ -119,8 +119,13 @@ private:
*
* @var Audio::AUDIO_CHANNELS
* @brief Ideally, we'd auto-detect, but that's a sane default
*
* @var BUFFER_COUNT
* @brief Number of buffers to use per audio source
*/
static const unsigned int BUFFER_COUNT = 16;
/**
* @brief Returns the singleton instance.
*/
@ -480,32 +485,35 @@ void Audio::playAudioBuffer(ALuint alSource, const int16_t* data, int samples, u
if (!(alOutDev && outputInitialized))
return;
ALuint bufid;
ALint processed = 0, queued = 16;
ALuint bufids[BUFFER_COUNT];
ALint processed = 0, queued = 0;
alGetSourcei(alSource, AL_BUFFERS_PROCESSED, &processed);
alGetSourcei(alSource, AL_BUFFERS_QUEUED, &queued);
alSourcei(alSource, AL_LOOPING, AL_FALSE);
if (processed) {
ALuint* bufids = new ALuint[processed];
alSourceUnqueueBuffers(alSource, processed, bufids);
alDeleteBuffers(processed - 1, bufids + 1);
bufid = bufids[0];
delete[] bufids;
} else if (queued < 16) {
alGenBuffers(1, &bufid);
if (processed == 0) {
if (queued >= BUFFER_COUNT) {
// reached limit, drop audio
return;
}
// create new buffer if none got free and we're below the limit
alGenBuffers(1, bufids);
} else {
return;
// unqueue all processed buffers
alSourceUnqueueBuffers(alSource, processed, bufids);
// delete all but the first buffer, reuse first for new data
alDeleteBuffers(processed - 1, bufids + 1);
}
alBufferData(bufid, (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data,
alBufferData(bufids[0], (channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, data,
samples * 2 * channels, sampleRate);
alSourceQueueBuffers(alSource, 1, &bufid);
alSourceQueueBuffers(alSource, 1, bufids);
ALint state;
alGetSourcei(alSource, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING)
if (state != AL_PLAYING) {
alSourcePlay(alSource);
}
}
/**
@ -671,6 +679,16 @@ void Audio::unsubscribeOutput(ALuint& sid)
if (sid) {
if (alIsSource(sid)) {
// stop playing, marks all buffers as processed
alSourceStop(sid);
// unqueue all buffers from the source
ALint processed = 0;
alGetSourcei(sid, AL_BUFFERS_PROCESSED, &processed);
ALuint* bufids = new ALuint[processed];
alSourceUnqueueBuffers(sid, processed, bufids);
// delete all buffers
alDeleteBuffers(processed, bufids);
delete[] bufids;
alDeleteSources(1, &sid);
qDebug() << "Audio source" << sid << "deleted. Sources active:" << outSources.size();
} else {