Browse Source

[Web] Fix sample playback deletion and `AudioStreamPolyphonic` issue

Adam Scott 1 month ago
parent
commit
1328921e04

+ 12 - 9
platform/web/js/libs/library_godot_audio.js

@@ -408,7 +408,7 @@ class SampleNode {
 	 * @returns {void}
 	 * @returns {void}
 	 */
 	 */
 	static delete(id) {
 	static delete(id) {
-		GodotAudio.sampleNodes.delete(id);
+		GodotAudio.deleteSampleNode(id);
 	}
 	}
 
 
 	/**
 	/**
@@ -776,15 +776,9 @@ class SampleNode {
 			}
 			}
 
 
 			switch (self.getSample().loopMode) {
 			switch (self.getSample().loopMode) {
-			case 'disabled': {
-				const id = this.id;
+			case 'disabled':
 				self.stop();
 				self.stop();
-				if (GodotAudio.sampleFinishedCallback != null) {
-					const idCharPtr = GodotRuntime.allocString(id);
-					GodotAudio.sampleFinishedCallback(idCharPtr);
-					GodotRuntime.free(idCharPtr);
-				}
-			} break;
+				break;
 			case 'forward':
 			case 'forward':
 			case 'backward':
 			case 'backward':
 				self.restart();
 				self.restart();
@@ -1175,6 +1169,15 @@ const _GodotAudio = {
 		 */
 		 */
 		sampleNodes: null,
 		sampleNodes: null,
 		SampleNode,
 		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
 		// `Bus` class
 		/**
 		/**

+ 7 - 0
scene/resources/audio_stream_polyphonic.cpp

@@ -216,6 +216,13 @@ AudioStreamPlaybackPolyphonic::ID AudioStreamPlaybackPolyphonic::play_stream(con
 			: p_playback_type;
 			: p_playback_type;
 
 
 	for (uint32_t i = 0; i < streams.size(); i++) {
 	for (uint32_t i = 0; i < streams.size(); i++) {
+		if (streams[i].active.is_set() && streams[i].stream_playback->get_is_sample()) {
+			Ref<AudioSamplePlayback> 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()) {
 		if (!streams[i].active.is_set()) {
 			// Can use this stream, as it's not active.
 			// Can use this stream, as it's not active.
 			streams[i].stream = p_stream;
 			streams[i].stream = p_stream;

+ 7 - 6
servers/audio_server.cpp

@@ -1918,12 +1918,13 @@ void AudioServer::start_sample_playback(const Ref<AudioSamplePlayback> &p_playba
 
 
 void AudioServer::stop_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
 void AudioServer::stop_sample_playback(const Ref<AudioSamplePlayback> &p_playback) {
 	ERR_FAIL_COND_MSG(p_playback.is_null(), "Parameter p_playback is null.");
 	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<AudioSamplePlayback> &p_playback, bool p_paused) {
 void AudioServer::set_sample_playback_pause(const Ref<AudioSamplePlayback> &p_playback, bool p_paused) {
@@ -1933,7 +1934,7 @@ void AudioServer::set_sample_playback_pause(const Ref<AudioSamplePlayback> &p_pl
 
 
 bool AudioServer::is_sample_playback_active(const Ref<AudioSamplePlayback> &p_playback) {
 bool AudioServer::is_sample_playback_active(const Ref<AudioSamplePlayback> &p_playback) {
 	ERR_FAIL_COND_V_MSG(p_playback.is_null(), false, "Parameter p_playback is null.");
 	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<AudioSamplePlayback> &p_playback) {
 double AudioServer::get_sample_playback_position(const Ref<AudioSamplePlayback> &p_playback) {