From 41b1f2a7f91cfbdb02c7176cb176fea2f4af12b0 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 13 Sep 2021 03:06:34 +0200 Subject: [PATCH] [HTML5] Use browser mix rate by default on the Web. Browsers doesn't really like forcing the mix rate, e.g. Firefox does not allow input (microphone) if the mix rate is not the default one, Chrom* will exhibit worse performances, etc. (cherry picked from commit b800438efbc7ebd99c16ad315225a1ba24a6b4ee) --- doc/classes/ProjectSettings.xml | 3 +++ platform/javascript/audio_driver_javascript.cpp | 2 +- platform/javascript/godot_audio.h | 2 +- .../javascript/js/libs/library_godot_audio.js | 17 ++++++++++++----- servers/audio_server.cpp | 1 + 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3d14bc1edc..2993f41dc8 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -258,6 +258,9 @@ Mixing rate used for audio. In general, it's better to not touch this and leave it to the host operating system. + + Safer override for [member audio/mix_rate] in the Web platform. Here [code]0[/code] means "let the browser choose" (since some browsers do not like forcing the mix rate). + Output latency in milliseconds for audio. Lower values will result in lower audio latency at the cost of increased CPU usage. Low values may result in audible cracking on slower hardware. diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index c65d9425e1..1b68542384 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -108,7 +108,7 @@ Error AudioDriverJavaScript::init() { mix_rate = GLOBAL_GET("audio/mix_rate"); int latency = GLOBAL_GET("audio/output_latency"); - channel_count = godot_audio_init(mix_rate, latency, &_state_change_callback, &_latency_update_callback); + channel_count = godot_audio_init(&mix_rate, latency, &_state_change_callback, &_latency_update_callback); buffer_length = closest_power_of_2((latency * mix_rate / 1000)); #ifndef NO_THREADS node = memnew(WorkletNode); diff --git a/platform/javascript/godot_audio.h b/platform/javascript/godot_audio.h index 54fc8fa3b5..de8f046bbd 100644 --- a/platform/javascript/godot_audio.h +++ b/platform/javascript/godot_audio.h @@ -38,7 +38,7 @@ extern "C" { #include "stddef.h" extern int godot_audio_is_available(); -extern int godot_audio_init(int p_mix_rate, int p_latency, void (*_state_cb)(int), void (*_latency_cb)(float)); +extern int godot_audio_init(int *p_mix_rate, int p_latency, void (*_state_cb)(int), void (*_latency_cb)(float)); extern void godot_audio_resume(); extern int godot_audio_capture_start(); diff --git a/platform/javascript/js/libs/library_godot_audio.js b/platform/javascript/js/libs/library_godot_audio.js index 45c3a3fe2e..c9dae1a7af 100644 --- a/platform/javascript/js/libs/library_godot_audio.js +++ b/platform/javascript/js/libs/library_godot_audio.js @@ -37,10 +37,14 @@ const GodotAudio = { interval: 0, init: function (mix_rate, latency, onstatechange, onlatencyupdate) { - const ctx = new (window.AudioContext || window.webkitAudioContext)({ - sampleRate: mix_rate, - // latencyHint: latency / 1000 // Do not specify, leave 'interactive' for good performance. - }); + const opts = {}; + // If mix_rate is 0, let the browser choose. + if (mix_rate) { + opts['sampleRate'] = mix_rate; + } + // Do not specify, leave 'interactive' for good performance. + // opts['latencyHint'] = latency / 1000; + const ctx = new (window.AudioContext || window.webkitAudioContext)(opts); GodotAudio.ctx = ctx; ctx.onstatechange = function () { let state = 0; @@ -159,7 +163,10 @@ const GodotAudio = { godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) { const statechange = GodotRuntime.get_func(p_state_change); const latencyupdate = GodotRuntime.get_func(p_latency_update); - return GodotAudio.init(p_mix_rate, p_latency, statechange, latencyupdate); + const mix_rate = GodotRuntime.getHeapValue(p_mix_rate, 'i32'); + const channels = GodotAudio.init(mix_rate, p_latency, statechange, latencyupdate); + GodotRuntime.setHeapValue(p_mix_rate, GodotAudio.ctx.sampleRate, 'i32'); + return channels; }, godot_audio_resume__sig: 'v', diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 1a78f47963..1a72190d7c 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -188,6 +188,7 @@ int AudioDriverManager::get_driver_count() { void AudioDriverManager::initialize(int p_driver) { GLOBAL_DEF_RST("audio/enable_audio_input", false); GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE); + GLOBAL_DEF_RST("audio/mix_rate.web", 0); // Safer default output_latency for web (use browser default). GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY); GLOBAL_DEF_RST("audio/output_latency.web", 50); // Safer default output_latency for web.