| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  audio_driver_javascript.cpp                                          */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-01 11:16:22 +01:00
										 |  |  | /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "audio_driver_javascript.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | #include <emscripten.h>
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | AudioDriverJavaScript *AudioDriverJavaScript::singleton = NULL; | 
					
						
							| 
									
										
										
										
											2017-11-04 20:24:06 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | const char *AudioDriverJavaScript::get_name() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return "JavaScript"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_js_mix() { | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	AudioDriverJavaScript::singleton->mix_to_js(); | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_capture(float sample) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AudioDriverJavaScript::singleton->process_capture(sample); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | void AudioDriverJavaScript::mix_to_js() { | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode()); | 
					
						
							|  |  |  | 	int sample_count = memarr_len(internal_buffer) / channel_count; | 
					
						
							|  |  |  | 	int32_t *stream_buffer = reinterpret_cast<int32_t *>(internal_buffer); | 
					
						
							|  |  |  | 	audio_server_process(sample_count, stream_buffer); | 
					
						
							|  |  |  | 	for (int i = 0; i < sample_count * channel_count; i++) { | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 		internal_buffer[i] = float(stream_buffer[i] >> 16) / 32768.f; | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | void AudioDriverJavaScript::process_capture(float sample) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16); | 
					
						
							| 
									
										
										
										
											2020-01-20 21:35:13 +01:00
										 |  |  | 	input_buffer_write(sample32); | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | Error AudioDriverJavaScript::init() { | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	EM_ASM({ | 
					
						
							|  |  |  | 		_audioDriver_audioContext = new (window.AudioContext || window.webkitAudioContext); | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 		_audioDriver_audioInput = null; | 
					
						
							|  |  |  | 		_audioDriver_inputStream = null; | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		_audioDriver_scriptNode = null; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode()); | 
					
						
							|  |  |  | 	/* clang-format off */ | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 	buffer_length = EM_ASM_INT({ | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		var CHANNEL_COUNT = $0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var channelCount = _audioDriver_audioContext.destination.channelCount; | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			// Try letting the browser recommend a buffer length.
 | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 			_audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(0, 2, channelCount); | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		} catch (e) { | 
					
						
							|  |  |  | 			// ...otherwise, default to 4096.
 | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 			_audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(4096, 2, channelCount); | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		_audioDriver_scriptNode.connect(_audioDriver_audioContext.destination); | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		return _audioDriver_scriptNode.bufferSize; | 
					
						
							|  |  |  | 	}, channel_count); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							|  |  |  | 	if (!buffer_length) { | 
					
						
							|  |  |  | 		return FAILED; | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-15 12:11:30 +02:00
										 |  |  | 	if (!internal_buffer || (int)memarr_len(internal_buffer) != buffer_length * channel_count) { | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		if (internal_buffer) | 
					
						
							|  |  |  | 			memdelete_arr(internal_buffer); | 
					
						
							|  |  |  | 		internal_buffer = memnew_arr(float, buffer_length *channel_count); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	return internal_buffer ? OK : ERR_OUT_OF_MEMORY; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-16 19:19:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AudioDriverJavaScript::start() { | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* clang-format off */ | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	EM_ASM({ | 
					
						
							|  |  |  | 		var INTERNAL_BUFFER_PTR = $0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var audioDriverMixFunction = cwrap('audio_driver_js_mix'); | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 		var audioDriverProcessCapture = cwrap('audio_driver_process_capture', null, ['number']); | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		_audioDriver_scriptNode.onaudioprocess = function(audioProcessingEvent) { | 
					
						
							|  |  |  | 			audioDriverMixFunction(); | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			var input = audioProcessingEvent.inputBuffer; | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 			var output = audioProcessingEvent.outputBuffer; | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 			var internalBuffer = HEAPF32.subarray( | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 					INTERNAL_BUFFER_PTR / HEAPF32.BYTES_PER_ELEMENT, | 
					
						
							|  |  |  | 					INTERNAL_BUFFER_PTR / HEAPF32.BYTES_PER_ELEMENT + output.length * output.numberOfChannels); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (var channel = 0; channel < output.numberOfChannels; channel++) { | 
					
						
							|  |  |  | 				var outputData = output.getChannelData(channel); | 
					
						
							|  |  |  | 				// Loop through samples.
 | 
					
						
							|  |  |  | 				for (var sample = 0; sample < outputData.length; sample++) { | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 					outputData[sample] = internalBuffer[sample * output.numberOfChannels + channel]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (_audioDriver_audioInput) { | 
					
						
							|  |  |  | 				var inputDataL = input.getChannelData(0); | 
					
						
							|  |  |  | 				var inputDataR = input.getChannelData(1); | 
					
						
							|  |  |  | 				for (var i = 0; i < inputDataL.length; i++) { | 
					
						
							|  |  |  | 					audioDriverProcessCapture(inputDataL[i]); | 
					
						
							|  |  |  | 					audioDriverProcessCapture(inputDataR[i]); | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-04 20:24:06 +01:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	}, internal_buffer); | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 	/* clang-format on */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-16 19:19:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-20 14:25:15 +01:00
										 |  |  | void AudioDriverJavaScript::resume() { | 
					
						
							|  |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	EM_ASM({ | 
					
						
							|  |  |  | 		if (_audioDriver_audioContext.resume) | 
					
						
							|  |  |  | 			_audioDriver_audioContext.resume(); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | int AudioDriverJavaScript::get_mix_rate() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	return EM_ASM_INT_V({ | 
					
						
							|  |  |  | 		return _audioDriver_audioContext.sampleRate; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const { | 
					
						
							| 
									
										
										
										
											2017-01-16 19:19:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	return get_speaker_mode_by_total_channels(EM_ASM_INT_V({ | 
					
						
							|  |  |  | 		return _audioDriver_audioContext.destination.channelCount; | 
					
						
							|  |  |  | 	})); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-16 19:19:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | // No locking, as threads are not supported.
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AudioDriverJavaScript::lock() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-16 19:19:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void AudioDriverJavaScript::unlock() { | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-16 19:19:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void AudioDriverJavaScript::finish() { | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	EM_ASM({ | 
					
						
							|  |  |  | 		_audioDriver_audioContext = null; | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 		_audioDriver_audioInput = null; | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 		_audioDriver_scriptNode = null; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (internal_buffer) { | 
					
						
							|  |  |  | 		memdelete_arr(internal_buffer); | 
					
						
							|  |  |  | 		internal_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error AudioDriverJavaScript::capture_start() { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 21:35:13 +01:00
										 |  |  | 	input_buffer_init(buffer_length); | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	EM_ASM({ | 
					
						
							|  |  |  | 		function gotMediaInput(stream) { | 
					
						
							|  |  |  | 			_audioDriver_inputStream = stream; | 
					
						
							|  |  |  | 			_audioDriver_audioInput = _audioDriver_audioContext.createMediaStreamSource(stream); | 
					
						
							|  |  |  | 			_audioDriver_audioInput.connect(_audioDriver_scriptNode); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		function gotMediaInputError(e) { | 
					
						
							| 
									
										
										
										
											2019-02-24 04:40:06 +01:00
										 |  |  | 			out(e); | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (navigator.mediaDevices.getUserMedia) { | 
					
						
							|  |  |  | 			navigator.mediaDevices.getUserMedia({"audio": true}).then(gotMediaInput, gotMediaInputError); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (!navigator.getUserMedia) | 
					
						
							|  |  |  | 				navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; | 
					
						
							|  |  |  | 			navigator.getUserMedia({"audio": true}, gotMediaInput, gotMediaInputError); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error AudioDriverJavaScript::capture_stop() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* clang-format off */ | 
					
						
							|  |  |  | 	EM_ASM({ | 
					
						
							|  |  |  | 		if (_audioDriver_inputStream) { | 
					
						
							|  |  |  | 			const tracks = _audioDriver_inputStream.getTracks(); | 
					
						
							|  |  |  | 			for (var i = 0; i < tracks.length; i++) { | 
					
						
							|  |  |  | 				tracks[i].stop(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			_audioDriver_inputStream = null; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (_audioDriver_audioInput) { | 
					
						
							|  |  |  | 			_audioDriver_audioInput.disconnect(); | 
					
						
							|  |  |  | 			_audioDriver_audioInput = null; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	/* clang-format on */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 21:35:13 +01:00
										 |  |  | 	input_buffer.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 	return OK; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | AudioDriverJavaScript::AudioDriverJavaScript() { | 
					
						
							| 
									
										
										
										
											2017-10-26 22:34:49 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-08 15:46:21 -03:00
										 |  |  | 	internal_buffer = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-05 23:48:13 +01:00
										 |  |  | 	singleton = this; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |