summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-07-07 21:59:00 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-07-07 21:59:00 +0200
commit42e5b3ac2da07d2105c775977b39e6949c723ded (patch)
treeb606333aa73d829c0032f889c90cc6e5ca11211e
parent56df419874a3af9bbfb4ba22816ce05cca6e4850 (diff)
parenta38f30fbd5bc4aeb55c749768111a37370ebd99e (diff)
downloadredot-engine-42e5b3ac2da07d2105c775977b39e6949c723ded.tar.gz
Merge pull request #94044 from adamscott/fix-web-sample-playback-finished-signal
Fix Web samples finished missing signal
-rw-r--r--platform/web/audio_driver_web.cpp32
-rw-r--r--platform/web/audio_driver_web.h1
-rw-r--r--platform/web/godot_audio.h1
-rw-r--r--platform/web/js/libs/library_godot_audio.js27
-rw-r--r--scene/audio/audio_stream_player_internal.cpp1
-rw-r--r--servers/audio/audio_stream.h1
6 files changed, 61 insertions, 2 deletions
diff --git a/platform/web/audio_driver_web.cpp b/platform/web/audio_driver_web.cpp
index dd986e650c..b24c6cb1fd 100644
--- a/platform/web/audio_driver_web.cpp
+++ b/platform/web/audio_driver_web.cpp
@@ -33,6 +33,8 @@
#include "godot_audio.h"
#include "core/config/project_settings.h"
+#include "core/object/object.h"
+#include "scene/main/node.h"
#include "servers/audio/audio_stream.h"
#include <emscripten.h>
@@ -51,6 +53,33 @@ void AudioDriverWeb::_latency_update_callback(float p_latency) {
AudioDriverWeb::audio_context.output_latency = p_latency;
}
+void AudioDriverWeb::_sample_playback_finished_callback(const char *p_playback_object_id) {
+ const ObjectID playback_id = ObjectID(String::to_int(p_playback_object_id));
+
+ Object *playback_object = ObjectDB::get_instance(playback_id);
+ if (playback_object == nullptr) {
+ return;
+ }
+ Ref<AudioSamplePlayback> playback = Object::cast_to<AudioSamplePlayback>(playback_object);
+ if (playback.is_null()) {
+ return;
+ }
+
+ Object *player_object = ObjectDB::get_instance(playback->player_id);
+ if (player_object == nullptr) {
+ return;
+ }
+ Node *player = Object::cast_to<Node>(player_object);
+ if (player == nullptr) {
+ return;
+ }
+
+ const StringName finished = SNAME("finished");
+ if (player->has_signal(finished)) {
+ player->emit_signal(finished);
+ }
+}
+
void AudioDriverWeb::_audio_driver_process(int p_from, int p_samples) {
int32_t *stream_buffer = reinterpret_cast<int32_t *>(output_rb);
const int max_samples = memarr_len(output_rb);
@@ -132,6 +161,9 @@ Error AudioDriverWeb::init() {
if (!input_rb) {
return ERR_OUT_OF_MEMORY;
}
+
+ godot_audio_sample_set_finished_callback(&_sample_playback_finished_callback);
+
return OK;
}
diff --git a/platform/web/audio_driver_web.h b/platform/web/audio_driver_web.h
index 298ad90fae..46c5ce4de1 100644
--- a/platform/web/audio_driver_web.h
+++ b/platform/web/audio_driver_web.h
@@ -58,6 +58,7 @@ private:
WASM_EXPORT static void _state_change_callback(int p_state);
WASM_EXPORT static void _latency_update_callback(float p_latency);
+ WASM_EXPORT static void _sample_playback_finished_callback(const char *p_playback_object_id);
static AudioDriverWeb *singleton;
diff --git a/platform/web/godot_audio.h b/platform/web/godot_audio.h
index 8bebbcf7de..dd5bec00cf 100644
--- a/platform/web/godot_audio.h
+++ b/platform/web/godot_audio.h
@@ -57,6 +57,7 @@ extern void godot_audio_sample_set_pause(const char *p_playback_object_id, bool
extern int godot_audio_sample_is_active(const char *p_playback_object_id);
extern void godot_audio_sample_update_pitch_scale(const char *p_playback_object_id, float p_pitch_scale);
extern void godot_audio_sample_set_volumes_linear(const char *p_playback_object_id, int *p_buses_buf, int p_buses_size, float *p_volumes_buf, int p_volumes_size);
+extern void godot_audio_sample_set_finished_callback(void (*p_callback)(const char *));
extern void godot_audio_sample_bus_set_count(int p_count);
extern void godot_audio_sample_bus_remove(int p_index);
diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js
index 531dbdaeab..0b16b07261 100644
--- a/platform/web/js/libs/library_godot_audio.js
+++ b/platform/web/js/libs/library_godot_audio.js
@@ -687,9 +687,15 @@ class SampleNode {
}
switch (self.getSample().loopMode) {
- case 'disabled':
+ case 'disabled': {
+ const id = this.id;
self.stop();
- break;
+ if (GodotAudio.sampleFinishedCallback != null) {
+ const idCharPtr = GodotRuntime.allocString(id);
+ GodotAudio.sampleFinishedCallback(idCharPtr);
+ GodotRuntime.free(idCharPtr);
+ }
+ } break;
case 'forward':
case 'backward':
self.restart();
@@ -1090,6 +1096,12 @@ const _GodotAudio = {
busSolo: null,
Bus,
+ /**
+ * Callback to signal that a sample has finished.
+ * @type {(playbackObjectIdPtr: number) => void | null}
+ */
+ sampleFinishedCallback: null,
+
/** @type {AudioContext} */
ctx: null,
input: null,
@@ -1764,6 +1776,17 @@ const _GodotAudio = {
godot_audio_sample_bus_set_mute: function (bus, enable) {
GodotAudio.set_sample_bus_mute(bus, Boolean(enable));
},
+
+ godot_audio_sample_set_finished_callback__proxy: 'sync',
+ godot_audio_sample_set_finished_callback__sig: 'vi',
+ /**
+ * Sets the finished callback
+ * @param {Number} callbackPtr Finished callback pointer
+ * @returns {void}
+ */
+ godot_audio_sample_set_finished_callback: function (callbackPtr) {
+ GodotAudio.sampleFinishedCallback = GodotRuntime.get_func(callbackPtr);
+ },
};
autoAddDeps(_GodotAudio, '$GodotAudio');
diff --git a/scene/audio/audio_stream_player_internal.cpp b/scene/audio/audio_stream_player_internal.cpp
index b3a55ddee0..6653e01f25 100644
--- a/scene/audio/audio_stream_player_internal.cpp
+++ b/scene/audio/audio_stream_player_internal.cpp
@@ -152,6 +152,7 @@ Ref<AudioStreamPlayback> AudioStreamPlayerInternal::play_basic() {
Ref<AudioSamplePlayback> sample_playback;
sample_playback.instantiate();
sample_playback->stream = stream;
+ sample_playback->player_id = node->get_instance_id();
stream_playback->set_sample_playback(sample_playback);
}
} else if (!stream->is_meta_stream()) {
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 0ca4777d5c..9149109381 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -49,6 +49,7 @@ class AudioSamplePlayback : public RefCounted {
public:
Ref<AudioStream> stream;
+ ObjectID player_id;
float offset = 0.0f;
Vector<AudioFrame> volume_vector;
StringName bus;