Use dummy driver when JS AudioContext is unavailable.

This commit is contained in:
Fabio Alessandrelli 2020-06-29 18:51:53 +02:00
parent 1a637b07b1
commit 7a5e10b8a9
5 changed files with 40 additions and 15 deletions

View File

@ -36,6 +36,15 @@
AudioDriverJavaScript *AudioDriverJavaScript::singleton = nullptr;
bool AudioDriverJavaScript::is_available() {
return EM_ASM_INT({
if (!(window.AudioContext || window.webkitAudioContext)) {
return 0;
}
return 1;
}) != 0;
}
const char *AudioDriverJavaScript::get_name() const {
return "JavaScript";
}
@ -207,12 +216,14 @@ void AudioDriverJavaScript::finish_async() {
/* clang-format off */
EM_ASM({
var ref = Module.IDHandler.get($0);
const id = $0;
var ref = Module.IDHandler.get(id);
Module.async_finish.push(new Promise(function(accept, reject) {
if (!ref) {
console.log("Ref not found!", $0, Module.IDHandler);
console.log("Ref not found!", id, Module.IDHandler);
setTimeout(accept, 0);
} else {
Module.IDHandler.remove(id);
const context = ref['context'];
// Disconnect script and input.
ref['script'].disconnect();
@ -226,7 +237,6 @@ void AudioDriverJavaScript::finish_async() {
});
}
}));
Module.IDHandler.remove($0);
}, id);
/* clang-format on */
}
@ -293,9 +303,5 @@ Error AudioDriverJavaScript::capture_stop() {
}
AudioDriverJavaScript::AudioDriverJavaScript() {
_driver_id = 0;
internal_buffer = nullptr;
buffer_length = 0;
singleton = this;
}

View File

@ -34,12 +34,13 @@
#include "servers/audio_server.h"
class AudioDriverJavaScript : public AudioDriver {
float *internal_buffer;
float *internal_buffer = nullptr;
int _driver_id;
int buffer_length;
int _driver_id = 0;
int buffer_length = 0;
public:
static bool is_available();
void mix_to_js();
void process_capture(float sample);

View File

@ -63,10 +63,17 @@ void main_loop_callback() {
}
if (os->main_loop_iterate()) {
emscripten_cancel_main_loop(); // Cancel current loop and wait for finalize_async.
/* clang-format off */
EM_ASM({
// This will contain the list of operations that need to complete before cleanup.
Module.async_finish = [];
Module.async_finish = [
// Always contains at least one async promise, to avoid firing immediately if nothing is added.
new Promise(function(accept, reject) {
setTimeout(accept, 0);
})
];
});
/* clang-format on */
os->get_main_loop()->finish();
os->finalize_async(); // Will add all the async finish functions.
EM_ASM({

View File

@ -77,7 +77,9 @@ void OS_JavaScript::initialize() {
}
void OS_JavaScript::resume_audio() {
audio_driver_javascript.resume();
if (audio_driver_javascript) {
audio_driver_javascript->resume();
}
}
void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) {
@ -125,11 +127,17 @@ void OS_JavaScript::delete_main_loop() {
void OS_JavaScript::finalize_async() {
finalizing = true;
audio_driver_javascript.finish_async();
if (audio_driver_javascript) {
audio_driver_javascript->finish_async();
}
}
void OS_JavaScript::finalize() {
delete_main_loop();
if (audio_driver_javascript) {
memdelete(audio_driver_javascript);
audio_driver_javascript = nullptr;
}
}
// Miscellaneous
@ -238,7 +246,10 @@ void OS_JavaScript::initialize_joypads() {
}
OS_JavaScript::OS_JavaScript() {
AudioDriverManager::add_driver(&audio_driver_javascript);
if (AudioDriverJavaScript::is_available()) {
audio_driver_javascript = memnew(AudioDriverJavaScript);
AudioDriverManager::add_driver(audio_driver_javascript);
}
Vector<Logger *> loggers;
loggers.push_back(memnew(StdLogger));

View File

@ -40,7 +40,7 @@
class OS_JavaScript : public OS_Unix {
MainLoop *main_loop = nullptr;
AudioDriverJavaScript audio_driver_javascript;
AudioDriverJavaScript *audio_driver_javascript = nullptr;
bool finalizing = false;
bool idb_available = false;