summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/SDL2/src/audio/emscripten
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/SDL2/src/audio/emscripten')
-rw-r--r--3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c443
-rw-r--r--3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h42
2 files changed, 0 insertions, 485 deletions
diff --git a/3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c b/3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c
deleted file mode 100644
index 839d445ee61..00000000000
--- a/3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- Simple DirectMedia Layer
- Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-*/
-#include "../../SDL_internal.h"
-
-#if SDL_AUDIO_DRIVER_EMSCRIPTEN
-
-#include "SDL_audio.h"
-#include "SDL_log.h"
-#include "../SDL_audio_c.h"
-#include "SDL_emscriptenaudio.h"
-
-#include <emscripten/emscripten.h>
-
-static int
-copyData(_THIS)
-{
- int byte_len;
-
- if (this->hidden->write_off + this->convert.len_cvt > this->hidden->mixlen) {
- if (this->hidden->write_off > this->hidden->read_off) {
- SDL_memmove(this->hidden->mixbuf,
- this->hidden->mixbuf + this->hidden->read_off,
- this->hidden->mixlen - this->hidden->read_off);
- this->hidden->write_off = this->hidden->write_off - this->hidden->read_off;
- } else {
- this->hidden->write_off = 0;
- }
- this->hidden->read_off = 0;
- }
-
- SDL_memcpy(this->hidden->mixbuf + this->hidden->write_off,
- this->convert.buf,
- this->convert.len_cvt);
- this->hidden->write_off += this->convert.len_cvt;
- byte_len = this->hidden->write_off - this->hidden->read_off;
-
- return byte_len;
-}
-
-static void
-HandleAudioProcess(_THIS)
-{
- Uint8 *buf = NULL;
- int byte_len = 0;
- int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
-
- /* Only do something if audio is enabled */
- if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
- return;
- }
-
- if (this->convert.needed) {
- const int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8;
-
- if (this->hidden->conv_in_len != 0) {
- this->convert.len = this->hidden->conv_in_len * bytes_in * this->spec.channels;
- }
-
- (*this->spec.callback) (this->spec.userdata,
- this->convert.buf,
- this->convert.len);
- SDL_ConvertAudio(&this->convert);
- buf = this->convert.buf;
- byte_len = this->convert.len_cvt;
-
- /* size mismatch*/
- if (byte_len != this->spec.size) {
- if (!this->hidden->mixbuf) {
- this->hidden->mixlen = this->spec.size > byte_len ? this->spec.size * 2 : byte_len * 2;
- this->hidden->mixbuf = SDL_malloc(this->hidden->mixlen);
- }
-
- /* copy existing data */
- byte_len = copyData(this);
-
- /* read more data*/
- while (byte_len < this->spec.size) {
- (*this->spec.callback) (this->spec.userdata,
- this->convert.buf,
- this->convert.len);
- SDL_ConvertAudio(&this->convert);
- byte_len = copyData(this);
- }
-
- byte_len = this->spec.size;
- buf = this->hidden->mixbuf + this->hidden->read_off;
- this->hidden->read_off += byte_len;
- }
-
- } else {
- if (!this->hidden->mixbuf) {
- this->hidden->mixlen = this->spec.size;
- this->hidden->mixbuf = SDL_malloc(this->hidden->mixlen);
- }
- (*this->spec.callback) (this->spec.userdata,
- this->hidden->mixbuf,
- this->hidden->mixlen);
- buf = this->hidden->mixbuf;
- byte_len = this->hidden->mixlen;
- }
-
- if (buf) {
- EM_ASM_ARGS({
- var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
- for (var c = 0; c < numChannels; ++c) {
- var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c);
- if (channelData.length != $1) {
- throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
- }
-
- for (var j = 0; j < $1; ++j) {
- channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2];
- }
- }
- }, buf, byte_len / bytes / this->spec.channels);
- }
-}
-
-static void
-HandleCaptureProcess(_THIS)
-{
- Uint8 *buf;
- int buflen;
-
- /* Only do something if audio is enabled */
- if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
- return;
- }
-
- if (this->convert.needed) {
- buf = this->convert.buf;
- buflen = this->convert.len_cvt;
- } else {
- if (!this->hidden->mixbuf) {
- this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
- if (!this->hidden->mixbuf) {
- return; /* oh well. */
- }
- }
- buf = this->hidden->mixbuf;
- buflen = this->spec.size;
- }
-
- EM_ASM_ARGS({
- var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
- if (numChannels == 1) { /* fastpath this a little for the common (mono) case. */
- var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(0);
- if (channelData.length != $1) {
- throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
- }
- for (var j = 0; j < $1; ++j) {
- setValue($0 + (j * 4), channelData[j], 'float');
- }
- } else {
- for (var c = 0; c < numChannels; ++c) {
- var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c);
- if (channelData.length != $1) {
- throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
- }
-
- for (var j = 0; j < $1; ++j) {
- setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float');
- }
- }
- }
- }, buf, (this->spec.size / sizeof (float)) / this->spec.channels);
-
- /* okay, we've got an interleaved float32 array in C now. */
-
- if (this->convert.needed) {
- SDL_ConvertAudio(&this->convert);
- }
-
- /* Send it to the app. */
- (*this->spec.callback) (this->spec.userdata, buf, buflen);
-}
-
-
-
-static void
-EMSCRIPTENAUDIO_CloseDevice(_THIS)
-{
- EM_ASM_({
- if ($0) {
- if (SDL2.capture.silenceTimer !== undefined) {
- clearTimeout(SDL2.capture.silenceTimer);
- }
- if (SDL2.capture.stream !== undefined) {
- var tracks = SDL2.capture.stream.getAudioTracks();
- for (var i = 0; i < tracks.length; i++) {
- SDL2.capture.stream.removeTrack(tracks[i]);
- }
- SDL2.capture.stream = undefined;
- }
- if (SDL2.capture.scriptProcessorNode !== undefined) {
- SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {};
- SDL2.capture.scriptProcessorNode.disconnect();
- SDL2.capture.scriptProcessorNode = undefined;
- }
- if (SDL2.capture.mediaStreamNode !== undefined) {
- SDL2.capture.mediaStreamNode.disconnect();
- SDL2.capture.mediaStreamNode = undefined;
- }
- if (SDL2.capture.silenceBuffer !== undefined) {
- SDL2.capture.silenceBuffer = undefined
- }
- SDL2.capture = undefined;
- } else {
- if (SDL2.audio.scriptProcessorNode != undefined) {
- SDL2.audio.scriptProcessorNode.disconnect();
- SDL2.audio.scriptProcessorNode = undefined;
- }
- SDL2.audio = undefined;
- }
- if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) {
- SDL2.audioContext.close();
- SDL2.audioContext = undefined;
- }
- }, this->iscapture);
-
- SDL_free(this->hidden->mixbuf);
- SDL_free(this->hidden);
-}
-
-static int
-EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
-{
- SDL_bool valid_format = SDL_FALSE;
- SDL_AudioFormat test_format;
- int i;
- float f;
- int result;
-
- /* based on parts of library_sdl.js */
-
- /* create context (TODO: this puts stuff in the global namespace...)*/
- result = EM_ASM_INT({
- if(typeof(SDL2) === 'undefined') {
- SDL2 = {};
- }
- if (!$0) {
- SDL2.audio = {};
- } else {
- SDL2.capture = {};
- }
-
- if (!SDL2.audioContext) {
- if (typeof(AudioContext) !== 'undefined') {
- SDL2.audioContext = new AudioContext();
- } else if (typeof(webkitAudioContext) !== 'undefined') {
- SDL2.audioContext = new webkitAudioContext();
- }
- }
- return SDL2.audioContext === undefined ? -1 : 0;
- }, iscapture);
- if (result < 0) {
- return SDL_SetError("Web Audio API is not available!");
- }
-
- test_format = SDL_FirstAudioFormat(this->spec.format);
- while ((!valid_format) && (test_format)) {
- switch (test_format) {
- case AUDIO_F32: /* web audio only supports floats */
- this->spec.format = test_format;
-
- valid_format = SDL_TRUE;
- break;
- }
- test_format = SDL_NextAudioFormat();
- }
-
- if (!valid_format) {
- /* Didn't find a compatible format :( */
- return SDL_SetError("No compatible audio format!");
- }
-
- /* Initialize all variables that we clean on shutdown */
- this->hidden = (struct SDL_PrivateAudioData *)
- SDL_malloc((sizeof *this->hidden));
- if (this->hidden == NULL) {
- return SDL_OutOfMemory();
- }
- SDL_zerop(this->hidden);
-
- /* limit to native freq */
- const int sampleRate = EM_ASM_INT_V({
- return SDL2.audioContext.sampleRate;
- });
-
- if(this->spec.freq != sampleRate) {
- for (i = this->spec.samples; i > 0; i--) {
- f = (float)i / (float)sampleRate * (float)this->spec.freq;
- if (SDL_floor(f) == f) {
- this->hidden->conv_in_len = SDL_floor(f);
- break;
- }
- }
-
- this->spec.freq = sampleRate;
- }
-
- SDL_CalculateAudioSpec(&this->spec);
-
- if (iscapture) {
- /* The idea is to take the capture media stream, hook it up to an
- audio graph where we can pass it through a ScriptProcessorNode
- to access the raw PCM samples and push them to the SDL app's
- callback. From there, we "process" the audio data into silence
- and forget about it. */
-
- /* This should, strictly speaking, use MediaRecorder for capture, but
- this API is cleaner to use and better supported, and fires a
- callback whenever there's enough data to fire down into the app.
- The downside is that we are spending CPU time silencing a buffer
- that the audiocontext uselessly mixes into any output. On the
- upside, both of those things are not only run in native code in
- the browser, they're probably SIMD code, too. MediaRecorder
- feels like it's a pretty inefficient tapdance in similar ways,
- to be honest. */
-
- EM_ASM_({
- var have_microphone = function(stream) {
- //console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
- if (SDL2.capture.silenceTimer !== undefined) {
- clearTimeout(SDL2.capture.silenceTimer);
- SDL2.capture.silenceTimer = undefined;
- }
- SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream);
- SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1);
- SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {
- if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; }
- audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0);
- SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
- Runtime.dynCall('vi', $2, [$3]);
- };
- SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
- SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
- SDL2.capture.stream = stream;
- };
-
- var no_microphone = function(error) {
- //console.log('SDL audio capture: we DO NOT have a microphone! (' + error.name + ')...leaving silence callback running.');
- };
-
- /* we write silence to the audio callback until the microphone is available (user approves use, etc). */
- SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
- SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0);
- var silence_callback = function() {
- SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
- Runtime.dynCall('vi', $2, [$3]);
- };
-
- SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
-
- if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) {
- navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone);
- } else if (navigator.webkitGetUserMedia !== undefined) {
- navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone);
- }
- }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
- } else {
- /* setup a ScriptProcessorNode */
- EM_ASM_ARGS({
- SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
- SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
- if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; }
- SDL2.audio.currentOutputBuffer = e['outputBuffer'];
- Runtime.dynCall('vi', $2, [$3]);
- };
- SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);
- }, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
- }
-
- return 0;
-}
-
-static int
-EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
-{
- /* Set the function pointers */
- impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice;
- impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice;
-
- impl->OnlyHasDefaultOutputDevice = 1;
-
- /* no threads here */
- impl->SkipMixerLock = 1;
- impl->ProvidesOwnCallbackThread = 1;
-
- /* check availability */
- const int available = EM_ASM_INT_V({
- if (typeof(AudioContext) !== 'undefined') {
- return 1;
- } else if (typeof(webkitAudioContext) !== 'undefined') {
- return 1;
- }
- return 0;
- });
-
- if (!available) {
- SDL_SetError("No audio context available");
- }
-
- const int capture_available = available && EM_ASM_INT_V({
- if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
- return 1;
- } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {
- return 1;
- }
- return 0;
- });
-
- impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE;
- impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE;
-
- return available;
-}
-
-AudioBootStrap EMSCRIPTENAUDIO_bootstrap = {
- "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0
-};
-
-#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */
-
-/* vi: set ts=4 sw=4 expandtab: */
diff --git a/3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h b/3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h
deleted file mode 100644
index cd5377d86cc..00000000000
--- a/3rdparty/SDL2/src/audio/emscripten/SDL_emscriptenaudio.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Simple DirectMedia Layer
- Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-*/
-#include "../../SDL_internal.h"
-
-#ifndef _SDL_emscriptenaudio_h
-#define _SDL_emscriptenaudio_h
-
-#include "../SDL_sysaudio.h"
-
-/* Hidden "this" pointer for the audio functions */
-#define _THIS SDL_AudioDevice *this
-
-struct SDL_PrivateAudioData
-{
- Uint8 *mixbuf;
- Uint32 mixlen;
-
- Uint32 conv_in_len;
-
- Uint32 write_off, read_off;
-};
-
-#endif /* _SDL_emscriptenaudio_h */
-/* vi: set ts=4 sw=4 expandtab: */