[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 b800438efb)
This commit is contained in:
Fabio Alessandrelli 2021-09-13 03:06:34 +02:00 committed by Rémi Verschelde
parent e34c09a705
commit 41b1f2a7f9
No known key found for this signature in database
GPG key ID: C3336907360768E1
5 changed files with 18 additions and 7 deletions

View file

@ -258,6 +258,9 @@
<member name="audio/mix_rate" type="int" setter="" getter="" default="44100"> <member name="audio/mix_rate" type="int" setter="" getter="" default="44100">
Mixing rate used for audio. In general, it's better to not touch this and leave it to the host operating system. Mixing rate used for audio. In general, it's better to not touch this and leave it to the host operating system.
</member> </member>
<member name="audio/mix_rate.web" type="int" setter="" getter="" default="0">
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).
</member>
<member name="audio/output_latency" type="int" setter="" getter="" default="15"> <member name="audio/output_latency" type="int" setter="" getter="" default="15">
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. 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.
</member> </member>

View file

@ -108,7 +108,7 @@ Error AudioDriverJavaScript::init() {
mix_rate = GLOBAL_GET("audio/mix_rate"); mix_rate = GLOBAL_GET("audio/mix_rate");
int latency = GLOBAL_GET("audio/output_latency"); 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)); buffer_length = closest_power_of_2((latency * mix_rate / 1000));
#ifndef NO_THREADS #ifndef NO_THREADS
node = memnew(WorkletNode); node = memnew(WorkletNode);

View file

@ -38,7 +38,7 @@ extern "C" {
#include "stddef.h" #include "stddef.h"
extern int godot_audio_is_available(); 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 void godot_audio_resume();
extern int godot_audio_capture_start(); extern int godot_audio_capture_start();

View file

@ -37,10 +37,14 @@ const GodotAudio = {
interval: 0, interval: 0,
init: function (mix_rate, latency, onstatechange, onlatencyupdate) { init: function (mix_rate, latency, onstatechange, onlatencyupdate) {
const ctx = new (window.AudioContext || window.webkitAudioContext)({ const opts = {};
sampleRate: mix_rate, // If mix_rate is 0, let the browser choose.
// latencyHint: latency / 1000 // Do not specify, leave 'interactive' for good performance. 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; GodotAudio.ctx = ctx;
ctx.onstatechange = function () { ctx.onstatechange = function () {
let state = 0; let state = 0;
@ -159,7 +163,10 @@ const GodotAudio = {
godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) { godot_audio_init: function (p_mix_rate, p_latency, p_state_change, p_latency_update) {
const statechange = GodotRuntime.get_func(p_state_change); const statechange = GodotRuntime.get_func(p_state_change);
const latencyupdate = GodotRuntime.get_func(p_latency_update); 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', godot_audio_resume__sig: 'v',

View file

@ -188,6 +188,7 @@ int AudioDriverManager::get_driver_count() {
void AudioDriverManager::initialize(int p_driver) { void AudioDriverManager::initialize(int p_driver) {
GLOBAL_DEF_RST("audio/enable_audio_input", false); GLOBAL_DEF_RST("audio/enable_audio_input", false);
GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE); 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", DEFAULT_OUTPUT_LATENCY);
GLOBAL_DEF_RST("audio/output_latency.web", 50); // Safer default output_latency for web. GLOBAL_DEF_RST("audio/output_latency.web", 50); // Safer default output_latency for web.