21 #include "../../SDL_internal.h"
23 #if SDL_AUDIO_DRIVER_EMSCRIPTEN
27 #include "../SDL_audio_c.h"
31 #include <emscripten/emscripten.h>
34 FeedAudioDevice(
_THIS,
const void *
buf,
const int buflen)
38 var SDL2 = Module[
'SDL2'];
39 var numChannels = SDL2.audio.currentOutputBuffer[
'numberOfChannels'];
40 for (var
c = 0;
c < numChannels; ++
c) {
41 var channelData = SDL2.audio.currentOutputBuffer[
'getChannelData'](
c);
42 if (channelData.length != $1) {
43 throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length +
' samples vs expected ' + $1 +
' samples!';
46 for (var
j = 0;
j < $1; ++
j) {
47 channelData[
j] = HEAPF32[$0 + ((
j*numChannels +
c) << 2) >> 2];
50 },
buf, buflen / framelen);
54 HandleAudioProcess(
_THIS)
57 const int stream_len = this->callbackspec.size;
69 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
73 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
88 FeedAudioDevice(
this, this->work_buffer, this->
spec.
size);
92 HandleCaptureProcess(
_THIS)
95 const int stream_len = this->callbackspec.size;
104 var SDL2 = Module[
'SDL2'];
105 var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
106 for (var
c = 0;
c < numChannels; ++
c) {
107 var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(
c);
108 if (channelData.length != $1) {
109 throw
'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length +
' samples vs expected ' + $1 +
' samples!';
112 if (numChannels == 1) {
113 for (var
j = 0;
j < $1; ++
j) {
114 setValue($0 + (
j * 4), channelData[
j],
'float');
117 for (var
j = 0;
j < $1; ++
j) {
118 setValue($0 + (((
j * numChannels) +
c) * 4), channelData[
j],
'float');
128 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
137 if (got != stream_len) {
138 SDL_memset(this->work_buffer, this->callbackspec.silence, stream_len);
140 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
147 EMSCRIPTENAUDIO_CloseDevice(
_THIS)
150 var SDL2 = Module[
'SDL2'];
152 if (SDL2.capture.silenceTimer !== undefined) {
153 clearTimeout(SDL2.capture.silenceTimer);
155 if (SDL2.capture.stream !== undefined) {
156 var tracks = SDL2.capture.stream.getAudioTracks();
157 for (var i = 0; i < tracks.length; i++) {
158 SDL2.capture.stream.removeTrack(tracks[i]);
160 SDL2.capture.stream = undefined;
162 if (SDL2.capture.scriptProcessorNode !== undefined) {
163 SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {};
164 SDL2.capture.scriptProcessorNode.disconnect();
165 SDL2.capture.scriptProcessorNode = undefined;
167 if (SDL2.capture.mediaStreamNode !== undefined) {
168 SDL2.capture.mediaStreamNode.disconnect();
169 SDL2.capture.mediaStreamNode = undefined;
171 if (SDL2.capture.silenceBuffer !== undefined) {
172 SDL2.capture.silenceBuffer = undefined
174 SDL2.capture = undefined;
176 if (SDL2.audio.scriptProcessorNode != undefined) {
177 SDL2.audio.scriptProcessorNode.disconnect();
178 SDL2.audio.scriptProcessorNode = undefined;
180 SDL2.audio = undefined;
182 if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) {
183 SDL2.audioContext.close();
184 SDL2.audioContext = undefined;
194 EMSCRIPTENAUDIO_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
204 if(typeof(Module[
'SDL2']) ===
'undefined') {
207 var SDL2 = Module[
'SDL2'];
214 if (!SDL2.audioContext) {
215 if (typeof(AudioContext) !==
'undefined') {
216 SDL2.audioContext = new AudioContext();
217 }
else if (typeof(webkitAudioContext) !==
'undefined') {
218 SDL2.audioContext =
new webkitAudioContext();
221 return SDL2.audioContext === undefined ? -1 : 0;
228 while ((!valid_format) && (test_format)) {
229 switch (test_format) {
248 if (this->hidden ==
NULL) {
257 var SDL2 = Module[
'SDL2'];
258 return SDL2.audioContext.sampleRate;
281 var SDL2 = Module[
'SDL2'];
282 var have_microphone =
function(
stream) {
284 if (SDL2.capture.silenceTimer !== undefined) {
285 clearTimeout(SDL2.capture.silenceTimer);
286 SDL2.capture.silenceTimer = undefined;
288 SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(
stream);
289 SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1);
290 SDL2.capture.scriptProcessorNode.onaudioprocess =
function(audioProcessingEvent) {
291 if ((SDL2 === undefined) || (SDL2.capture === undefined)) {
return; }
292 audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0);
293 SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
294 dynCall(
'vi', $2, [$3]);
296 SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
297 SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
298 SDL2.capture.stream =
stream;
301 var no_microphone =
function(error) {
306 SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
307 SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0);
308 var silence_callback =
function() {
309 SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
310 dynCall(
'vi', $2, [$3]);
313 SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
315 if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) {
316 navigator.mediaDevices.getUserMedia({
audio:
true, video:
false }).then(have_microphone).catch(no_microphone);
317 }
else if (navigator.webkitGetUserMedia !== undefined) {
318 navigator.webkitGetUserMedia({
audio:
true, video:
false }, have_microphone, no_microphone);
324 var SDL2 = Module[
'SDL2'];
325 SDL2.audio.scriptProcessorNode = SDL2.audioContext[
'createScriptProcessor']($1, 0, $0);
326 SDL2.audio.scriptProcessorNode[
'onaudioprocess'] =
function (
e) {
327 if ((SDL2 === undefined) || (SDL2.audio === undefined)) {
return; }
328 SDL2.audio.currentOutputBuffer =
e[
'outputBuffer'];
329 dynCall(
'vi', $2, [$3]);
331 SDL2.audio.scriptProcessorNode[
'connect'](SDL2.audioContext[
'destination']);
342 int capture_available;
345 impl->
OpenDevice = EMSCRIPTENAUDIO_OpenDevice;
356 if (typeof(AudioContext) !==
'undefined') {
358 }
else if (typeof(webkitAudioContext) !==
'undefined') {
368 capture_available =
available && EM_ASM_INT_V({
369 if ((typeof(navigator.mediaDevices) !==
'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !==
'undefined')) {
371 }
else if (typeof(navigator.webkitGetUserMedia) !==
'undefined') {
384 "emscripten",
"SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0