src/audio/nacl/SDL_naclaudio.c
author Ryan C. Gordon
Sun, 28 Aug 2016 18:52:25 -0400
changeset 10288 d45b253d1174
parent 10281 2a002e96888f
child 10737 3406a0f8b041
permissions -rw-r--r--
nacl: Patched to compile.
gabomdq@8833
     1
/*
gabomdq@8833
     2
  Simple DirectMedia Layer
slouken@9998
     3
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
gabomdq@8833
     4
gabomdq@8833
     5
  This software is provided 'as-is', without any express or implied
gabomdq@8833
     6
  warranty.  In no event will the authors be held liable for any damages
gabomdq@8833
     7
  arising from the use of this software.
gabomdq@8833
     8
gabomdq@8833
     9
  Permission is granted to anyone to use this software for any purpose,
gabomdq@8833
    10
  including commercial applications, and to alter it and redistribute it
gabomdq@8833
    11
  freely, subject to the following restrictions:
gabomdq@8833
    12
gabomdq@8833
    13
  1. The origin of this software must not be misrepresented; you must not
gabomdq@8833
    14
     claim that you wrote the original software. If you use this software
gabomdq@8833
    15
     in a product, an acknowledgment in the product documentation would be
gabomdq@8833
    16
     appreciated but is not required.
gabomdq@8833
    17
  2. Altered source versions must be plainly marked as such, and must not be
gabomdq@8833
    18
     misrepresented as being the original software.
gabomdq@8833
    19
  3. This notice may not be removed or altered from any source distribution.
gabomdq@8833
    20
*/
gabomdq@8833
    21
gabomdq@8833
    22
#include "../../SDL_internal.h"
philipp@9332
    23
philipp@9332
    24
#if SDL_AUDIO_DRIVER_NACL
philipp@9332
    25
gabomdq@8833
    26
#include "SDL_naclaudio.h"
gabomdq@8833
    27
gabomdq@8833
    28
#include "SDL_audio.h"
gabomdq@8833
    29
#include "SDL_mutex.h"
gabomdq@8833
    30
#include "../SDL_audio_c.h"
gabomdq@8833
    31
#include "../SDL_audiodev_c.h"
gabomdq@8833
    32
gabomdq@8833
    33
#include "ppapi/c/pp_errors.h"
gabomdq@8833
    34
#include "ppapi/c/pp_instance.h"
gabomdq@8833
    35
#include "ppapi_simple/ps.h"
gabomdq@8833
    36
#include "ppapi_simple/ps_interface.h"
gabomdq@8833
    37
#include "ppapi_simple/ps_event.h"
gabomdq@8833
    38
gabomdq@8833
    39
/* The tag name used by NACL audio */
icculus@10281
    40
#define NACLAUDIO_DRIVER_NAME         "nacl"
gabomdq@8833
    41
gabomdq@8833
    42
#define SAMPLE_FRAME_COUNT 4096
gabomdq@8833
    43
gabomdq@8833
    44
/* Audio driver functions */
gabomdq@8833
    45
static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data);
gabomdq@8833
    46
gabomdq@8833
    47
/* FIXME: Make use of latency if needed */
gabomdq@8833
    48
static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data) {
gabomdq@8833
    49
    SDL_AudioDevice* _this = (SDL_AudioDevice*) data;
gabomdq@8833
    50
    
icculus@10234
    51
    SDL_LockMutex(private->mutex);  /* !!! FIXME: is this mutex necessary? */
gabomdq@8851
    52
icculus@10288
    53
    if (SDL_AtomicGet(&_this->enabled) && !SDL_AtomicGet(&_this->paused)) {
gabomdq@8851
    54
        if (_this->convert.needed) {
gabomdq@8851
    55
            SDL_LockMutex(_this->mixer_lock);
gabomdq@8851
    56
            (*_this->spec.callback) (_this->spec.userdata,
gabomdq@8851
    57
                                     (Uint8 *) _this->convert.buf,
gabomdq@8851
    58
                                     _this->convert.len);
gabomdq@8851
    59
            SDL_UnlockMutex(_this->mixer_lock);
gabomdq@8851
    60
            SDL_ConvertAudio(&_this->convert);
gabomdq@8851
    61
            SDL_memcpy(samples, _this->convert.buf, _this->convert.len_cvt);
gabomdq@8851
    62
        } else {
gabomdq@8851
    63
            SDL_LockMutex(_this->mixer_lock);
gabomdq@8851
    64
            (*_this->spec.callback) (_this->spec.userdata, (Uint8 *) samples, buffer_size);
gabomdq@8851
    65
            SDL_UnlockMutex(_this->mixer_lock);
gabomdq@8851
    66
        }
gabomdq@8851
    67
    } else {
icculus@10257
    68
        SDL_memset(samples, _this->spec.silence, buffer_size);
gabomdq@8851
    69
    }
gabomdq@8833
    70
    
icculus@10234
    71
    SDL_UnlockMutex(private->mutex);
gabomdq@8833
    72
}
gabomdq@8833
    73
