AudioDriverJavaScript now compute buffer size.

Based on mix rate and expected latency.
This commit is contained in:
Fabio Alessandrelli 2020-05-18 02:19:35 +02:00
parent d4599fff68
commit 245c179bd3
2 changed files with 34 additions and 14 deletions

View File

@ -30,6 +30,8 @@
#include "audio_driver_javascript.h" #include "audio_driver_javascript.h"
#include "core/project_settings.h"
#include <emscripten.h> #include <emscripten.h>
AudioDriverJavaScript *AudioDriverJavaScript::singleton = nullptr; AudioDriverJavaScript *AudioDriverJavaScript::singleton = nullptr;
@ -62,10 +64,15 @@ void AudioDriverJavaScript::process_capture(float sample) {
} }
Error AudioDriverJavaScript::init() { Error AudioDriverJavaScript::init() {
int mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
/* clang-format off */ /* clang-format off */
_driver_id = EM_ASM_INT({ _driver_id = EM_ASM_INT({
const MIX_RATE = $0;
const LATENCY = $1;
return Module.IDHandler.add({ return Module.IDHandler.add({
'context': new (window.AudioContext || window.webkitAudioContext), 'context': new (window.AudioContext || window.webkitAudioContext)({ sampleRate: MIX_RATE, latencyHint: LATENCY}),
'input': null, 'input': null,
'stream': null, 'stream': null,
'script': null 'script': null
@ -74,26 +81,19 @@ Error AudioDriverJavaScript::init() {
/* clang-format on */ /* clang-format on */
int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode()); int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
buffer_length = closest_power_of_2((latency * mix_rate / 1000) * channel_count);
/* clang-format off */ /* clang-format off */
buffer_length = EM_ASM_INT({ buffer_length = EM_ASM_INT({
var ref = Module.IDHandler.get($0); var ref = Module.IDHandler.get($0);
var ctx = ref['context']; const ctx = ref['context'];
var CHANNEL_COUNT = $1; const BUFFER_LENGTH = $1;
const CHANNEL_COUNT = $2;
var channelCount = ctx.destination.channelCount; var script = ctx.createScriptProcessor(BUFFER_LENGTH, 2, CHANNEL_COUNT);
var script = null;
try {
// Try letting the browser recommend a buffer length.
script = ctx.createScriptProcessor(0, 2, channelCount);
} catch (e) {
// ...otherwise, default to 4096.
script = ctx.createScriptProcessor(4096, 2, channelCount);
}
script.connect(ctx.destination); script.connect(ctx.destination);
ref['script'] = script; ref['script'] = script;
return script.bufferSize; return script.bufferSize;
}, _driver_id, channel_count); }, _driver_id, buffer_length, channel_count);
/* clang-format on */ /* clang-format on */
if (!buffer_length) { if (!buffer_length) {
return FAILED; return FAILED;
@ -156,6 +156,25 @@ void AudioDriverJavaScript::resume() {
/* clang-format on */ /* clang-format on */
} }
float AudioDriverJavaScript::get_latency() {
/* clang-format off */
return EM_ASM_DOUBLE({
const ref = Module.IDHandler.get($0);
var latency = 0;
if (ref && ref['context']) {
const ctx = ref['context'];
if (ctx.baseLatency) {
latency += ctx.baseLatency;
}
if (ctx.outputLatency) {
latency += ctx.outputLatency;
}
}
return latency;
}, _driver_id);
/* clang-format on */
}
int AudioDriverJavaScript::get_mix_rate() const { int AudioDriverJavaScript::get_mix_rate() const {
/* clang-format off */ /* clang-format off */
return EM_ASM_INT({ return EM_ASM_INT({

View File

@ -50,6 +50,7 @@ public:
virtual Error init(); virtual Error init();
virtual void start(); virtual void start();
void resume(); void resume();
virtual float get_latency();
virtual int get_mix_rate() const; virtual int get_mix_rate() const;
virtual SpeakerMode get_speaker_mode() const; virtual SpeakerMode get_speaker_mode() const;
virtual void lock(); virtual void lock();