src/audio/baudio/SDL_beaudio.cc
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Dec 2001 12:38:15 +0000
changeset 252 e8157fcb3114
parent 114 dabc453ce7f7
child 1312 c9b51268668f
permissions -rw-r--r--
Updated the source with the correct e-mail address
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 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     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* Allow access to the audio stream on BeOS */
    29 
    30 #include <stdlib.h>
    31 #include <stdio.h>
    32 #include <string.h>
    33 #include <SoundPlayer.h>
    34 
    35 #include "SDL_BeApp.h"
    36 
    37 extern "C" {
    38 
    39 #include "SDL_audio.h"
    40 #include "SDL_audio_c.h"
    41 #include "SDL_sysaudio.h"
    42 #include "SDL_systhread_c.h"
    43 #include "SDL_beaudio.h"
    44 
    45 
    46 /* Audio driver functions */
    47 static int BE_OpenAudio(_THIS, SDL_AudioSpec *spec);
    48 static void BE_WaitAudio(_THIS);
    49 static void BE_PlayAudio(_THIS);
    50 static Uint8 *BE_GetAudioBuf(_THIS);
    51 static void BE_CloseAudio(_THIS);
    52 
    53 /* Audio driver bootstrap functions */
    54 
    55 static int Audio_Available(void)
    56 {
    57 	return(1);
    58 }
    59 
    60 static void Audio_DeleteDevice(SDL_AudioDevice *device)
    61 {
    62 	free(device->hidden);
    63 	free(device);
    64 }
    65 
    66 static SDL_AudioDevice *Audio_CreateDevice(int devindex)
    67 {
    68 	SDL_AudioDevice *device;
    69 
    70 	/* Initialize all variables that we clean on shutdown */
    71 	device = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
    72 	if ( device ) {
    73 		memset(device, 0, (sizeof *device));
    74 		device->hidden = (struct SDL_PrivateAudioData *)
    75 				malloc((sizeof *device->hidden));
    76 	}
    77 	if ( (device == NULL) || (device->hidden == NULL) ) {
    78 		SDL_OutOfMemory();
    79 		if ( device ) {
    80 			free(device);
    81 		}
    82 		return(0);
    83 	}
    84 	memset(device->hidden, 0, (sizeof *device->hidden));
    85 
    86 	/* Set the function pointers */
    87 	device->OpenAudio = BE_OpenAudio;
    88 	device->WaitAudio = BE_WaitAudio;
    89 	device->PlayAudio = BE_PlayAudio;
    90 	device->GetAudioBuf = BE_GetAudioBuf;
    91 	device->CloseAudio = BE_CloseAudio;
    92 
    93 	device->free = Audio_DeleteDevice;
    94 
    95 	return device;
    96 }
    97 
    98 AudioBootStrap BAUDIO_bootstrap = {
    99 	"baudio", "BeOS BSoundPlayer",
   100 	Audio_Available, Audio_CreateDevice
   101 };
   102 
   103 /* The BeOS callback for handling the audio buffer */
   104 static void FillSound(void *device, void *stream, size_t len, 
   105 					const media_raw_audio_format &format)
   106 {
   107 	SDL_AudioDevice *audio = (SDL_AudioDevice *)device;
   108 
   109 	/* Silence the buffer, since it's ours */
   110 	memset(stream, audio->spec.silence, len);
   111 
   112 	/* Only do soemthing if audio is enabled */
   113 	if ( ! audio->enabled )
   114 		return;
   115 
   116 	if ( ! audio->paused ) {
   117 		if ( audio->convert.needed ) {
   118 			SDL_mutexP(audio->mixer_lock);
   119 			(*audio->spec.callback)(audio->spec.userdata,
   120 				(Uint8 *)audio->convert.buf,audio->convert.len);
   121 			SDL_mutexV(audio->mixer_lock);
   122 			SDL_ConvertAudio(&audio->convert);
   123 			memcpy(stream,audio->convert.buf,audio->convert.len_cvt);
   124 		} else {
   125 			SDL_mutexP(audio->mixer_lock);
   126 			(*audio->spec.callback)(audio->spec.userdata,
   127 						(Uint8 *)stream, len);
   128 			SDL_mutexV(audio->mixer_lock);
   129 		}
   130 	}
   131 	return;
   132 }
   133 
   134 /* Dummy functions -- we don't use thread-based audio */
   135 void BE_WaitAudio(_THIS)
   136 {
   137 	return;
   138 }
   139 void BE_PlayAudio(_THIS)
   140 {
   141 	return;
   142 }
   143 Uint8 *BE_GetAudioBuf(_THIS)
   144 {
   145 	return(NULL);
   146 }
   147 
   148 void BE_CloseAudio(_THIS)
   149 {
   150 	if ( audio_obj ) {
   151 		audio_obj->Stop();
   152 		delete audio_obj;
   153 		audio_obj = NULL;
   154 	}
   155 
   156 	/* Quit the Be Application, if there's nothing left to do */
   157 	SDL_QuitBeApp();
   158 }
   159 
   160 int BE_OpenAudio(_THIS, SDL_AudioSpec *spec)
   161 {
   162 	media_raw_audio_format format;
   163 
   164 	/* Initialize the Be Application, if it's not already started */
   165 	if ( SDL_InitBeApp() < 0 ) {
   166 		return(-1);
   167 	}
   168 
   169 	/* Parse the audio format and fill the Be raw audio format */
   170 	format.frame_rate = (float)spec->freq;
   171 	format.channel_count = spec->channels;
   172 	switch (spec->format&~0x1000) {
   173 		case AUDIO_S8:
   174 			/* Signed 8-bit audio unsupported, convert to U8 */
   175 			spec->format = AUDIO_U8;
   176 		case AUDIO_U8:
   177 			format.format = media_raw_audio_format::B_AUDIO_UCHAR;
   178 			format.byte_order = 0;
   179 			break;
   180 		case AUDIO_U16:
   181 			/* Unsigned 16-bit audio unsupported, convert to S16 */
   182 			spec->format ^= 0x8000;
   183 		case AUDIO_S16:
   184 			format.format = media_raw_audio_format::B_AUDIO_SHORT;
   185 			if ( spec->format & 0x1000 ) {
   186 				format.byte_order = 1; /* Big endian */
   187 			} else {
   188 				format.byte_order = 2; /* Little endian */
   189 			}
   190 			break;
   191 	}
   192 	format.buffer_size = spec->samples;
   193 	
   194 	/* Calculate the final parameters for this audio specification */
   195 	SDL_CalculateAudioSpec(spec);
   196 
   197 	/* Subscribe to the audio stream (creates a new thread) */
   198 	{ sigset_t omask;
   199 		SDL_MaskSignals(&omask);
   200 		audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound,
   201 		                                                 NULL, _this);
   202 		SDL_UnmaskSignals(&omask);
   203 	}
   204 	if ( audio_obj->Start() == B_NO_ERROR ) {
   205 		audio_obj->SetHasData(true);
   206 	} else {
   207 		SDL_SetError("Unable to start Be audio");
   208 		return(-1);
   209 	}
   210 
   211 	/* We're running! */
   212 	return(1);
   213 }
   214 
   215 };	/* Extern C */