src/audio/baudio/SDL_beaudio.cc
author Sam Lantinga <slouken@libsdl.org>
Fri, 17 Feb 2006 08:43:23 +0000
changeset 1367 e440d5c488c1
parent 1361 19418e4422cb
child 1403 376665398b25
permissions -rw-r--r--
Fixes for BeOS and Solaris builds
     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 
    23 /* Allow access to the audio stream on BeOS */
    24 
    25 #include <SoundPlayer.h>
    26 
    27 #include "../../main/beos/SDL_BeApp.h"
    28 
    29 extern "C" {
    30 
    31 #include "SDL_audio.h"
    32 #include "../SDL_audio_c.h"
    33 #include "../SDL_sysaudio.h"
    34 #include "../../thread/beos/SDL_systhread_c.h"
    35 #include "SDL_beaudio.h"
    36 
    37 
    38 /* Audio driver functions */
    39 static int BE_OpenAudio(_THIS, SDL_AudioSpec *spec);
    40 static void BE_WaitAudio(_THIS);
    41 static void BE_PlayAudio(_THIS);
    42 static Uint8 *BE_GetAudioBuf(_THIS);
    43 static void BE_CloseAudio(_THIS);
    44 
    45 /* Audio driver bootstrap functions */
    46 
    47 static int Audio_Available(void)
    48 {
    49 	return(1);
    50 }
    51 
    52 static void Audio_DeleteDevice(SDL_AudioDevice *device)
    53 {
    54 	SDL_free(device->hidden);
    55 	SDL_free(device);
    56 }
    57 
    58 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
    59 {
    60 	SDL_AudioDevice *device;
    61 
    62 	/* Initialize all variables that we clean on shutdown */
    63 	device = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));
    64 	if ( device ) {
    65 		SDL_memset(device, 0, (sizeof *device));
    66 		device->hidden = (struct SDL_PrivateAudioData *)
    67 				SDL_malloc((sizeof *device->hidden));
    68 	}
    69 	if ( (device == NULL) || (device->hidden == NULL) ) {
    70 		SDL_OutOfMemory();
    71 		if ( device ) {
    72 			SDL_free(device);
    73 		}
    74 		return(0);
    75 	}
    76 	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
    77 
    78 	/* Set the function pointers */
    79 	device->OpenAudio = BE_OpenAudio;
    80 	device->WaitAudio = BE_WaitAudio;
    81 	device->PlayAudio = BE_PlayAudio;
    82 	device->GetAudioBuf = BE_GetAudioBuf;
    83 	device->CloseAudio = BE_CloseAudio;
    84 
    85 	device->free = Audio_DeleteDevice;
    86 
    87 	return device;
    88 }
    89 
    90 AudioBootStrap BAUDIO_bootstrap = {
    91 	"baudio", "BeOS BSoundPlayer",
    92 	Audio_Available, Audio_CreateDevice
    93 };
    94 
    95 /* The BeOS callback for handling the audio buffer */
    96 static void FillSound(void *device, void *stream, size_t len, 
    97 					const media_raw_audio_format &format)
    98 {
    99 	SDL_AudioDevice *audio = (SDL_AudioDevice *)device;
   100 
   101 	/* Silence the buffer, since it's ours */
   102 	SDL_memset(stream, audio->spec.silence, len);
   103 
   104 	/* Only do soemthing if audio is enabled */
   105 	if ( ! audio->enabled )
   106 		return;
   107 
   108 	if ( ! audio->paused ) {
   109 		if ( audio->convert.needed ) {
   110 			SDL_mutexP(audio->mixer_lock);
   111 			(*audio->spec.callback)(audio->spec.userdata,
   112 				(Uint8 *)audio->convert.buf,audio->convert.len);
   113 			SDL_mutexV(audio->mixer_lock);
   114 			SDL_ConvertAudio(&audio->convert);
   115 			SDL_memcpy(stream,audio->convert.buf,audio->convert.len_cvt);
   116 		} else {
   117 			SDL_mutexP(audio->mixer_lock);
   118 			(*audio->spec.callback)(audio->spec.userdata,
   119 						(Uint8 *)stream, len);
   120 			SDL_mutexV(audio->mixer_lock);
   121 		}
   122 	}
   123 	return;
   124 }
   125 
   126 /* Dummy functions -- we don't use thread-based audio */
   127 void BE_WaitAudio(_THIS)
   128 {
   129 	return;
   130 }
   131 void BE_PlayAudio(_THIS)
   132 {
   133 	return;
   134 }
   135 Uint8 *BE_GetAudioBuf(_THIS)
   136 {
   137 	return(NULL);
   138 }
   139 
   140 void BE_CloseAudio(_THIS)
   141 {
   142 	if ( audio_obj ) {
   143 		audio_obj->Stop();
   144 		delete audio_obj;
   145 		audio_obj = NULL;
   146 	}
   147 
   148 	/* Quit the Be Application, if there's nothing left to do */
   149 	SDL_QuitBeApp();
   150 }
   151 
   152 int BE_OpenAudio(_THIS, SDL_AudioSpec *spec)
   153 {
   154 	media_raw_audio_format format;
   155 
   156 	/* Initialize the Be Application, if it's not already started */
   157 	if ( SDL_InitBeApp() < 0 ) {
   158 		return(-1);
   159 	}
   160 
   161 	/* Parse the audio format and fill the Be raw audio format */
   162 	format.frame_rate = (float)spec->freq;
   163 	format.channel_count = spec->channels;
   164 	switch (spec->format&~0x1000) {
   165 		case AUDIO_S8:
   166 			/* Signed 8-bit audio unsupported, convert to U8 */
   167 			spec->format = AUDIO_U8;
   168 		case AUDIO_U8:
   169 			format.format = media_raw_audio_format::B_AUDIO_UCHAR;
   170 			format.byte_order = 0;
   171 			break;
   172 		case AUDIO_U16:
   173 			/* Unsigned 16-bit audio unsupported, convert to S16 */
   174 			spec->format ^= 0x8000;
   175 		case AUDIO_S16:
   176 			format.format = media_raw_audio_format::B_AUDIO_SHORT;
   177 			if ( spec->format & 0x1000 ) {
   178 				format.byte_order = 1; /* Big endian */
   179 			} else {
   180 				format.byte_order = 2; /* Little endian */
   181 			}
   182 			break;
   183 	}
   184 	format.buffer_size = spec->samples;
   185 	
   186 	/* Calculate the final parameters for this audio specification */
   187 	SDL_CalculateAudioSpec(spec);
   188 
   189 	/* Subscribe to the audio stream (creates a new thread) */
   190 	{ sigset_t omask;
   191 		SDL_MaskSignals(&omask);
   192 		audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound,
   193 		                                                 NULL, _this);
   194 		SDL_UnmaskSignals(&omask);
   195 	}
   196 	if ( audio_obj->Start() == B_NO_ERROR ) {
   197 		audio_obj->SetHasData(true);
   198 	} else {
   199 		SDL_SetError("Unable to start Be audio");
   200 		return(-1);
   201 	}
   202 
   203 	/* We're running! */
   204 	return(1);
   205 }
   206 
   207 };	/* Extern C */