Browse Source

Merge pull request #38816 from Faless/js/fix_audio_driver_4.0

AudioDriverJavaScript buffer size calculation.
Rémi Verschelde 5 years ago
parent
commit
37efaad8fb

+ 2 - 2
drivers/alsa/audio_driver_alsa.cpp

@@ -38,7 +38,7 @@
 #include <errno.h>
 #include <errno.h>
 
 
 Error AudioDriverALSA::init_device() {
 Error AudioDriverALSA::init_device() {
-	mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 	speaker_mode = SPEAKER_MODE_STEREO;
 	speaker_mode = SPEAKER_MODE_STEREO;
 	channels = 2;
 	channels = 2;
 
 
@@ -104,7 +104,7 @@ Error AudioDriverALSA::init_device() {
 	// In ALSA the period size seems to be the one that will determine the actual latency
 	// In ALSA the period size seems to be the one that will determine the actual latency
 	// Ref: https://www.alsa-project.org/main/index.php/FramesPeriods
 	// Ref: https://www.alsa-project.org/main/index.php/FramesPeriods
 	unsigned int periods = 2;
 	unsigned int periods = 2;
-	int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+	int latency = GLOBAL_GET("audio/output_latency");
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 	buffer_size = buffer_frames * periods;
 	buffer_size = buffer_frames * periods;
 	period_size = buffer_frames;
 	period_size = buffer_frames;

+ 3 - 3
drivers/coreaudio/audio_driver_coreaudio.cpp

@@ -116,7 +116,7 @@ Error AudioDriverCoreAudio::init() {
 			break;
 			break;
 	}
 	}
 
 
-	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 
 
 	zeromem(&strdesc, sizeof(strdesc));
 	zeromem(&strdesc, sizeof(strdesc));
 	strdesc.mFormatID = kAudioFormatLinearPCM;
 	strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -131,7 +131,7 @@ Error AudioDriverCoreAudio::init() {
 	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
 	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
 	ERR_FAIL_COND_V(result != noErr, FAILED);
 	ERR_FAIL_COND_V(result != noErr, FAILED);
 
 
-	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+	int latency = GLOBAL_GET("audio/output_latency");
 	// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
 	// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 
 
@@ -403,7 +403,7 @@ Error AudioDriverCoreAudio::capture_init() {
 			break;
 			break;
 	}
 	}
 
 
-	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 
 
 	zeromem(&strdesc, sizeof(strdesc));
 	zeromem(&strdesc, sizeof(strdesc));
 	strdesc.mFormatID = kAudioFormatLinearPCM;
 	strdesc.mFormatID = kAudioFormatLinearPCM;

+ 2 - 2
drivers/pulseaudio/audio_driver_pulseaudio.cpp

@@ -179,7 +179,7 @@ Error AudioDriverPulseAudio::init_device() {
 			break;
 			break;
 	}
 	}
 
 
-	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+	int latency = GLOBAL_GET("audio/output_latency");
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 	pa_buffer_size = buffer_frames * pa_map.channels;
 	pa_buffer_size = buffer_frames * pa_map.channels;
 
 
@@ -237,7 +237,7 @@ Error AudioDriverPulseAudio::init() {
 	thread_exited = false;
 	thread_exited = false;
 	exit_thread = false;
 	exit_thread = false;
 
 
-	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 
 
 	pa_ml = pa_mainloop_new();
 	pa_ml = pa_mainloop_new();
 	ERR_FAIL_COND_V(pa_ml == nullptr, ERR_CANT_OPEN);
 	ERR_FAIL_COND_V(pa_ml == nullptr, ERR_CANT_OPEN);

+ 1 - 1
drivers/wasapi/audio_driver_wasapi.cpp

@@ -387,7 +387,7 @@ Error AudioDriverWASAPI::finish_capture_device() {
 }
 }
 
 
 Error AudioDriverWASAPI::init() {
 Error AudioDriverWASAPI::init() {
-	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 
 
 	Error err = init_render_device();
 	Error err = init_render_device();
 	if (err != OK) {
 	if (err != OK) {

+ 2 - 2
drivers/xaudio2/audio_driver_xaudio2.cpp

@@ -44,12 +44,12 @@ Error AudioDriverXAudio2::init() {
 	pcm_open = false;
 	pcm_open = false;
 	samples_in = nullptr;
 	samples_in = nullptr;
 
 
-	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 	// FIXME: speaker_mode seems unused in the Xaudio2 driver so far
 	// FIXME: speaker_mode seems unused in the Xaudio2 driver so far
 	speaker_mode = SPEAKER_MODE_STEREO;
 	speaker_mode = SPEAKER_MODE_STEREO;
 	channels = 2;
 	channels = 2;
 
 
-	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+	int latency = GLOBAL_GET("audio/output_latency");
 	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 
 
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);

+ 2 - 2
platform/android/audio_driver_jandroid.cpp

@@ -73,9 +73,9 @@ Error AudioDriverAndroid::init() {
 	//        __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
 	//        __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
 
 
 	JNIEnv *env = ThreadAndroid::get_env();
 	JNIEnv *env = ThreadAndroid::get_env();
-	int mix_rate = GLOBAL_DEF_RST("audio/mix_rate", 44100);
+	int mix_rate = GLOBAL_GET("audio/mix_rate");
 
 
-	int latency = GLOBAL_DEF_RST("audio/output_latency", 25);
+	int latency = GLOBAL_GET("audio/output_latency");
 	unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
 	unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
 	print_verbose("Audio buffer size: " + itos(buffer_size));
 	print_verbose("Audio buffer size: " + itos(buffer_size));
 
 

+ 2 - 2
platform/haiku/audio_driver_media_kit.cpp

@@ -39,11 +39,11 @@ int32_t *AudioDriverMediaKit::samples_in = nullptr;
 Error AudioDriverMediaKit::init() {
 Error AudioDriverMediaKit::init() {
 	active = false;
 	active = false;
 
 
-	mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 	speaker_mode = SPEAKER_MODE_STEREO;
 	speaker_mode = SPEAKER_MODE_STEREO;
 	channels = 2;
 	channels = 2;
 
 
-	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+	int latency = GLOBAL_GET("audio/output_latency");
 	buffer_size = next_power_of_2(latency * mix_rate / 1000);
 	buffer_size = next_power_of_2(latency * mix_rate / 1000);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 
 

+ 34 - 15
platform/javascript/audio_driver_javascript.cpp

@@ -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_GET("audio/mix_rate");
+	int latency = GLOBAL_GET("audio/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'];
-		var CHANNEL_COUNT = $1;
-
-		var channelCount = ctx.destination.channelCount;
-		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);
-		}
+		const ctx = ref['context'];
+		const BUFFER_LENGTH = $1;
+		const CHANNEL_COUNT = $2;
+
+		var script = ctx.createScriptProcessor(BUFFER_LENGTH, 2, CHANNEL_COUNT);
 		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({

+ 1 - 0
platform/javascript/audio_driver_javascript.h

@@ -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();

+ 2 - 2
servers/audio/audio_driver_dummy.cpp

@@ -39,11 +39,11 @@ Error AudioDriverDummy::init() {
 	exit_thread = false;
 	exit_thread = false;
 	samples_in = nullptr;
 	samples_in = nullptr;
 
 
-	mix_rate = DEFAULT_MIX_RATE;
+	mix_rate = GLOBAL_GET("audio/mix_rate");
 	speaker_mode = SPEAKER_MODE_STEREO;
 	speaker_mode = SPEAKER_MODE_STEREO;
 	channels = 2;
 	channels = 2;
 
 
-	int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+	int latency = GLOBAL_GET("audio/output_latency");
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 	buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
 
 
 	samples_in = memnew_arr(int32_t, buffer_frames * channels);
 	samples_in = memnew_arr(int32_t, buffer_frames * channels);

+ 3 - 0
servers/audio_server.cpp

@@ -182,6 +182,9 @@ 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/output_latency", DEFAULT_OUTPUT_LATENCY);
+
 	int failed_driver = -1;
 	int failed_driver = -1;
 
 
 	// Check if there is a selected driver
 	// Check if there is a selected driver

+ 3 - 3
servers/audio_server.h

@@ -80,9 +80,6 @@ public:
 		SPEAKER_SURROUND_71,
 		SPEAKER_SURROUND_71,
 	};
 	};
 
 
-	static const int DEFAULT_MIX_RATE = 44100;
-	static const int DEFAULT_OUTPUT_LATENCY = 15;
-
 	static AudioDriver *get_singleton();
 	static AudioDriver *get_singleton();
 	void set_singleton();
 	void set_singleton();
 
 
@@ -129,6 +126,9 @@ class AudioDriverManager {
 		MAX_DRIVERS = 10
 		MAX_DRIVERS = 10
 	};
 	};
 
 
+	static const int DEFAULT_MIX_RATE = 44100;
+	static const int DEFAULT_OUTPUT_LATENCY = 15;
+
 	static AudioDriver *drivers[MAX_DRIVERS];
 	static AudioDriver *drivers[MAX_DRIVERS];
 	static int driver_count;
 	static int driver_count;