icculus@10281
    74
static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
gabomdq@8833
    75
    const PPB_Core *core = PSInterfaceCore();
gabomdq@8833
    76
    const PPB_Audio *ppb_audio = PSInterfaceAudio();
gabomdq@8833
    77
    SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden;
gabomdq@8833
    78
    
gabomdq@8833
    79
    ppb_audio->StopPlayback(hidden->audio);
gabomdq@8833
    80
    SDL_DestroyMutex(hidden->mutex);
gabomdq@8833
    81
    core->ReleaseResource(hidden->audio);
gabomdq@8833
    82
}
gabomdq@8833
    83
gabomdq@8833
    84
static int
icculus@10281
    85
NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
gabomdq@8833
    86
    PP_Instance instance = PSGetInstanceId();
gabomdq@8833
    87
    const PPB_Audio *ppb_audio = PSInterfaceAudio();
gabomdq@8833
    88
    const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
gabomdq@8833
    89
    
gabomdq@8833
    90
    private = (SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *private));
gabomdq@8833
    91
    if (private == NULL) {
gabomdq@8833
    92
        SDL_OutOfMemory();
gabomdq@8833
    93
        return 0;
gabomdq@8833
    94
    }
gabomdq@8833
    95
    
gabomdq@8833
    96
    private->mutex = SDL_CreateMutex();
gabomdq@8833
    97
    _this->spec.freq = 44100;
gabomdq@8833
    98
    _this->spec.format = AUDIO_S16LSB;
gabomdq@8833
    99
    _this->spec.channels = 2;
gabomdq@8833
   100
    _this->spec.samples = ppb_audiocfg->RecommendSampleFrameCount(
gabomdq@8833
   101
        instance, 
gabomdq@8833
   102
        PP_AUDIOSAMPLERATE_44100, 
gabomdq@8833
   103
        SAMPLE_FRAME_COUNT);
gabomdq@8833
   104
    
gabomdq@8851
   105
    /* Calculate the final parameters for this audio specification */
gabomdq@8851
   106
    SDL_CalculateAudioSpec(&_this->spec);
gabomdq@8851
   107
    
gabomdq@8833
   108
    private->audio = ppb_audio->Create(
gabomdq@8833
   109
        instance,
gabomdq@8833
   110
        ppb_audiocfg->CreateStereo16Bit(instance, PP_AUDIOSAMPLERATE_44100, _this->spec.samples),
gabomdq@8833
   111
        nacl_audio_callback, 
gabomdq@8833
   112
        _this);
gabomdq@8833
   113
    
gabomdq@8833
   114
    /* Start audio playback while we are still on the main thread. */
gabomdq@8833
   115
    ppb_audio->StartPlayback(private->audio);
gabomdq@8833
   116
    
gabomdq@8833
   117
    return 1;
gabomdq@8833
   118
}
gabomdq@8833
   119
gabomdq@8833
   120
static int
icculus@10281
   121
NACLAUDIO_Init(SDL_AudioDriverImpl * impl)
gabomdq@8833
   122
{
gabomdq@8833
   123
    if (PSGetInstanceId() == 0) {
gabomdq@8833
   124
        return 0;
gabomdq@8833
   125
    }
gabomdq@8833
   126
    
gabomdq@8833
   127
    /* Set the function pointers */
icculus@10281
   128
    impl->OpenDevice = NACLAUDIO_OpenDevice;
icculus@10281
   129
    impl->CloseDevice = NACLAUDIO_CloseDevice;
gabomdq@8833
   130
    impl->OnlyHasDefaultOutputDevice = 1;
gabomdq@8833
   131
    impl->ProvidesOwnCallbackThread = 1;
gabomdq@8833
   132
    /*
icculus@10281
   133
     *    impl->WaitDevice = NACLAUDIO_WaitDevice;
icculus@10281
   134
     *    impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf;
icculus@10281
   135
     *    impl->PlayDevice = NACLAUDIO_PlayDevice;
icculus@10281
   136
     *    impl->Deinitialize = NACLAUDIO_Deinitialize;
gabomdq@8833
   137
     */
gabomdq@8833
   138
    
gabomdq@8833
   139
    return 1;
gabomdq@8833
   140
}
gabomdq@8833
   141
icculus@10281
   142
AudioBootStrap NACLAUDIO_bootstrap = {
icculus@10281
   143
    NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver",
icculus@10281
   144
    NACLAUDIO_Init, 0
gabomdq@8833
   145
};
philipp@9332
   146
philipp@9332
   147
#endif /* SDL_AUDIO_DRIVER_NACL */
philipp@9332
   148
philipp@9332
   149
/* vi: set ts=4 sw=4 expandtab: */