src/audio/baudio/SDL_beaudio.cc
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Mar 2013 20:12:40 -0800
changeset 6977 b73d51026c68
parent 6885 700f1b25f77f
child 7038 7f22b9ba218f
permissions -rw-r--r--
Changed the name of SDL_mutexP() SDL_mutexV()
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 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     /* 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 
    73 static void
    74 BEOSAUDIO_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 static int
    89 BEOSAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
    90 {
    91     int valid_datatype = 0;
    92     media_raw_audio_format format;
    93     SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
    94 
    95     /* Initialize all variables that we clean on shutdown */
    96     _this->hidden = new SDL_PrivateAudioData;
    97     if (_this->hidden == NULL) {
    98         SDL_OutOfMemory();
    99         return 0;
   100     }
   101     SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
   102 
   103     /* Parse the audio format and fill the Be raw audio format */
   104     SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
   105     format.byte_order = B_MEDIA_LITTLE_ENDIAN;
   106     format.frame_rate = (float) _this->spec.freq;
   107     format.channel_count = _this->spec.channels;        /* !!! FIXME: support > 2? */
   108     while ((!valid_datatype) && (test_format)) {
   109         valid_datatype = 1;
   110         _this->spec.format = test_format;
   111         switch (test_format) {
   112         case AUDIO_S8:
   113             format.format = media_raw_audio_format::B_AUDIO_CHAR;
   114             break;
   115 
   116         case AUDIO_U8:
   117             format.format = media_raw_audio_format::B_AUDIO_UCHAR;
   118             break;
   119 
   120         case AUDIO_S16LSB:
   121             format.format = media_raw_audio_format::B_AUDIO_SHORT;
   122             break;
   123 
   124         case AUDIO_S16MSB:
   125             format.format = media_raw_audio_format::B_AUDIO_SHORT;
   126             format.byte_order = B_MEDIA_BIG_ENDIAN;
   127             break;
   128 
   129         case AUDIO_S32LSB:
   130             format.format = media_raw_audio_format::B_AUDIO_INT;
   131             break;
   132 
   133         case AUDIO_S32MSB:
   134             format.format = media_raw_audio_format::B_AUDIO_INT;
   135             format.byte_order = B_MEDIA_BIG_ENDIAN;
   136             break;
   137 
   138         case AUDIO_F32LSB:
   139             format.format = media_raw_audio_format::B_AUDIO_FLOAT;
   140             break;
   141 
   142         case AUDIO_F32MSB:
   143             format.format = media_raw_audio_format::B_AUDIO_FLOAT;
   144             format.byte_order = B_MEDIA_BIG_ENDIAN;
   145             break;
   146 
   147         default:
   148             valid_datatype = 0;
   149             test_format = SDL_NextAudioFormat();
   150             break;
   151         }
   152     }
   153 
   154     if (!valid_datatype) {      /* shouldn't happen, but just in case... */
   155         BEOSAUDIO_CloseDevice(_this);
   156         SDL_SetError("Unsupported audio format");
   157         return 0;
   158     }
   159 
   160     /* Calculate the final parameters for this audio specification */
   161     SDL_CalculateAudioSpec(&_this->spec);
   162 
   163     format.buffer_size = _this->spec.size;
   164 
   165     /* Subscribe to the audio stream (creates a new thread) */
   166     sigset_t omask;
   167     SDL_MaskSignals(&omask);
   168     _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
   169                                                 FillSound, NULL, _this);
   170     SDL_UnmaskSignals(&omask);
   171 
   172     if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
   173         _this->hidden->audio_obj->SetHasData(true);
   174     } else {
   175         BEOSAUDIO_CloseDevice(_this);
   176         SDL_SetError("Unable to start Be audio");
   177         return 0;
   178     }
   179 
   180     /* We're running! */
   181     return 1;
   182 }
   183 
   184 static void
   185 BEOSAUDIO_Deinitialize(void)
   186 {
   187     SDL_QuitBeApp();
   188 }
   189 
   190 static int
   191 BEOSAUDIO_Init(SDL_AudioDriverImpl * impl)
   192 {
   193     /* Initialize the Be Application, if it's not already started */
   194     if (SDL_InitBeApp() < 0) {
   195         return 0;
   196     }
   197 
   198     /* Set the function pointers */
   199     impl->OpenDevice = BEOSAUDIO_OpenDevice;
   200     impl->CloseDevice = BEOSAUDIO_CloseDevice;
   201     impl->Deinitialize = BEOSAUDIO_Deinitialize;
   202     impl->ProvidesOwnCallbackThread = 1;
   203     impl->OnlyHasDefaultOutputDevice = 1;
   204 
   205     return 1;   /* this audio target is available. */
   206 }
   207 
   208 extern "C"
   209 {
   210     extern AudioBootStrap BEOSAUDIO_bootstrap;
   211 }
   212 AudioBootStrap BEOSAUDIO_bootstrap = {
   213     "baudio", "BeOS BSoundPlayer", BEOSAUDIO_Init, 0
   214 };
   215 
   216 #endif /* SDL_AUDIO_DRIVER_BEOSAUDIO */
   217 
   218 /* vi: set ts=4 sw=4 expandtab: */