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