cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_haikuaudio.cc (6937B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
      4
      5  This software is provided 'as-is', without any express or implied
      6  warranty.  In no event will the authors be held liable for any damages
      7  arising from the use of this software.
      8
      9  Permission is granted to anyone to use this software for any purpose,
     10  including commercial applications, and to alter it and redistribute it
     11  freely, subject to the following restrictions:
     12
     13  1. The origin of this software must not be misrepresented; you must not
     14     claim that you wrote the original software. If you use this software
     15     in a product, an acknowledgment in the product documentation would be
     16     appreciated but is not required.
     17  2. Altered source versions must be plainly marked as such, and must not be
     18     misrepresented as being the original software.
     19  3. This notice may not be removed or altered from any source distribution.
     20*/
     21#include "../../SDL_internal.h"
     22
     23#if SDL_AUDIO_DRIVER_HAIKU
     24
     25/* Allow access to the audio stream on Haiku */
     26
     27#include <SoundPlayer.h>
     28#include <signal.h>
     29
     30#include "../../main/haiku/SDL_BeApp.h"
     31
     32extern "C"
     33{
     34
     35#include "SDL_audio.h"
     36#include "../SDL_audio_c.h"
     37#include "../SDL_sysaudio.h"
     38#include "SDL_haikuaudio.h"
     39
     40}
     41
     42
     43/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
     44/* The Haiku callback for handling the audio buffer */
     45static void
     46FillSound(void *device, void *stream, size_t len,
     47          const media_raw_audio_format & format)
     48{
     49    SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
     50
     51    /* Only do soemthing if audio is enabled */
     52    if (!audio->enabled)
     53        return;
     54
     55    if (!audio->paused) {
     56        if (audio->convert.needed) {
     57            SDL_LockMutex(audio->mixer_lock);
     58            (*audio->spec.callback) (audio->spec.userdata,
     59                                     (Uint8 *) audio->convert.buf,
     60                                     audio->convert.len);
     61            SDL_UnlockMutex(audio->mixer_lock);
     62            SDL_ConvertAudio(&audio->convert);
     63            SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
     64        } else {
     65            SDL_LockMutex(audio->mixer_lock);
     66            (*audio->spec.callback) (audio->spec.userdata,
     67                                     (Uint8 *) stream, len);
     68            SDL_UnlockMutex(audio->mixer_lock);
     69        }
     70    }
     71}
     72
     73static void
     74HAIKUAUDIO_CloseDevice(_THIS)
     75{
     76    if (_this->hidden != NULL) {
     77        if (_this->hidden->audio_obj) {
     78            _this->hidden->audio_obj->Stop();
     79            delete _this->hidden->audio_obj;
     80            _this->hidden->audio_obj = NULL;
     81        }
     82
     83        delete _this->hidden;
     84        _this->hidden = NULL;
     85    }
     86}
     87
     88
     89static const int sig_list[] = {
     90    SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0
     91};
     92
     93static inline void
     94MaskSignals(sigset_t * omask)
     95{
     96    sigset_t mask;
     97    int i;
     98
     99    sigemptyset(&mask);
    100    for (i = 0; sig_list[i]; ++i) {
    101        sigaddset(&mask, sig_list[i]);
    102    }
    103    sigprocmask(SIG_BLOCK, &mask, omask);
    104}
    105
    106static inline void
    107UnmaskSignals(sigset_t * omask)
    108{
    109    sigprocmask(SIG_SETMASK, omask, NULL);
    110}
    111
    112
    113static int
    114HAIKUAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
    115{
    116    int valid_datatype = 0;
    117    media_raw_audio_format format;
    118    SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
    119
    120    /* Initialize all variables that we clean on shutdown */
    121    _this->hidden = new SDL_PrivateAudioData;
    122    if (_this->hidden == NULL) {
    123        return SDL_OutOfMemory();
    124    }
    125    SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
    126
    127    /* Parse the audio format and fill the Be raw audio format */
    128    SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
    129    format.byte_order = B_MEDIA_LITTLE_ENDIAN;
    130    format.frame_rate = (float) _this->spec.freq;
    131    format.channel_count = _this->spec.channels;        /* !!! FIXME: support > 2? */
    132    while ((!valid_datatype) && (test_format)) {
    133        valid_datatype = 1;
    134        _this->spec.format = test_format;
    135        switch (test_format) {
    136        case AUDIO_S8:
    137            format.format = media_raw_audio_format::B_AUDIO_CHAR;
    138            break;
    139
    140        case AUDIO_U8:
    141            format.format = media_raw_audio_format::B_AUDIO_UCHAR;
    142            break;
    143
    144        case AUDIO_S16LSB:
    145            format.format = media_raw_audio_format::B_AUDIO_SHORT;
    146            break;
    147
    148        case AUDIO_S16MSB:
    149            format.format = media_raw_audio_format::B_AUDIO_SHORT;
    150            format.byte_order = B_MEDIA_BIG_ENDIAN;
    151            break;
    152
    153        case AUDIO_S32LSB:
    154            format.format = media_raw_audio_format::B_AUDIO_INT;
    155            break;
    156
    157        case AUDIO_S32MSB:
    158            format.format = media_raw_audio_format::B_AUDIO_INT;
    159            format.byte_order = B_MEDIA_BIG_ENDIAN;
    160            break;
    161
    162        case AUDIO_F32LSB:
    163            format.format = media_raw_audio_format::B_AUDIO_FLOAT;
    164            break;
    165
    166        case AUDIO_F32MSB:
    167            format.format = media_raw_audio_format::B_AUDIO_FLOAT;
    168            format.byte_order = B_MEDIA_BIG_ENDIAN;
    169            break;
    170
    171        default:
    172            valid_datatype = 0;
    173            test_format = SDL_NextAudioFormat();
    174            break;
    175        }
    176    }
    177
    178    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
    179        HAIKUAUDIO_CloseDevice(_this);
    180        return SDL_SetError("Unsupported audio format");
    181    }
    182
    183    /* Calculate the final parameters for this audio specification */
    184    SDL_CalculateAudioSpec(&_this->spec);
    185
    186    format.buffer_size = _this->spec.size;
    187
    188    /* Subscribe to the audio stream (creates a new thread) */
    189    sigset_t omask;
    190    MaskSignals(&omask);
    191    _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
    192                                                FillSound, NULL, _this);
    193    UnmaskSignals(&omask);
    194
    195    if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
    196        _this->hidden->audio_obj->SetHasData(true);
    197    } else {
    198        HAIKUAUDIO_CloseDevice(_this);
    199        return SDL_SetError("Unable to start Be audio");
    200    }
    201
    202    /* We're running! */
    203    return 0;
    204}
    205
    206static void
    207HAIKUAUDIO_Deinitialize(void)
    208{
    209    SDL_QuitBeApp();
    210}
    211
    212static int
    213HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl)
    214{
    215    /* Initialize the Be Application, if it's not already started */
    216    if (SDL_InitBeApp() < 0) {
    217        return 0;
    218    }
    219
    220    /* Set the function pointers */
    221    impl->OpenDevice = HAIKUAUDIO_OpenDevice;
    222    impl->CloseDevice = HAIKUAUDIO_CloseDevice;
    223    impl->Deinitialize = HAIKUAUDIO_Deinitialize;
    224    impl->ProvidesOwnCallbackThread = 1;
    225    impl->OnlyHasDefaultOutputDevice = 1;
    226
    227    return 1;   /* this audio target is available. */
    228}
    229
    230extern "C"
    231{
    232    extern AudioBootStrap HAIKUAUDIO_bootstrap;
    233}
    234AudioBootStrap HAIKUAUDIO_bootstrap = {
    235    "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, 0
    236};
    237
    238#endif /* SDL_AUDIO_DRIVER_HAIKU */
    239
    240/* vi: set ts=4 sw=4 expandtab: */