src/audio/baudio/SDL_beaudio.cc
author Ryan C. Gordon <icculus@icculus.org>
Sat, 07 Oct 2006 19:56:47 +0000
branchSDL-ryan-multiple-audio-device
changeset 3830 29e83f221c62
parent 3819 b225d9820ee3
child 3837 7c9663fb0860
permissions -rw-r--r--
Fixed some things to use SDL C runtime functions.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1403
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* Allow access to the audio stream on BeOS */
slouken@0
    25
slouken@0
    26
#include <SoundPlayer.h>
slouken@0
    27
slouken@1367
    28
#include "../../main/beos/SDL_BeApp.h"
slouken@0
    29
slouken@1895
    30
extern "C"
slouken@1895
    31
{
slouken@0
    32
slouken@0
    33
#include "SDL_audio.h"
slouken@1361
    34
#include "../SDL_audio_c.h"
slouken@1361
    35
#include "../SDL_sysaudio.h"
slouken@1367
    36
#include "../../thread/beos/SDL_systhread_c.h"
slouken@0
    37
#include "SDL_beaudio.h"
slouken@0
    38
icculus@3819
    39
}
slouken@0
    40
slouken@0
    41
icculus@3819
    42
static int BEAUDIO_Available(void)
icculus@3819
    43
{
icculus@3819
    44
    return 1;  /* Always available on BeOS. */
icculus@3819
    45
}
slouken@0
    46
slouken@0
    47
icculus@3819
    48
/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
icculus@3819
    49
/* The BeOS callback for handling the audio buffer */
icculus@3819
    50
static void
icculus@3819
    51
FillSound(void *device, void *stream, size_t len,
icculus@3819
    52
          const media_raw_audio_format & format)
icculus@3819
    53
{
icculus@3819
    54
    SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
slouken@0
    55
icculus@3819
    56
    /* Silence the buffer, since it's ours */
icculus@3819
    57
    SDL_memset(stream, audio->spec.silence, len);
slouken@0
    58
icculus@3819
    59
    /* Only do soemthing if audio is enabled */
icculus@3819
    60
    if (!audio->enabled)
icculus@3819
    61
        return;
slouken@0
    62
icculus@3819
    63
    if (!audio->paused) {
icculus@3819
    64
        if (audio->convert.needed) {
icculus@3819
    65
            SDL_mutexP(audio->mixer_lock);
icculus@3819
    66
            (*audio->spec.callback) (audio->spec.userdata,
slouken@1895
    67
                                         (Uint8 *) audio->convert.buf,
slouken@1895
    68
                                         audio->convert.len);
icculus@3819
    69
            SDL_mutexV(audio->mixer_lock);
icculus@3819
    70
            SDL_ConvertAudio(&audio->convert);
icculus@3819
    71
            SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
icculus@3819
    72
        } else {
icculus@3819
    73
            SDL_mutexP(audio->mixer_lock);
icculus@3819
    74
            (*audio->spec.callback) (audio->spec.userdata,
icculus@3819
    75
                                        (Uint8 *) stream, len);
icculus@3819
    76
            SDL_mutexV(audio->mixer_lock);
slouken@1895
    77
        }
slouken@1895
    78
    }
icculus@3819
    79
}
slouken@0
    80
icculus@3819
    81
static void
icculus@3819
    82
BEAUDIO_CloseDevice(_THIS)
icculus@3819
    83
{
icculus@3819
    84
    if (_this->hidden != NULL) {
icculus@3819
    85
        if (_this->hidden->audio_obj) {
icculus@3819
    86
            _this->hidden->audio_obj->Stop();
icculus@3819
    87
            delete _this->hidden->audio_obj;
icculus@3819
    88
            _this->hidden->audio_obj = NULL;
icculus@3819
    89
        }
slouken@0
    90
icculus@3819
    91
        delete _this->hidden;
icculus@3819
    92
        _this->hidden = NULL;
slouken@0
    93
slouken@1895
    94
        /* Quit the Be Application, if there's nothing left to do */
slouken@1895
    95
        SDL_QuitBeApp();
slouken@1895
    96
    }
icculus@3819
    97
}
slouken@0
    98
icculus@3819
    99
static int
icculus@3819
   100
BEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
icculus@3819
   101
{
icculus@3819
   102
    int valid_datatype = 0;
icculus@3819
   103
    media_raw_audio_format format;
icculus@3819
   104
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
icculus@1997
   105
icculus@3819
   106
    /* Initialize all variables that we clean on shutdown */
icculus@3819
   107
    _this->hidden = new SDL_PrivateAudioData;
icculus@3819
   108
    if (_this->hidden == NULL) {
icculus@3819
   109
        SDL_OutOfMemory();
icculus@3819
   110
        return 0;
icculus@3819
   111
    }
icculus@3819
   112
    SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
icculus@3819
   113
icculus@3819
   114
    /* Initialize the Be Application, if it's not already started */
icculus@3819
   115
    if (SDL_InitBeApp() < 0) {
icculus@3819
   116
        return 0;
icculus@3819
   117
    }
icculus@3819
   118
icculus@3819
   119
    /* Parse the audio format and fill the Be raw audio format */
icculus@3830
   120
    SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
icculus@3819
   121
    format.byte_order = B_MEDIA_LITTLE_ENDIAN;
icculus@3819
   122
    format.frame_rate = (float) this->spec.freq;
icculus@3819
   123
    format.channel_count = this->spec.channels;  /* !!! FIXME: support > 2? */
icculus@3819
   124
    while ((!valid_datatype) && (test_format)) {
icculus@3819
   125
        valid_datatype = 1;
icculus@3819
   126
        this->spec.format = test_format;
icculus@3819
   127
        switch (test_format) {
slouken@2043
   128
            case AUDIO_S8:
slouken@2043
   129
                format.format = media_raw_audio_format::B_AUDIO_CHAR;
slouken@2043
   130
                break;
icculus@1997
   131
slouken@2043
   132
            case AUDIO_U8:
slouken@2043
   133
                format.format = media_raw_audio_format::B_AUDIO_UCHAR;
slouken@2043
   134
                break;
icculus@1997
   135
slouken@2043
   136
            case AUDIO_S16LSB:
slouken@2043
   137
                format.format = media_raw_audio_format::B_AUDIO_SHORT;
slouken@2043
   138
                break;
icculus@1997
   139
slouken@2043
   140
            case AUDIO_S16MSB:
slouken@2043
   141
                format.format = media_raw_audio_format::B_AUDIO_SHORT;
slouken@2043
   142
                format.byte_order = B_MEDIA_BIG_ENDIAN;
slouken@2043
   143
                break;
icculus@1997
   144
slouken@2043
   145
            case AUDIO_S32LSB:
slouken@2043
   146
                format.format = media_raw_audio_format::B_AUDIO_INT;
slouken@2043
   147
                break;
icculus@1997
   148
slouken@2043
   149
            case AUDIO_S32MSB:
slouken@2043
   150
                format.format = media_raw_audio_format::B_AUDIO_INT;
slouken@2043
   151
                format.byte_order = B_MEDIA_BIG_ENDIAN;
slouken@2043
   152
                break;
icculus@1997
   153
slouken@2043
   154
            case AUDIO_F32LSB:
slouken@2043
   155
                format.format = media_raw_audio_format::B_AUDIO_FLOAT;
slouken@2043
   156
                break;
icculus@1997
   157
slouken@2043
   158
            case AUDIO_F32MSB:
slouken@2043
   159
                format.format = media_raw_audio_format::B_AUDIO_FLOAT;
slouken@2043
   160
                format.byte_order = B_MEDIA_BIG_ENDIAN;
slouken@2043
   161
                break;
icculus@1997
   162
slouken@2043
   163
            default:
slouken@2043
   164
                valid_datatype = 0;
slouken@2043
   165
                test_format = SDL_NextAudioFormat();
slouken@2043
   166
                break;
icculus@1997
   167
        }
slouken@1895
   168
    }
slouken@1895
   169
icculus@3819
   170
    format.buffer_size = this->spec.samples;
icculus@3819
   171
icculus@3819
   172
    if (!valid_datatype) {  /* shouldn't happen, but just in case... */
icculus@3819
   173
        SDL_SetError("Unsupported audio format");
icculus@3819
   174
        return 0;
icculus@3819
   175
    }
icculus@3819
   176
icculus@3819
   177
    /* Calculate the final parameters for this audio specification */
icculus@3819
   178
    SDL_CalculateAudioSpec(&this->spec);
icculus@3819
   179
icculus@3819
   180
    /* Subscribe to the audio stream (creates a new thread) */
icculus@3819
   181
    sigset_t omask;
icculus@3819
   182
    SDL_MaskSignals(&omask);
icculus@3819
   183
    _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
icculus@3819
   184
                                                FillSound, NULL, _this);
icculus@3819
   185
    SDL_UnmaskSignals(&omask);
icculus@3819
   186
icculus@3819
   187
    if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
icculus@3819
   188
        _this->hidden->audio_obj->SetHasData(true);
icculus@3819
   189
    } else {
icculus@3819
   190
        SDL_SetError("Unable to start Be audio");
icculus@3819
   191
        return 0;
icculus@3819
   192
    }
icculus@3819
   193
icculus@3819
   194
    /* We're running! */
icculus@3819
   195
    return 1;
icculus@3819
   196
}
icculus@3819
   197
icculus@3819
   198
static int
icculus@3819
   199
BEAUDIO_Init(SDL_AudioDriverImpl *impl)
icculus@3819
   200
{
icculus@3819
   201
    /* Set the function pointers */
icculus@3819
   202
    impl->OpenDevice = DSP_OpenDevice;
icculus@3819
   203
    impl->CloseDevice = DSP_CloseDevice;
icculus@3819
   204
    impl->ProvidesOwnCallbackThread = 1;
icculus@3819
   205
    impl->OnlyHasDefaultOutputDevice = 1;
icculus@3819
   206
icculus@3819
   207
    return 1;
icculus@3819
   208
}
icculus@3819
   209
icculus@3819
   210
icculus@3819
   211
AudioBootStrap BEAUDIO_bootstrap = {
icculus@3819
   212
    "baudio", "BeOS BSoundPlayer",
icculus@3819
   213
    BEAUDIO_Available, BEAUDIO_Init, 0
icculus@3819
   214
};
slouken@1895
   215
slouken@1895
   216
/* vi: set ts=4 sw=4 expandtab: */