src/audio/emscripten/SDL_emscriptenaudio.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Sat, 14 Feb 2015 00:16:27 +0100
changeset 9344 83f4ab8fb0b8
parent 9291 02b47b8164da
child 9394 bb28e5281770
permissions -rw-r--r--
Emscripten: Fixed throwing JavaScript exception if no audio context available. Handling the error in C provides the possibility to just continue without audio.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9278
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/*
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
  Simple DirectMedia Layer
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
  This software is provided 'as-is', without any express or implied
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     6
  warranty.  In no event will the authors be held liable for any damages
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
  arising from the use of this software.
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
  Permission is granted to anyone to use this software for any purpose,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
  including commercial applications, and to alter it and redistribute it
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    11
  freely, subject to the following restrictions:
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    12
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    13
  1. The origin of this software must not be misrepresented; you must not
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    14
     claim that you wrote the original software. If you use this software
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    15
     in a product, an acknowledgment in the product documentation would be
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    16
     appreciated but is not required.
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    17
  2. Altered source versions must be plainly marked as such, and must not be
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    18
     misrepresented as being the original software.
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    19
  3. This notice may not be removed or altered from any source distribution.
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    20
*/
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    21
#include "../../SDL_internal.h"
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    22
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    23
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    24
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    25
#include "SDL_audio.h"
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    26
#include "SDL_log.h"
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    27
#include "../SDL_audio_c.h"
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    28
#include "SDL_emscriptenaudio.h"
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    29
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    30
#include <emscripten/emscripten.h>
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    31
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    32
static int
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    33
copyData(_THIS)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    34
{
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    35
    int byte_len;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    36
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    37
    if (this->hidden->write_off + this->convert.len_cvt > this->hidden->mixlen) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    38
        if (this->hidden->write_off > this->hidden->read_off) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    39
            SDL_memmove(this->hidden->mixbuf,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    40
                        this->hidden->mixbuf + this->hidden->read_off,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    41
                        this->hidden->mixlen - this->hidden->read_off);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    42
            this->hidden->write_off = this->hidden->write_off - this->hidden->read_off;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    43
        } else {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    44
            this->hidden->write_off = 0;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    45
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    46
        this->hidden->read_off = 0;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    47
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    48
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    49
    SDL_memcpy(this->hidden->mixbuf + this->hidden->write_off,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    50
               this->convert.buf,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    51
               this->convert.len_cvt);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    52
    this->hidden->write_off += this->convert.len_cvt;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    53
    byte_len = this->hidden->write_off - this->hidden->read_off;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    54
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    55
    return byte_len;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    56
}
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    57
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    58
static void
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    59
HandleAudioProcess(_THIS)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    60
{
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    61
    Uint8 *buf = NULL;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    62
    int byte_len = 0;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    63
    int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    64
    int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    65
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    66
    /* Only do soemthing if audio is enabled */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    67
    if (!this->enabled)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
        return;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    69
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
    if (this->paused)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    71
        return;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    72
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
    if (this->convert.needed) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    74
        if (this->hidden->conv_in_len != 0) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
            this->convert.len = this->hidden->conv_in_len * bytes_in * this->spec.channels;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    76
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    77
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    78
        (*this->spec.callback) (this->spec.userdata,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    79
                                 this->convert.buf,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    80
                                 this->convert.len);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    81
        SDL_ConvertAudio(&this->convert);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    82
        buf = this->convert.buf;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    83
        byte_len = this->convert.len_cvt;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    84
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    85
        /* size mismatch*/
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    86
        if (byte_len != this->spec.size) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    87
            if (!this->hidden->mixbuf) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    88
                this->hidden->mixlen = this->spec.size > byte_len ? this->spec.size * 2 : byte_len * 2;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    89
                this->hidden->mixbuf = SDL_malloc(this->hidden->mixlen);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    90
            }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    91
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    92
            /* copy existing data */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    93
            byte_len = copyData(this);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    94
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    95
            /* read more data*/
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    96
            while (byte_len < this->spec.size) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    97
                (*this->spec.callback) (this->spec.userdata,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    98
                                         this->convert.buf,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    99
                                         this->convert.len);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   100
                SDL_ConvertAudio(&this->convert);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   101
                byte_len = copyData(this);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   102
            }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   103
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   104
            byte_len = this->spec.size;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   105
            buf = this->hidden->mixbuf + this->hidden->read_off;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   106
            this->hidden->read_off += byte_len;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   107
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   108
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   109
    } else {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   110
        if (!this->hidden->mixbuf) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   111
            this->hidden->mixlen = this->spec.size;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   112
            this->hidden->mixbuf = SDL_malloc(this->hidden->mixlen);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   113
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   114
        (*this->spec.callback) (this->spec.userdata,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   115
                                 this->hidden->mixbuf,
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   116
                                 this->hidden->mixlen);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   117
        buf = this->hidden->mixbuf;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   118
        byte_len = this->hidden->mixlen;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   119
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   120
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   121
    if (buf) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   122
        EM_ASM_ARGS({
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   123
            var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   124
            for (var c = 0; c < numChannels; ++c) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   125
                var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   126
                if (channelData.length != $1) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   127
                    throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   128
                }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   129
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   130
                for (var j = 0; j < $1; ++j) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   131
                    channelData[j] = getValue($0 + (j*numChannels + c)*4, 'float');
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   132
                }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   133
            }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   134
        }, buf, byte_len / bytes / this->spec.channels);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   135
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   136
}
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   137
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   138
static void
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   139
Emscripten_CloseDevice(_THIS)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   140
{
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   141
    if (this->hidden != NULL) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   142
        if (this->hidden->mixbuf != NULL) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   143
            /* Clean up the audio buffer */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   144
            SDL_free(this->hidden->mixbuf);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   145
            this->hidden->mixbuf = NULL;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   146
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   147
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   148
        SDL_free(this->hidden);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   149
        this->hidden = NULL;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   150
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   151
}
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   152
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   153
static int
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   154
Emscripten_OpenDevice(_THIS, const char *devname, int iscapture)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   155
{
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   156
    SDL_bool valid_format = SDL_FALSE;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   157
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   158
    int i;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   159
    float f;
9344
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   160
    int result;
9278
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   161
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   162
    while ((!valid_format) && (test_format)) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   163
        switch (test_format) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   164
        case AUDIO_F32: /* web audio only supports floats */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   165
            this->spec.format = test_format;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   166
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   167
            valid_format = SDL_TRUE;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   168
            break;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   169
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   170
        test_format = SDL_NextAudioFormat();
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   171
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   172
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   173
    if (!valid_format) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   174
        /* Didn't find a compatible format :( */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   175
        return SDL_SetError("No compatible audio format!");
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   176
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   177
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   178
    /* Initialize all variables that we clean on shutdown */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   179
    this->hidden = (struct SDL_PrivateAudioData *)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   180
        SDL_malloc((sizeof *this->hidden));
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   181
    if (this->hidden == NULL) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   182
        return SDL_OutOfMemory();
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   183
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   184
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   185
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   186
    /* based on parts of library_sdl.js */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   187
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   188
    /* create context (TODO: this puts stuff in the global namespace...)*/
9344
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   189
    result = EM_ASM_INT_V({
9278
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   190
        if(typeof(SDL2) === 'undefined')
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   191
            SDL2 = {};
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   192
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   193
        if(typeof(SDL2.audio) === 'undefined')
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   194
            SDL2.audio = {};
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   195
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   196
        if (!SDL2.audioContext) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   197
            if (typeof(AudioContext) !== 'undefined') {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   198
                SDL2.audioContext = new AudioContext();
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   199
            } else if (typeof(webkitAudioContext) !== 'undefined') {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   200
                SDL2.audioContext = new webkitAudioContext();
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   201
            } else {
9344
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   202
                return -1;
9278
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   203
            }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   204
        }
9344
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   205
        return 0;
9278
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   206
    });
