mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Fix Web samples finished missing signal
This commit is contained in:
parent
f3af22b10b
commit
a38f30fbd5
6 changed files with 61 additions and 2 deletions
|
@ -33,6 +33,8 @@
|
||||||
#include "godot_audio.h"
|
#include "godot_audio.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
|
#include "core/object/object.h"
|
||||||
|
#include "scene/main/node.h"
|
||||||
#include "servers/audio/audio_stream.h"
|
#include "servers/audio/audio_stream.h"
|
||||||
|
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
|
@ -51,6 +53,33 @@ void AudioDriverWeb::_latency_update_callback(float p_latency) {
|
||||||
AudioDriverWeb::audio_context.output_latency = 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) {
|
void AudioDriverWeb::_audio_driver_process(int p_from, int p_samples) {
|
||||||
int32_t *stream_buffer = reinterpret_cast<int32_t *>(output_rb);
|
int32_t *stream_buffer = reinterpret_cast<int32_t *>(output_rb);
|
||||||
const int max_samples = memarr_len(output_rb);
|
const int max_samples = memarr_len(output_rb);
|
||||||
|
@ -132,6 +161,9 @@ Error AudioDriverWeb::init() {
|
||||||
if (!input_rb) {
|
if (!input_rb) {
|
||||||
return ERR_OUT_OF_MEMORY;
|
return ERR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
godot_audio_sample_set_finished_callback(&_sample_playback_finished_callback);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ private:
|
||||||
|
|
||||||
WASM_EXPORT static void _state_change_callback(int p_state);
|
WASM_EXPORT static void _state_change_callback(int p_state);
|
||||||
WASM_EXPORT static void _latency_update_callback(float p_latency);
|
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;
|
static AudioDriverWeb *singleton;
|
||||||
|
|
||||||
|
|
|
@ -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 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_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_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_set_count(int p_count);
|
||||||
extern void godot_audio_sample_bus_remove(int p_index);
|
extern void godot_audio_sample_bus_remove(int p_index);
|
||||||
|
|
|
@ -687,9 +687,15 @@ class SampleNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (self.getSample().loopMode) {
|
switch (self.getSample().loopMode) {
|
||||||
case 'disabled':
|
case 'disabled': {
|
||||||
|
const id = this.id;
|
||||||
self.stop();
|
self.stop();
|
||||||
break;
|
if (GodotAudio.sampleFinishedCallback != null) {
|
||||||
|
const idCharPtr = GodotRuntime.allocString(id);
|
||||||
|
GodotAudio.sampleFinishedCallback(idCharPtr);
|
||||||
|
GodotRuntime.free(idCharPtr);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case 'forward':
|
case 'forward':
|
||||||
case 'backward':
|
case 'backward':
|
||||||
self.restart();
|
self.restart();
|
||||||
|
@ -1090,6 +1096,12 @@ const _GodotAudio = {
|
||||||
busSolo: null,
|
busSolo: null,
|
||||||
Bus,
|
Bus,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to signal that a sample has finished.
|
||||||
|
* @type {(playbackObjectIdPtr: number) => void | null}
|
||||||
|
*/
|
||||||
|
sampleFinishedCallback: null,
|
||||||
|
|
||||||
/** @type {AudioContext} */
|
/** @type {AudioContext} */
|
||||||
ctx: null,
|
ctx: null,
|
||||||
input: null,
|
input: null,
|
||||||
|
@ -1764,6 +1776,17 @@ const _GodotAudio = {
|
||||||
godot_audio_sample_bus_set_mute: function (bus, enable) {
|
godot_audio_sample_bus_set_mute: function (bus, enable) {
|
||||||
GodotAudio.set_sample_bus_mute(bus, Boolean(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');
|
autoAddDeps(_GodotAudio, '$GodotAudio');
|
||||||
|
|
|
@ -152,6 +152,7 @@ Ref<AudioStreamPlayback> AudioStreamPlayerInternal::play_basic() {
|
||||||
Ref<AudioSamplePlayback> sample_playback;
|
Ref<AudioSamplePlayback> sample_playback;
|
||||||
sample_playback.instantiate();
|
sample_playback.instantiate();
|
||||||
sample_playback->stream = stream;
|
sample_playback->stream = stream;
|
||||||
|
sample_playback->player_id = node->get_instance_id();
|
||||||
stream_playback->set_sample_playback(sample_playback);
|
stream_playback->set_sample_playback(sample_playback);
|
||||||
}
|
}
|
||||||
} else if (!stream->is_meta_stream()) {
|
} else if (!stream->is_meta_stream()) {
|
||||||
|
|
|
@ -49,6 +49,7 @@ class AudioSamplePlayback : public RefCounted {
|
||||||
public:
|
public:
|
||||||
Ref<AudioStream> stream;
|
Ref<AudioStream> stream;
|
||||||
|
|
||||||
|
ObjectID player_id;
|
||||||
float offset = 0.0f;
|
float offset = 0.0f;
|
||||||
Vector<AudioFrame> volume_vector;
|
Vector<AudioFrame> volume_vector;
|
||||||
StringName bus;
|
StringName bus;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue