Skip to content

Commit

Permalink
Fix leak when using audio samples instead of streams
Browse files Browse the repository at this point in the history
  • Loading branch information
adamscott committed Sep 4, 2024
1 parent e2dd56b commit d3ddce6
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 12 deletions.
3 changes: 3 additions & 0 deletions modules/minimp3/audio_stream_mp3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ Ref<AudioSamplePlayback> AudioStreamPlaybackMP3::get_sample_playback() const {

void AudioStreamPlaybackMP3::set_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
sample_playback = p_playback;
if (sample_playback.is_valid()) {
sample_playback->stream_playback = Ref<AudioStreamPlayback>(this);
}
}

void AudioStreamPlaybackMP3::set_parameter(const StringName &p_name, const Variant &p_value) {
Expand Down
3 changes: 3 additions & 0 deletions modules/vorbis/audio_stream_ogg_vorbis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ Ref<AudioSamplePlayback> AudioStreamPlaybackOggVorbis::get_sample_playback() con

void AudioStreamPlaybackOggVorbis::set_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
sample_playback = p_playback;
if (sample_playback.is_valid()) {
sample_playback->stream_playback = Ref<AudioStreamPlayback>(this);
}
}

AudioStreamPlaybackOggVorbis::~AudioStreamPlaybackOggVorbis() {
Expand Down
3 changes: 3 additions & 0 deletions scene/animation/animation_mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,9 @@ void AnimationMixer::_blend_process(double p_delta, bool p_update_only) {
}

if (t_obj->call(SNAME("get_is_sample"))) {
if (t->audio_stream_playback->get_sample_playback().is_valid()) {
AudioServer::get_singleton()->stop_sample_playback(t->audio_stream_playback->get_sample_playback());
}
Ref<AudioSamplePlayback> sample_playback;
sample_playback.instantiate();
sample_playback->stream = stream;
Expand Down
8 changes: 8 additions & 0 deletions scene/resources/audio_stream_polyphonic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ AudioStreamPlaybackPolyphonic::ID AudioStreamPlaybackPolyphonic::play_stream(con
sp->volume_vector.write[2] = AudioFrame(linear_volume, linear_volume);
sp->volume_vector.write[3] = AudioFrame(linear_volume, linear_volume);
sp->bus = p_bus;

if (streams[i].stream_playback->get_sample_playback().is_valid()) {
AudioServer::get_singleton()->stop_playback_stream(sp);
}

streams[i].stream_playback->set_sample_playback(sp);
AudioServer::get_singleton()->start_sample_playback(sp);
}
Expand Down Expand Up @@ -315,6 +320,9 @@ Ref<AudioSamplePlayback> AudioStreamPlaybackPolyphonic::get_sample_playback() co

void AudioStreamPlaybackPolyphonic::set_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
sample_playback = p_playback;
if (sample_playback.is_valid()) {
sample_playback->stream_playback = Ref<AudioStreamPlayback>(this);
}
}

void AudioStreamPlaybackPolyphonic::_bind_methods() {
Expand Down
3 changes: 3 additions & 0 deletions scene/resources/audio_stream_wav.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,9 @@ Ref<AudioSamplePlayback> AudioStreamPlaybackWAV::get_sample_playback() const {

void AudioStreamPlaybackWAV::set_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
sample_playback = p_playback;
if (sample_playback.is_valid()) {
sample_playback->stream_playback = Ref<AudioStreamPlayback>(this);
}
}

AudioStreamPlaybackWAV::AudioStreamPlaybackWAV() {}
Expand Down
1 change: 1 addition & 0 deletions servers/audio/audio_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class AudioSamplePlayback : public RefCounted {

public:
Ref<AudioStream> stream;
Ref<AudioStreamPlayback> stream_playback;

float offset = 0.0f;
float pitch_scale = 1.0;
Expand Down
48 changes: 36 additions & 12 deletions servers/audio_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,7 @@ void AudioServer::_mix_step() {
switch (playback->state.load()) {
case AudioStreamPlaybackListNode::AWAITING_DELETION:
case AudioStreamPlaybackListNode::FADE_OUT_TO_DELETION:
playback_list.erase(playback, [](AudioStreamPlaybackListNode *p) {
delete p->prev_bus_details;
delete p->bus_details.load();
p->stream_playback.unref();
delete p;
});
_delete_stream_playback_list_node(playback);
break;
case AudioStreamPlaybackListNode::FADE_OUT_TO_PAUSE: {
// Pause the stream.
Expand Down Expand Up @@ -697,6 +692,23 @@ AudioServer::AudioStreamPlaybackListNode *AudioServer::_find_playback_list_node(
return nullptr;
}

void AudioServer::_delete_stream_playback(Ref<AudioStreamPlayback> p_playback) {
ERR_FAIL_COND(p_playback.is_null());
AudioStreamPlaybackListNode *playback_node = _find_playback_list_node(p_playback);
if (playback_node) {
_delete_stream_playback_list_node(playback_node);
}
}

void AudioServer::_delete_stream_playback_list_node(AudioStreamPlaybackListNode *p_playback_node) {
playback_list.erase(p_playback_node, [](AudioStreamPlaybackListNode *p) {
delete p->prev_bus_details;
delete p->bus_details.load();
p->stream_playback.unref();
delete p;
});
}

bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const {
if (p_bus < 0 || p_bus >= buses.size()) {
return false;
Expand Down Expand Up @@ -1227,8 +1239,12 @@ void AudioServer::stop_playback_stream(Ref<AudioStreamPlayback> p_playback) {
ERR_FAIL_COND(p_playback.is_null());

// Handle sample playback.
if (p_playback->get_is_sample() && p_playback->get_sample_playback().is_valid()) {
AudioServer::get_singleton()->stop_sample_playback(p_playback->get_sample_playback());
if (p_playback->get_is_sample()) {
if (p_playback->get_sample_playback().is_valid()) {
AudioServer::get_singleton()->stop_sample_playback(p_playback->get_sample_playback());
} else {
_delete_stream_playback(p_playback);
}
return;
}

Expand Down Expand Up @@ -1370,8 +1386,12 @@ void AudioServer::set_playback_highshelf_params(Ref<AudioStreamPlayback> p_playb
bool AudioServer::is_playback_active(Ref<AudioStreamPlayback> p_playback) {
ERR_FAIL_COND_V(p_playback.is_null(), false);

if (p_playback->get_is_sample() && p_playback->get_sample_playback().is_valid()) {
return sample_playback_list.has(p_playback->get_sample_playback());
if (p_playback->get_is_sample()) {
if (p_playback->get_sample_playback().is_valid()) {
return sample_playback_list.has(p_playback->get_sample_playback());
} else {
return false;
}
}

AudioStreamPlaybackListNode *playback_node = _find_playback_list_node(p_playback);
Expand Down Expand Up @@ -1845,8 +1865,12 @@ void AudioServer::start_sample_playback(const Ref<AudioSamplePlayback> &p_playba

void AudioServer::stop_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null.");
AudioDriver::get_singleton()->stop_sample_playback(p_playback);
sample_playback_list.erase(p_playback);
if (sample_playback_list.has(p_playback)) {
sample_playback_list.erase(p_playback);
AudioDriver::get_singleton()->stop_sample_playback(p_playback);
p_playback->stream_playback->set_sample_playback(nullptr);
stop_playback_stream(p_playback->stream_playback);
}
}

void AudioServer::set_sample_playback_pause(const Ref<AudioSamplePlayback> &p_playback, bool p_paused) {
Expand Down
2 changes: 2 additions & 0 deletions servers/audio_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ class AudioServer : public Object {

SafeList<AudioStreamPlaybackListNode *> playback_list;
SafeList<AudioStreamPlaybackBusDetails *> bus_details_graveyard;
void _delete_stream_playback(Ref<AudioStreamPlayback> p_playback);
void _delete_stream_playback_list_node(AudioStreamPlaybackListNode *p_node);

// TODO document if this is necessary.
SafeList<AudioStreamPlaybackBusDetails *> bus_details_graveyard_frame_old;
Expand Down

0 comments on commit d3ddce6

Please sign in to comment.