From 1328921e04e8d07ccf726144ffc14fd10cbd1fa6 Mon Sep 17 00:00:00 2001 From: Adam Scott Date: Mon, 7 Jul 2025 14:44:13 -0400 Subject: [PATCH] [Web] Fix sample playback deletion and `AudioStreamPolyphonic` issue --- platform/web/js/libs/library_godot_audio.js | 21 ++++++++++++--------- scene/resources/audio_stream_polyphonic.cpp | 7 +++++++ servers/audio_server.cpp | 13 +++++++------ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 7f8ddb0aa68..4eb69483edf 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -408,7 +408,7 @@ class SampleNode { * @returns {void} */ static delete(id) { - GodotAudio.sampleNodes.delete(id); + GodotAudio.deleteSampleNode(id); } /** @@ -776,15 +776,9 @@ class SampleNode { } switch (self.getSample().loopMode) { - case 'disabled': { - const id = this.id; + case 'disabled': self.stop(); - if (GodotAudio.sampleFinishedCallback != null) { - const idCharPtr = GodotRuntime.allocString(id); - GodotAudio.sampleFinishedCallback(idCharPtr); - GodotRuntime.free(idCharPtr); - } - } break; + break; case 'forward': case 'backward': self.restart(); @@ -1175,6 +1169,15 @@ const _GodotAudio = { */ sampleNodes: null, SampleNode, + deleteSampleNode: (pSampleNodeId) => { + GodotAudio.sampleNodes.delete(pSampleNodeId); + if (GodotAudio.sampleFinishedCallback == null) { + return; + } + const sampleNodeIdPtr = GodotRuntime.allocString(pSampleNodeId); + GodotAudio.sampleFinishedCallback(sampleNodeIdPtr); + GodotRuntime.free(sampleNodeIdPtr); + }, // `Bus` class /** diff --git a/scene/resources/audio_stream_polyphonic.cpp b/scene/resources/audio_stream_polyphonic.cpp index 5090d41eb48..da9de3a5fdf 100644 --- a/scene/resources/audio_stream_polyphonic.cpp +++ b/scene/resources/audio_stream_polyphonic.cpp @@ -216,6 +216,13 @@ AudioStreamPlaybackPolyphonic::ID AudioStreamPlaybackPolyphonic::play_stream(con : p_playback_type; for (uint32_t i = 0; i < streams.size(); i++) { + if (streams[i].active.is_set() && streams[i].stream_playback->get_is_sample()) { + Ref active_sample_playback = streams[i].stream_playback->get_sample_playback(); + if (active_sample_playback.is_null() || !AudioServer::get_singleton()->is_sample_playback_active(active_sample_playback)) { + streams[i].active.clear(); + } + } + if (!streams[i].active.is_set()) { // Can use this stream, as it's not active. streams[i].stream = p_stream; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 0558c178a05..07d38316496 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1918,12 +1918,13 @@ void AudioServer::start_sample_playback(const Ref &p_playba void AudioServer::stop_sample_playback(const Ref &p_playback) { ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null."); - 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); + if (!sample_playback_list.has(p_playback)) { + return; } + 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 &p_playback, bool p_paused) { @@ -1933,7 +1934,7 @@ void AudioServer::set_sample_playback_pause(const Ref &p_pl bool AudioServer::is_sample_playback_active(const Ref &p_playback) { ERR_FAIL_COND_V_MSG(p_playback.is_null(), false, "Parameter p_playback is null."); - return AudioDriver::get_singleton()->is_sample_playback_active(p_playback); + return sample_playback_list.has(p_playback); } double AudioServer::get_sample_playback_position(const Ref &p_playback) {