summaryrefslogtreecommitdiffstats
path: root/servers
diff options
context:
space:
mode:
authorAdam Scott <ascott.ca@gmail.com>2024-09-04 12:04:27 -0400
committerRémi Verschelde <rverschelde@gmail.com>2024-09-17 08:57:44 +0200
commit0b815cbb99173e7eefb4448615805ab365d991e8 (patch)
tree205998b196bcfb8c094d514447414cfa62887904 /servers
parentf11f9e3b7fb069033f9f9822226830b99f9adeb0 (diff)
downloadredot-engine-0b815cbb99173e7eefb4448615805ab365d991e8.tar.gz
Fix leak when using audio samples instead of streams
(cherry picked from commit d3ddce6b8836bd6c39dc6ebc2a30102041953599)
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_stream.h1
-rw-r--r--servers/audio_server.cpp48
-rw-r--r--servers/audio_server.h2
3 files changed, 39 insertions, 12 deletions
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index c995fb01ab..4e75666d03 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -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;
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 332f8984a2..e06079efe8 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -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.
@@ -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;
@@ -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;
}
@@ -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);
@@ -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) {
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 2d6fc60860..16fcc029b3 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -297,6 +297,8 @@ private:
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;