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 numChannels = SDL2.audio.currentOutputBuffer[
'numberOfChannels'];
39 for (var
c = 0;
c < numChannels; ++
c) {
40 var channelData = SDL2.audio.currentOutputBuffer[
'getChannelData'](
c);
41 if (channelData.length != $1) {
42 throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length +
' samples vs expected ' + $1 +
' samples!';
45 for (var
j = 0;
j < $1; ++
j) {
46 channelData[
j] = HEAPF32[$0 + ((
j*numChannels +
c) << 2) >> 2];
49 },
buf, buflen / framelen);
53 HandleAudioProcess(
_THIS)
56 const int stream_len = this->callbackspec.size;
68 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
72 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
87 FeedAudioDevice(
this, this->work_buffer, this->
spec.
size);
91 HandleCaptureProcess(
_THIS)
94 const int stream_len = this->callbackspec.size;
103 var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
104 for (var
c = 0;
c < numChannels; ++
c) {
105 var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(
c);
106 if (channelData.length != $1) {
107 throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length +
' samples vs expected ' + $1 +
' samples!';
110 if (numChannels == 1) {
111 for (var
j = 0;
j < $1; ++
j) {
112 setValue($0 + (
j * 4), channelData[
j],
'float');
115 for (var
j = 0;
j < $1; ++
j) {
116 setValue($0 + (((
j * numChannels) +
c) * 4), channelData[
j],
'float');
126 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
135 if (got != stream_len) {
136 SDL_memset(this->work_buffer, this->callbackspec.silence, stream_len);
138 callback(this->callbackspec.userdata, this->work_buffer, stream_len);
145 EMSCRIPTENAUDIO_CloseDevice(
_THIS)
149 if (SDL2.capture.silenceTimer !== undefined) {
150 clearTimeout(SDL2.capture.silenceTimer);
152 if (SDL2.capture.stream !== undefined) {
153 var tracks = SDL2.capture.stream.getAudioTracks();
154 for (var i = 0; i < tracks.length; i++) {
155 SDL2.capture.stream.removeTrack(tracks[i]);
157 SDL2.capture.stream = undefined;
159 if (SDL2.capture.scriptProcessorNode !== undefined) {
160 SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {};
161 SDL2.capture.scriptProcessorNode.disconnect();
162 SDL2.capture.scriptProcessorNode = undefined;
164 if (SDL2.capture.mediaStreamNode !== undefined) {
165 SDL2.capture.mediaStreamNode.disconnect();
166 SDL2.capture.mediaStreamNode = undefined;
168 if (SDL2.capture.silenceBuffer !== undefined) {
169 SDL2.capture.silenceBuffer = undefined
171 SDL2.capture = undefined;
173 if (SDL2.audio.scriptProcessorNode != undefined) {
174 SDL2.audio.scriptProcessorNode.disconnect();
175 SDL2.audio.scriptProcessorNode = undefined;
177 SDL2.audio = undefined;
179 if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) {
180 SDL2.audioContext.close();
181 SDL2.audioContext = undefined;
191 EMSCRIPTENAUDIO_OpenDevice(
_THIS,
void *
handle,
const char *devname,
int iscapture)
200 result = EM_ASM_INT({
201 if(typeof(SDL2) ===
'undefined') {
210 if (!SDL2.audioContext) {
211 if (typeof(AudioContext) !==
'undefined') {
212 SDL2.audioContext = new AudioContext();
213 }
else if (typeof(webkitAudioContext) !==
'undefined') {
214 SDL2.audioContext =
new webkitAudioContext();
217 return SDL2.audioContext === undefined ? -1 : 0;
224 while ((!valid_format) && (test_format)) {
225 switch (test_format) {
244 if (this->hidden ==
NULL) {
251 this->
spec.
freq = EM_ASM_INT_V({
return SDL2.audioContext.sampleRate; });
273 var have_microphone =
function(
stream) {
275 if (SDL2.capture.silenceTimer !== undefined) {
276 clearTimeout(SDL2.capture.silenceTimer);
277 SDL2.capture.silenceTimer = undefined;
279 SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(
stream);
280 SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1);
281 SDL2.capture.scriptProcessorNode.onaudioprocess =
function(audioProcessingEvent) {
282 if ((SDL2 === undefined) || (SDL2.capture === undefined)) {
return; }
283 audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0);
284 SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
285 Runtime.dynCall(
'vi', $2, [$3]);
287 SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
288 SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
289 SDL2.capture.stream =
stream;
292 var no_microphone =
function(error) {
297 SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
298 SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0);
299 var silence_callback =
function() {
300 SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
301 Runtime.dynCall(
'vi', $2, [$3]);
304 SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
306 if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) {
307 navigator.mediaDevices.getUserMedia({
audio:
true, video:
false }).then(have_microphone).catch(no_microphone);
308 }
else if (navigator.webkitGetUserMedia !== undefined) {
309 navigator.webkitGetUserMedia({
audio:
true, video:
false }, have_microphone, no_microphone);
315 SDL2.audio.scriptProcessorNode = SDL2.audioContext[
'createScriptProcessor']($1, 0, $0);
316 SDL2.audio.scriptProcessorNode[
'onaudioprocess'] =
function (
e) {
317 if ((SDL2 === undefined) || (SDL2.audio === undefined)) {
return; }
318 SDL2.audio.currentOutputBuffer =
e[
'outputBuffer'];
319 Runtime.dynCall(
'vi', $2, [$3]);
321 SDL2.audio.scriptProcessorNode[
'connect'](SDL2.audioContext[
'destination']);
332 int capture_available;
335 impl->
OpenDevice = EMSCRIPTENAUDIO_OpenDevice;
345 available = EM_ASM_INT_V({
346 if (typeof(AudioContext) !==
'undefined') {
348 }
else if (typeof(webkitAudioContext) !==
'undefined') {
358 capture_available = available && EM_ASM_INT_V({
359 if ((typeof(navigator.mediaDevices) !==
'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !==
'undefined')) {
361 }
else if (typeof(navigator.webkitGetUserMedia) !==
'undefined') {
374 "emscripten",
"SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0
AudioBootStrap EMSCRIPTENAUDIO_bootstrap
#define SDL_AudioStreamAvailable
SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
#define SDL_AudioStreamGet
int ProvidesOwnCallbackThread
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
Uint16 SDL_AudioFormat
Audio format flags.
int OnlyHasDefaultCaptureDevice
SDL_AudioFormat SDL_NextAudioFormat(void)
int OnlyHasDefaultOutputDevice
EGLImageKHR EGLint EGLint * handle
void(* SDL_AudioCallback)(void *userdata, Uint8 *stream, int len)
#define SDL_AUDIO_BITSIZE(x)
#define SDL_AudioStreamPut
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
static Uint32 callback(Uint32 interval, void *param)
void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLenum GLsizei const GLuint GLboolean enabled
#define SDL_assert(condition)
int(* OpenDevice)(_THIS, void *handle, const char *devname, int iscapture)
#define SDL_OutOfMemory()
void(* CloseDevice)(_THIS)
#define SDL_AudioStreamClear