9344
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   207
    if (result < 0) {
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   208
        return SDL_SetError("Web Audio API is not available!");
83f4ab8fb0b8 Emscripten: Fixed throwing JavaScript exception if no audio context available.
Philipp Wiesemann <philipp.wiesemann@arcor.de>
parents: 9291
diff changeset
   209
    }
9278
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   210
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   211
    /* limit to native freq */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   212
    int sampleRate = EM_ASM_INT_V({
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   213
        return SDL2.audioContext['sampleRate'];
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   214
    });
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   215
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   216
    if(this->spec.freq != sampleRate) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   217
        for (i = this->spec.samples; i > 0; i--) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   218
            f = (float)i / (float)sampleRate * (float)this->spec.freq;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   219
            if (SDL_floor(f) == f) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   220
                this->hidden->conv_in_len = SDL_floor(f);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   221
                break;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   222
            }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   223
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   224
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   225
        this->spec.freq = sampleRate;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   226
    }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   227
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   228
    SDL_CalculateAudioSpec(&this->spec);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   229
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   230
    /* setup a ScriptProcessorNode */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   231
    EM_ASM_ARGS({
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   232
        SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   233
        SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   234
            SDL2.audio.currentOutputBuffer = e['outputBuffer'];
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   235
            Runtime.dynCall('vi', $2, [$3]);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   236
        };
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   237
        SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   238
    }, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   239
    return 0;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   240
}
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   241
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   242
static int
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   243
Emscripten_Init(SDL_AudioDriverImpl * impl)
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   244
{
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   245
    /* Set the function pointers */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   246
    impl->OpenDevice = Emscripten_OpenDevice;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   247
    impl->CloseDevice = Emscripten_CloseDevice;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   248
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   249
    /* only one output */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   250
    impl->OnlyHasDefaultOutputDevice = 1;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   251
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   252
    /* no threads here */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   253
    impl->SkipMixerLock = 1;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   254
    impl->ProvidesOwnCallbackThread = 1;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   255
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   256
    /* check availability */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   257
    int available = EM_ASM_INT_V({
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   258
        if (typeof(AudioContext) !== 'undefined') {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   259
            return 1;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   260
        } else if (typeof(webkitAudioContext) !== 'undefined') {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   261
            return 1;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   262
        }
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   263
        return 0;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   264
    });
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   265
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   266
    return available;
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   267
}
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   268
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   269
AudioBootStrap EmscriptenAudio_bootstrap = {
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   270
    "emscripten", "SDL emscripten audio driver", Emscripten_Init, 0
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   271
};
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   272
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   273
#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   274
8900afb78a19 Initial merge of Emscripten port!
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   275
/* vi: set ts=4 sw=4 expandtab: */