src/audio/baudio/SDL_beaudio.cc
author Sam Lantinga <slouken@libsdl.org>
Mon, 31 Oct 2011 05:56:58 -0400
changeset 6044 35448a5ea044
parent 5535 96594ac5fd1a
child 6138 4c64952a58fb
permissions -rw-r--r--
Lots of fixes importing SDL source wholesale into a new iOS project
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 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_config.h"
    22 
    23 #if SDL_AUDIO_DRIVER_BEOSAUDIO
    24 
    25 /* Allow access to the audio stream on BeOS */
    26 
    27 #include <SoundPlayer.h>
    28 
    29 #include "../../main/beos/SDL_BeApp.h"
    30 
    31 extern "C"
    32 {
    33 
    34 #include "SDL_audio.h"
    35 #include "../SDL_audio_c.h"
    36 #include "../SDL_sysaudio.h"
    37 #include "../../thread/beos/SDL_systhread_c.h"
    38 #include "SDL_beaudio.h"
    39 
    40 }
    41 
    42 
    43 /* !!! FIXME: have the callback call the higher level to avoid code dupe. */
    44 /* The BeOS callback for handling the audio buffer */
    45 static void
    46 FillSound(void *device, void *stream, size_t len,
    47           const media_raw_audio_format & format)
    48 {
    49     SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
    50 
    51     /* Silence the buffer, since it's ours */
    52     SDL_memset(stream, audio->spec.silence, len);
    53 
    54     /* Only do soemthing if audio is enabled */
    55     if (!audio->enabled)
    56         return;
    57 
    58     if (!audio->paused) {
    59         if (audio->convert.needed) {
    60             SDL_mutexP(audio->mixer_lock);
    61             (*audio->spec.callback) (audio->spec.userdata,
    62                                      (Uint8 *) audio->convert.buf,
    63                                      audio->convert.len);
    64             SDL_mutexV(audio->mixer_lock);
    65             SDL_ConvertAudio(&audio->convert);
    66             SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
    67         } else {
    68             SDL_mutexP(audio->mixer_lock);
    69             (*audio->spec.callback) (audio->spec.userdata,
    70                                      (Uint8 *) stream, len);
    71             SDL_mutexV(audio->mixer_lock);
    72         }
    73     }
    74 }
    75 
    76 static void
    77 BEOSAUDIO_CloseDevice(_THIS)
    78 {
    79     if (_this->hidden != NULL) {
    80         if (_this->hidden->audio_obj) {
    81             _this->hidden->audio_obj->Stop();
    82             delete _this->hidden->audio_obj;
    83             _this->hidden->audio_obj = NULL;
    84         }
    85 
    86         delete _this->hidden;
    87         _this->hidden = NULL;
    88     }
    89 }
    90 
    91 static int
    92 BEOSAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
    93 {
    94     int valid_datatype = 0;
    95     media_raw_audio_format format;
    96     SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
    97 
    98     /* Initialize all variables that we clean on shutdown */
    99     _this->hidden = new SDL_PrivateAudioData;
   100     if (_this->hidden == NULL) {
   101         SDL_OutOfMemory();
   102         return 0;
   103     }
   104     SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
   105 
   106     /* Parse the audio format and fill the Be raw audio format */
   107     SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
   108     format.byte_order = B_MEDIA_LITTLE_ENDIAN;
   109     format.frame_rate = (float) _this->spec.freq;
   110     format.channel_count = _this->spec.channels;        /* !!! FIXME: support > 2? */
   111     while ((!valid_datatype) && (test_format)) {
   112         valid_datatype = 1;
   113         _this->spec.format = test_format;
   114         switch (test_format) {
   115         case AUDIO_S8:
   116             format.format = media_raw_audio_format::B_AUDIO_CHAR;
   117             break;
   118 
   119         case AUDIO_U8:
   120             format.format = media_raw_audio_format::B_AUDIO_UCHAR;
   121             break;
   122 
   123         case AUDIO_S16LSB:
   124             format.format = media_raw_audio_format::B_AUDIO_SHORT;
   125             break;
   126 
   127         case AUDIO_S16MSB:
   128             format.format = media_raw_audio_format::B_AUDIO_SHORT;
   129             format.byte_order = B_MEDIA_BIG_ENDIAN;
   130             break;
   131 
   132         case AUDIO_S32LSB:
   133             format.format = media_raw_audio_format::B_AUDIO_INT;
   134             break;
   135 
   136         case AUDIO_S32MSB:
   137             format.format = media_raw_audio_format::B_AUDIO_INT;
   138             format.byte_order = B_MEDIA_BIG_ENDIAN;
   139             break;
   140 
   141         case AUDIO_F32LSB:
   142             format.format = media_raw_audio_format::B_AUDIO_FLOAT;
   143             break;
   144 
   145         case AUDIO_F32MSB:
   146             format.format = media_raw_audio_format::B_AUDIO_FLOAT;
   147             format.byte_order = B_MEDIA_BIG_ENDIAN;
   148             break;
   149 
   150         default:
   151             valid_datatype = 0;
   152             test_format = SDL_NextAudioFormat();
   153             break;
   154         }
   155     }
   156 
   157     format.buffer_size = _this->spec.samples;
   158 
   159     if (!valid_datatype) {      /* shouldn't happen, but just in case... */
   160         BEOSAUDIO_CloseDevice(_this);
   161         SDL_SetError("Unsupported audio format");
   162         return 0;
   163     }
   164 
   165     /* Calculate the final parameters for this audio specification */
   166     SDL_CalculateAudioSpec(&_this->spec);
   167 
   168     /* Subscribe to the audio stream (creates a new thread) */
   169     sigset_t omask;
   170     SDL_MaskSignals(&omask);
   171     _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
   172                                                 FillSound, NULL, _this);
   173     SDL_UnmaskSignals(&omask);
   174 
   175     if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
   176         _this->hidden->audio_obj->SetHasData(true);
   177     } else {
   178         BEOSAUDIO_CloseDevice(_this);
   179         SDL_SetError("Unable to start Be audio");
   180         return 0;
   181     }
   182 
   183     /* We're running! */
   184     return 1;
   185 }
   186 
   187 static void
   188 BEOSAUDIO_Deinitialize(void)
   189 {
   190     SDL_QuitBeApp();
   191 }
   192 
   193 static int
   194 BEOSAUDIO_Init(SDL_AudioDriverImpl * impl)
   195 {
   196     /* Initialize the Be Application, if it's not already started */
   197     if (SDL_InitBeApp() < 0) {
   198         return 0;
   199     }
   200 
   201     /* Set the function pointers */
   202     impl->OpenDevice = BEOSAUDIO_OpenDevice;
   203     impl->CloseDevice = BEOSAUDIO_CloseDevice;
   204     impl->Deinitialize = BEOSAUDIO_Deinitialize;
   205     impl->ProvidesOwnCallbackThread = 1;
   206     impl->OnlyHasDefaultOutputDevice = 1;
   207 
   208     return 1;   /* this audio target is available. */
   209 }
   210 
   211 extern "C"
   212 {
   213     extern AudioBootStrap BEOSAUDIO_bootstrap;
   214 }
   215 AudioBootStrap BEOSAUDIO_bootstrap = {
   216     "baudio", "BeOS BSoundPlayer", BEOSAUDIO_Init, 0
   217 };
   218 
   219 #endif /* SDL_AUDIO_DRIVER_BEOSAUDIO */
   220 
   221 /* vi: set ts=4 sw=4 expandtab: */