src/audio/SDL_audio.c
changeset 1895 c121d94672cb
parent 1794 5605a9820134
child 1901 f1828a500391
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
    35 #endif
    35 #endif
    36 
    36 
    37 /* Available audio drivers */
    37 /* Available audio drivers */
    38 static AudioBootStrap *bootstrap[] = {
    38 static AudioBootStrap *bootstrap[] = {
    39 #if SDL_AUDIO_DRIVER_BSD
    39 #if SDL_AUDIO_DRIVER_BSD
    40 	&BSD_AUDIO_bootstrap,
    40     &BSD_AUDIO_bootstrap,
    41 #endif
    41 #endif
    42 #if SDL_AUDIO_DRIVER_OSS
    42 #if SDL_AUDIO_DRIVER_OSS
    43 	&DSP_bootstrap,
    43     &DSP_bootstrap,
    44 	&DMA_bootstrap,
    44     &DMA_bootstrap,
    45 #endif
    45 #endif
    46 #if SDL_AUDIO_DRIVER_ALSA
    46 #if SDL_AUDIO_DRIVER_ALSA
    47 	&ALSA_bootstrap,
    47     &ALSA_bootstrap,
    48 #endif
    48 #endif
    49 #if SDL_AUDIO_DRIVER_QNXNTO
    49 #if SDL_AUDIO_DRIVER_QNXNTO
    50 	&QNXNTOAUDIO_bootstrap,
    50     &QNXNTOAUDIO_bootstrap,
    51 #endif
    51 #endif
    52 #if SDL_AUDIO_DRIVER_SUNAUDIO
    52 #if SDL_AUDIO_DRIVER_SUNAUDIO
    53 	&SUNAUDIO_bootstrap,
    53     &SUNAUDIO_bootstrap,
    54 #endif
    54 #endif
    55 #if SDL_AUDIO_DRIVER_DMEDIA
    55 #if SDL_AUDIO_DRIVER_DMEDIA
    56 	&DMEDIA_bootstrap,
    56     &DMEDIA_bootstrap,
    57 #endif
    57 #endif
    58 #if SDL_AUDIO_DRIVER_ARTS
    58 #if SDL_AUDIO_DRIVER_ARTS
    59 	&ARTS_bootstrap,
    59     &ARTS_bootstrap,
    60 #endif
    60 #endif
    61 #if SDL_AUDIO_DRIVER_ESD
    61 #if SDL_AUDIO_DRIVER_ESD
    62 	&ESD_bootstrap,
    62     &ESD_bootstrap,
    63 #endif
    63 #endif
    64 #if SDL_AUDIO_DRIVER_NAS
    64 #if SDL_AUDIO_DRIVER_NAS
    65 	&NAS_bootstrap,
    65     &NAS_bootstrap,
    66 #endif
    66 #endif
    67 #if SDL_AUDIO_DRIVER_DSOUND
    67 #if SDL_AUDIO_DRIVER_DSOUND
    68 	&DSOUND_bootstrap,
    68     &DSOUND_bootstrap,
    69 #endif
    69 #endif
    70 #if SDL_AUDIO_DRIVER_WAVEOUT
    70 #if SDL_AUDIO_DRIVER_WAVEOUT
    71 	&WAVEOUT_bootstrap,
    71     &WAVEOUT_bootstrap,
    72 #endif
    72 #endif
    73 #if SDL_AUDIO_DRIVER_PAUD
    73 #if SDL_AUDIO_DRIVER_PAUD
    74 	&Paud_bootstrap,
    74     &Paud_bootstrap,
    75 #endif
    75 #endif
    76 #if SDL_AUDIO_DRIVER_BAUDIO
    76 #if SDL_AUDIO_DRIVER_BAUDIO
    77 	&BAUDIO_bootstrap,
    77     &BAUDIO_bootstrap,
    78 #endif
    78 #endif
    79 #if SDL_AUDIO_DRIVER_COREAUDIO
    79 #if SDL_AUDIO_DRIVER_COREAUDIO
    80 	&COREAUDIO_bootstrap,
    80     &COREAUDIO_bootstrap,
    81 #endif
    81 #endif
    82 #if SDL_AUDIO_DRIVER_SNDMGR
    82 #if SDL_AUDIO_DRIVER_SNDMGR
    83 	&SNDMGR_bootstrap,
    83     &SNDMGR_bootstrap,
    84 #endif
    84 #endif
    85 #if SDL_AUDIO_DRIVER_AHI
    85 #if SDL_AUDIO_DRIVER_AHI
    86 	&AHI_bootstrap,
    86     &AHI_bootstrap,
    87 #endif
    87 #endif
    88 #if SDL_AUDIO_DRIVER_MINT
    88 #if SDL_AUDIO_DRIVER_MINT
    89 	&MINTAUDIO_GSXB_bootstrap,
    89     &MINTAUDIO_GSXB_bootstrap,
    90 	&MINTAUDIO_MCSN_bootstrap,
    90     &MINTAUDIO_MCSN_bootstrap,
    91 	&MINTAUDIO_STFA_bootstrap,
    91     &MINTAUDIO_STFA_bootstrap,
    92 	&MINTAUDIO_XBIOS_bootstrap,
    92     &MINTAUDIO_XBIOS_bootstrap,
    93 	&MINTAUDIO_DMA8_bootstrap,
    93     &MINTAUDIO_DMA8_bootstrap,
    94 #endif
    94 #endif
    95 #if SDL_AUDIO_DRIVER_DISK
    95 #if SDL_AUDIO_DRIVER_DISK
    96 	&DISKAUD_bootstrap,
    96     &DISKAUD_bootstrap,
    97 #endif
    97 #endif
    98 #if SDL_AUDIO_DRIVER_DUMMY
    98 #if SDL_AUDIO_DRIVER_DUMMY
    99 	&DUMMYAUD_bootstrap,
    99     &DUMMYAUD_bootstrap,
   100 #endif
   100 #endif
   101 #if SDL_AUDIO_DRIVER_DC
   101 #if SDL_AUDIO_DRIVER_DC
   102 	&DCAUD_bootstrap,
   102     &DCAUD_bootstrap,
   103 #endif
   103 #endif
   104 #if SDL_AUDIO_DRIVER_MMEAUDIO
   104 #if SDL_AUDIO_DRIVER_MMEAUDIO
   105 	&MMEAUDIO_bootstrap,
   105     &MMEAUDIO_bootstrap,
   106 #endif
   106 #endif
   107 #if SDL_AUDIO_DRIVER_DART
   107 #if SDL_AUDIO_DRIVER_DART
   108 	&DART_bootstrap,
   108     &DART_bootstrap,
   109 #endif
   109 #endif
   110 	NULL
   110     NULL
   111 };
   111 };
   112 SDL_AudioDevice *current_audio = NULL;
   112 SDL_AudioDevice *current_audio = NULL;
   113 
   113 
   114 /* Various local functions */
   114 /* Various local functions */
   115 int SDL_AudioInit(const char *driver_name);
   115 int SDL_AudioInit(const char *driver_name);
   118 #if SDL_AUDIO_DRIVER_AHI
   118 #if SDL_AUDIO_DRIVER_AHI
   119 static int audio_configured = 0;
   119 static int audio_configured = 0;
   120 #endif
   120 #endif
   121 
   121 
   122 /* The general mixing thread function */
   122 /* The general mixing thread function */
   123 int SDLCALL SDL_RunAudio(void *audiop)
   123 int SDLCALL
   124 {
   124 SDL_RunAudio(void *audiop)
   125 	SDL_AudioDevice *audio = (SDL_AudioDevice *)audiop;
   125 {
   126 	Uint8 *stream;
   126     SDL_AudioDevice *audio = (SDL_AudioDevice *) audiop;
   127 	int    stream_len;
   127     Uint8 *stream;
   128 	void  *udata;
   128     int stream_len;
   129 	void (SDLCALL *fill)(void *userdata,Uint8 *stream, int len);
   129     void *udata;
   130 	int    silence;
   130     void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
       
   131     int silence;
   131 #if SDL_AUDIO_DRIVER_AHI
   132 #if SDL_AUDIO_DRIVER_AHI
   132 	int started = 0;
   133     int started = 0;
   133 
   134 
   134 /* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
   135 /* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
   135 
   136 
   136 	D(bug("Task audio started audio struct:<%lx>...\n",audiop));
   137     D(bug("Task audio started audio struct:<%lx>...\n", audiop));
   137 
   138 
   138 	D(bug("Before Openaudio..."));
   139     D(bug("Before Openaudio..."));
   139 	if(audio->OpenAudio(audio, &audio->spec)==-1)
   140     if (audio->OpenAudio(audio, &audio->spec) == -1) {
   140 	{
   141         D(bug("Open audio failed...\n"));
   141 		D(bug("Open audio failed...\n"));
   142         return (-1);
   142 		return(-1);
   143     }
   143 	}
   144     D(bug("OpenAudio...OK\n"));
   144 	D(bug("OpenAudio...OK\n"));
   145 #endif
   145 #endif
   146 
   146 
   147     /* Perform any thread setup */
   147 	/* Perform any thread setup */
   148     if (audio->ThreadInit) {
   148 	if ( audio->ThreadInit ) {
   149         audio->ThreadInit(audio);
   149 		audio->ThreadInit(audio);
   150     }
   150 	}
   151     audio->threadid = SDL_ThreadID();
   151 	audio->threadid = SDL_ThreadID();
   152 
   152 
   153     /* Set up the mixing function */
   153 	/* Set up the mixing function */
   154     fill = audio->spec.callback;
   154 	fill  = audio->spec.callback;
   155     udata = audio->spec.userdata;
   155 	udata = audio->spec.userdata;
       
   156 
   156 
   157 #if SDL_AUDIO_DRIVER_AHI
   157 #if SDL_AUDIO_DRIVER_AHI
   158 	audio_configured = 1;
   158     audio_configured = 1;
   159 
   159 
   160 	D(bug("Audio configured... Checking for conversion\n"));
   160     D(bug("Audio configured... Checking for conversion\n"));
   161 	SDL_mutexP(audio->mixer_lock);
   161     SDL_mutexP(audio->mixer_lock);
   162 	D(bug("Semaphore obtained...\n"));
   162     D(bug("Semaphore obtained...\n"));
   163 #endif
   163 #endif
   164 
   164 
   165 	if ( audio->convert.needed ) {
   165     if (audio->convert.needed) {
   166 		if ( audio->convert.src_format == AUDIO_U8 ) {
   166         if (audio->convert.src_format == AUDIO_U8) {
   167 			silence = 0x80;
   167             silence = 0x80;
   168 		} else {
   168         } else {
   169 			silence = 0;
   169             silence = 0;
   170 		}
   170         }
   171 		stream_len = audio->convert.len;
   171         stream_len = audio->convert.len;
   172 	} else {
   172     } else {
   173 		silence = audio->spec.silence;
   173         silence = audio->spec.silence;
   174 		stream_len = audio->spec.size;
   174         stream_len = audio->spec.size;
   175 	}
   175     }
   176 
   176 
   177 #if SDL_AUDIO_DRIVER_AHI
   177 #if SDL_AUDIO_DRIVER_AHI
   178 	SDL_mutexV(audio->mixer_lock);
   178     SDL_mutexV(audio->mixer_lock);
   179 	D(bug("Entering audio loop...\n"));
   179     D(bug("Entering audio loop...\n"));
   180 #endif
   180 #endif
   181 
   181 
   182 #ifdef __OS2__
   182 #ifdef __OS2__
   183         /* Increase the priority of this thread to make sure that
   183     /* Increase the priority of this thread to make sure that
   184            the audio will be continuous all the time! */
   184        the audio will be continuous all the time! */
   185 #ifdef USE_DOSSETPRIORITY
   185 #ifdef USE_DOSSETPRIORITY
   186         if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO"))
   186     if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
   187         {
       
   188 #ifdef DEBUG_BUILD
   187 #ifdef DEBUG_BUILD
   189           printf("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n", SDL_ThreadID());
   188         printf
   190 #endif
   189             ("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n",
   191           DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
   190              SDL_ThreadID());
   192         }
   191 #endif
   193         else
   192         DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
   194         {
   193     } else {
   195 #ifdef DEBUG_BUILD
   194 #ifdef DEBUG_BUILD
   196           printf("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n", SDL_ThreadID());
   195         printf
   197 #endif
   196             ("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n",
   198           DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
   197              SDL_ThreadID());
   199         }
   198 #endif
   200 #endif
   199         DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
   201 #endif
   200     }
   202 
   201 #endif
   203 	/* Loop, filling the audio buffers */
   202 #endif
   204 	while ( audio->enabled ) {
   203 
   205 
   204     /* Loop, filling the audio buffers */
   206 		/* Fill the current buffer with sound */
   205     while (audio->enabled) {
   207 		if ( audio->convert.needed ) {
   206 
   208 			if ( audio->convert.buf ) {
   207         /* Fill the current buffer with sound */
   209 				stream = audio->convert.buf;
   208         if (audio->convert.needed) {
   210 			} else {
   209             if (audio->convert.buf) {
   211 				continue;
   210                 stream = audio->convert.buf;
   212 			}
   211             } else {
   213 		} else {
   212                 continue;
   214 			stream = audio->GetAudioBuf(audio);
   213             }
   215 			if ( stream == NULL ) {
   214         } else {
   216 				stream = audio->fake_stream;
   215             stream = audio->GetAudioBuf(audio);
   217 			}
   216             if (stream == NULL) {
   218 		}
   217                 stream = audio->fake_stream;
   219 		SDL_memset(stream, silence, stream_len);
   218             }
   220 
   219         }
   221 		if ( ! audio->paused ) {
   220         SDL_memset(stream, silence, stream_len);
   222 			SDL_mutexP(audio->mixer_lock);
   221 
   223 			(*fill)(udata, stream, stream_len);
   222         if (!audio->paused) {
   224 			SDL_mutexV(audio->mixer_lock);
   223             SDL_mutexP(audio->mixer_lock);
   225 		}
   224             (*fill) (udata, stream, stream_len);
   226 
   225             SDL_mutexV(audio->mixer_lock);
   227 		/* Convert the audio if necessary */
   226         }
   228 		if ( audio->convert.needed ) {
   227 
   229 			SDL_ConvertAudio(&audio->convert);
   228         /* Convert the audio if necessary */
   230 			stream = audio->GetAudioBuf(audio);
   229         if (audio->convert.needed) {
   231 			if ( stream == NULL ) {
   230             SDL_ConvertAudio(&audio->convert);
   232 				stream = audio->fake_stream;
   231             stream = audio->GetAudioBuf(audio);
   233 			}
   232             if (stream == NULL) {
   234 			SDL_memcpy(stream, audio->convert.buf,
   233                 stream = audio->fake_stream;
   235 			               audio->convert.len_cvt);
   234             }
   236 		}
   235             SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
   237 
   236         }
   238 		/* Ready current buffer for play and change current buffer */
   237 
   239 		if ( stream != audio->fake_stream ) {
   238         /* Ready current buffer for play and change current buffer */
   240 			audio->PlayAudio(audio);
   239         if (stream != audio->fake_stream) {
   241 		}
   240             audio->PlayAudio(audio);
   242 
   241         }
   243 		/* Wait for an audio buffer to become available */
   242 
   244 		if ( stream == audio->fake_stream ) {
   243         /* Wait for an audio buffer to become available */
   245 			SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
   244         if (stream == audio->fake_stream) {
   246 		} else {
   245             SDL_Delay((audio->spec.samples * 1000) / audio->spec.freq);
   247 			audio->WaitAudio(audio);
   246         } else {
   248 		}
   247             audio->WaitAudio(audio);
   249 	}
   248         }
   250 
   249     }
   251 	/* Wait for the audio to drain.. */
   250 
   252 	if ( audio->WaitDone ) {
   251     /* Wait for the audio to drain.. */
   253 		audio->WaitDone(audio);
   252     if (audio->WaitDone) {
   254 	}
   253         audio->WaitDone(audio);
   255 
   254     }
   256 #if SDL_AUDIO_DRIVER_AHI
   255 #if SDL_AUDIO_DRIVER_AHI
   257 	D(bug("WaitAudio...Done\n"));
   256     D(bug("WaitAudio...Done\n"));
   258 
   257 
   259 	audio->CloseAudio(audio);
   258     audio->CloseAudio(audio);
   260 
   259 
   261 	D(bug("CloseAudio..Done, subtask exiting...\n"));
   260     D(bug("CloseAudio..Done, subtask exiting...\n"));
   262 	audio_configured = 0;
   261     audio_configured = 0;
   263 #endif
   262 #endif
   264 #ifdef __OS2__
   263 #ifdef __OS2__
   265 #ifdef DEBUG_BUILD
   264 #ifdef DEBUG_BUILD
   266         printf("[SDL_RunAudio] : Task exiting. (TID%d)\n", SDL_ThreadID());
   265     printf("[SDL_RunAudio] : Task exiting. (TID%d)\n", SDL_ThreadID());
   267 #endif
   266 #endif
   268 #endif
   267 #endif
   269 	return(0);
   268     return (0);
   270 }
   269 }
   271 
   270 
   272 static void SDL_LockAudio_Default(SDL_AudioDevice *audio)
   271 static void
   273 {
   272 SDL_LockAudio_Default(SDL_AudioDevice * audio)
   274 	if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
   273 {
   275 		return;
   274     if (audio->thread && (SDL_ThreadID() == audio->threadid)) {
   276 	}
   275         return;
   277 	SDL_mutexP(audio->mixer_lock);
   276     }
   278 }
   277     SDL_mutexP(audio->mixer_lock);
   279 
   278 }
   280 static void SDL_UnlockAudio_Default(SDL_AudioDevice *audio)
   279 
   281 {
   280 static void
   282 	if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
   281 SDL_UnlockAudio_Default(SDL_AudioDevice * audio)
   283 		return;
   282 {
   284 	}
   283     if (audio->thread && (SDL_ThreadID() == audio->threadid)) {
   285 	SDL_mutexV(audio->mixer_lock);
   284         return;
   286 }
   285     }
   287 
   286     SDL_mutexV(audio->mixer_lock);
   288 static Uint16 SDL_ParseAudioFormat(const char *string)
   287 }
   289 {
   288 
   290 	Uint16 format = 0;
   289 static Uint16
   291 
   290 SDL_ParseAudioFormat(const char *string)
   292 	switch (*string) {
   291 {
   293 	    case 'U':
   292     Uint16 format = 0;
   294 		++string;
   293 
   295 		format |= 0x0000;
   294     switch (*string) {
   296 		break;
   295     case 'U':
   297 	    case 'S':
   296         ++string;
   298 		++string;
   297         format |= 0x0000;
   299 		format |= 0x8000;
   298         break;
   300 		break;
   299     case 'S':
   301 	    default:
   300         ++string;
   302 		return 0;
   301         format |= 0x8000;
   303 	}
   302         break;
   304 	switch (SDL_atoi(string)) {
   303     default:
   305 	    case 8:
   304         return 0;
   306 		string += 1;
   305     }
   307 		format |= 8;
   306     switch (SDL_atoi(string)) {
   308 		break;
   307     case 8:
   309 	    case 16:
   308         string += 1;
   310 		string += 2;
   309         format |= 8;
   311 		format |= 16;
   310         break;
   312 		if ( SDL_strcmp(string, "LSB") == 0
   311     case 16:
       
   312         string += 2;
       
   313         format |= 16;
       
   314         if (SDL_strcmp(string, "LSB") == 0
   313 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   315 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   314 		     || SDL_strcmp(string, "SYS") == 0
   316             || SDL_strcmp(string, "SYS") == 0
   315 #endif
   317 #endif
   316 		    ) {
   318             ) {
   317 			format |= 0x0000;
   319             format |= 0x0000;
   318 		}
   320         }
   319 		if ( SDL_strcmp(string, "MSB") == 0
   321         if (SDL_strcmp(string, "MSB") == 0
   320 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   322 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   321 		     || SDL_strcmp(string, "SYS") == 0
   323             || SDL_strcmp(string, "SYS") == 0
   322 #endif
   324 #endif
   323 		    ) {
   325             ) {
   324 			format |= 0x1000;
   326             format |= 0x1000;
   325 		}
   327         }
   326 		break;
   328         break;
   327 	    default:
   329     default:
   328 		return 0;
   330         return 0;
   329 	}
   331     }
   330 	return format;
   332     return format;
   331 }
   333 }
   332 
   334 
   333 int SDL_AudioInit(const char *driver_name)
   335 int
   334 {
   336 SDL_GetNumAudioDrivers(void)
   335 	SDL_AudioDevice *audio;
   337 {
   336 	int i = 0, idx;
   338     return (SDL_arraysize(bootstrap) - 1);
   337 
   339 }
   338 	/* Check to make sure we don't overwrite 'current_audio' */
   340 
   339 	if ( current_audio != NULL ) {
   341 const char *
   340 		SDL_AudioQuit();
   342 SDL_GetAudioDriver(int index)
   341 	}
   343 {
   342 
   344     if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
   343 	/* Select the proper audio driver */
   345         return (bootstrap[index]->name);
   344 	audio = NULL;
   346     }
   345 	idx = 0;
   347     return (NULL);
       
   348 }
       
   349 
       
   350 int
       
   351 SDL_AudioInit(const char *driver_name)
       
   352 {
       
   353     SDL_AudioDevice *audio;
       
   354     int i = 0, idx;
       
   355 
       
   356     /* Check to make sure we don't overwrite 'current_audio' */
       
   357     if (current_audio != NULL) {
       
   358         SDL_AudioQuit();
       
   359     }
       
   360 
       
   361     /* Select the proper audio driver */
       
   362     audio = NULL;
       
   363     idx = 0;
   346 #if SDL_AUDIO_DRIVER_ESD
   364 #if SDL_AUDIO_DRIVER_ESD
   347 	if ( (driver_name == NULL) && (SDL_getenv("ESPEAKER") != NULL) ) {
   365     if ((driver_name == NULL) && (SDL_getenv("ESPEAKER") != NULL)) {
   348 		/* Ahem, we know that if ESPEAKER is set, user probably wants
   366         /* Ahem, we know that if ESPEAKER is set, user probably wants
   349 		   to use ESD, but don't start it if it's not already running.
   367            to use ESD, but don't start it if it's not already running.
   350 		   This probably isn't the place to do this, but... Shh! :)
   368            This probably isn't the place to do this, but... Shh! :)
   351 		 */
   369          */
   352 		for ( i=0; bootstrap[i]; ++i ) {
   370         for (i = 0; bootstrap[i]; ++i) {
   353 			if ( SDL_strcmp(bootstrap[i]->name, "esd") == 0 ) {
   371             if (SDL_strcmp(bootstrap[i]->name, "esd") == 0) {
   354 #ifdef HAVE_PUTENV
   372 #ifdef HAVE_PUTENV
   355 				const char *esd_no_spawn;
   373                 const char *esd_no_spawn;
   356 
   374 
   357 				/* Don't start ESD if it's not running */
   375                 /* Don't start ESD if it's not running */
   358 				esd_no_spawn = getenv("ESD_NO_SPAWN");
   376                 esd_no_spawn = getenv("ESD_NO_SPAWN");
   359 				if ( esd_no_spawn == NULL ) {
   377                 if (esd_no_spawn == NULL) {
   360 					putenv("ESD_NO_SPAWN=1");
   378                     putenv("ESD_NO_SPAWN=1");
   361 				}
   379                 }
   362 #endif
   380 #endif
   363 				if ( bootstrap[i]->available() ) {
   381                 if (bootstrap[i]->available()) {
   364 					audio = bootstrap[i]->create(0);
   382                     audio = bootstrap[i]->create(0);
   365 					break;
   383                     break;
   366 				}
   384                 }
   367 #ifdef HAVE_UNSETENV
   385 #ifdef HAVE_UNSETENV
   368 				if ( esd_no_spawn == NULL ) {
   386                 if (esd_no_spawn == NULL) {
   369 					unsetenv("ESD_NO_SPAWN");
   387                     unsetenv("ESD_NO_SPAWN");
   370 				}
   388                 }
   371 #endif
   389 #endif
   372 			}
   390             }
   373 		}
   391         }
   374 	}
   392     }
   375 #endif /* SDL_AUDIO_DRIVER_ESD */
   393 #endif /* SDL_AUDIO_DRIVER_ESD */
   376 	if ( audio == NULL ) {
   394     if (audio == NULL) {
   377 		if ( driver_name != NULL ) {
   395         if (driver_name != NULL) {
   378 #if 0	/* This will be replaced with a better driver selection API */
   396 #if 0                           /* This will be replaced with a better driver selection API */
   379 			if ( SDL_strrchr(driver_name, ':') != NULL ) {
   397             if (SDL_strrchr(driver_name, ':') != NULL) {
   380 				idx = atoi(SDL_strrchr(driver_name, ':')+1);
   398                 idx = atoi(SDL_strrchr(driver_name, ':') + 1);
   381 			}
   399             }
   382 #endif
   400 #endif
   383 			for ( i=0; bootstrap[i]; ++i ) {
   401             for (i = 0; bootstrap[i]; ++i) {
   384 				if (SDL_strncmp(bootstrap[i]->name, driver_name,
   402                 if (SDL_strncmp(bootstrap[i]->name, driver_name,
   385 				            SDL_strlen(bootstrap[i]->name)) == 0) {
   403                                 SDL_strlen(bootstrap[i]->name)) == 0) {
   386 					if ( bootstrap[i]->available() ) {
   404                     if (bootstrap[i]->available()) {
   387 						audio=bootstrap[i]->create(idx);
   405                         audio = bootstrap[i]->create(idx);
   388 						break;
   406                     }
   389 					}
   407                     break;
   390 				}
   408                 }
   391 			}
   409             }
   392 		} else {
   410         } else {
   393 			for ( i=0; bootstrap[i]; ++i ) {
   411             for (i = 0; bootstrap[i]; ++i) {
   394 				if ( bootstrap[i]->available() ) {
   412                 if (bootstrap[i]->available()) {
   395 					audio = bootstrap[i]->create(idx);
   413                     audio = bootstrap[i]->create(idx);
   396 					if ( audio != NULL ) {
   414                     if (audio != NULL) {
   397 						break;
   415                         break;
   398 					}
   416                     }
   399 				}
   417                 }
   400 			}
   418             }
   401 		}
   419         }
   402 		if ( audio == NULL ) {
   420         if (audio == NULL) {
   403 			SDL_SetError("No available audio device");
   421             if (driver_name) {
   404 #if 0 /* Don't fail SDL_Init() if audio isn't available.
   422                 SDL_SetError("%s not available", driver_name);
   405          SDL_OpenAudio() will handle it at that point.  *sigh*
   423             } else {
   406        */
   424                 SDL_SetError("No available audio device");
   407 			return(-1);
   425             }
   408 #endif
   426 #if 0                           /* Don't fail SDL_Init() if audio isn't available.
   409 		}
   427                                    SDL_OpenAudio() will handle it at that point.  *sigh*
   410 	}
   428                                  */
   411 	current_audio = audio;
   429             return (-1);
   412 	if ( current_audio ) {
   430 #endif
   413 		current_audio->name = bootstrap[i]->name;
   431         }
   414 		if ( !current_audio->LockAudio && !current_audio->UnlockAudio ) {
   432     }
   415 			current_audio->LockAudio = SDL_LockAudio_Default;
   433     current_audio = audio;
   416 			current_audio->UnlockAudio = SDL_UnlockAudio_Default;
   434     if (current_audio) {
   417 		}
   435         current_audio->name = bootstrap[i]->name;
   418 	}
   436         if (!current_audio->LockAudio && !current_audio->UnlockAudio) {
   419 	return(0);
   437             current_audio->LockAudio = SDL_LockAudio_Default;
   420 }
   438             current_audio->UnlockAudio = SDL_UnlockAudio_Default;
   421 
   439         }
   422 char *SDL_AudioDriverName(char *namebuf, int maxlen)
   440     }
   423 {
   441     return (0);
   424 	if ( current_audio != NULL ) {
   442 }
   425 		SDL_strlcpy(namebuf, current_audio->name, maxlen);
   443 
   426 		return(namebuf);
   444 /*
   427 	}
   445  * Get the current audio driver name
   428 	return(NULL);
   446  */
   429 }
   447 const char *
   430 
   448 SDL_GetCurrentAudioDriver()
   431 int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
   449 {
   432 {
   450     if (current_audio) {
   433 	SDL_AudioDevice *audio;
   451         return current_audio->name;
   434 	const char *env;
   452     }
   435 
   453     return (NULL);
   436 	/* Start up the audio driver, if necessary */
   454 }
   437 	if ( ! current_audio ) {
   455 
   438 		if ( (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) ||
   456 int
   439 		     (current_audio == NULL) ) {
   457 SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
   440 			return(-1);
   458 {
   441 		}
   459     SDL_AudioDevice *audio;
   442 	}
   460     const char *env;
   443 	audio = current_audio;
   461 
   444 
   462     /* Start up the audio driver, if necessary */
   445 	if (audio->opened) {
   463     if (!current_audio) {
   446 		SDL_SetError("Audio device is already opened");
   464         if ((SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) ||
   447 		return(-1);
   465             (current_audio == NULL)) {
   448 	}
   466             return (-1);
   449 
   467         }
   450 	/* Verify some parameters */
   468     }
   451 	if ( desired->freq == 0 ) {
   469     audio = current_audio;
   452 		env = SDL_getenv("SDL_AUDIO_FREQUENCY");
   470 
   453 		if ( env ) {
   471     if (audio->opened) {
   454 			desired->freq = SDL_atoi(env);
   472         SDL_SetError("Audio device is already opened");
   455 		}
   473         return (-1);
   456 	}
   474     }
   457 	if ( desired->freq == 0 ) {
   475 
   458 		/* Pick some default audio frequency */
   476     /* Verify some parameters */
   459 		desired->freq = 22050;
   477     if (desired->freq == 0) {
   460 	}
   478         env = SDL_getenv("SDL_AUDIO_FREQUENCY");
   461 	if ( desired->format == 0 ) {
   479         if (env) {
   462 		env = SDL_getenv("SDL_AUDIO_FORMAT");
   480             desired->freq = SDL_atoi(env);
   463 		if ( env ) {
   481         }
   464 			desired->format = SDL_ParseAudioFormat(env);
   482     }
   465 		}
   483     if (desired->freq == 0) {
   466 	}
   484         /* Pick some default audio frequency */
   467 	if ( desired->format == 0 ) {
   485         desired->freq = 22050;
   468 		/* Pick some default audio format */
   486     }
   469 		desired->format = AUDIO_S16;
   487     if (desired->format == 0) {
   470 	}
   488         env = SDL_getenv("SDL_AUDIO_FORMAT");
   471 	if ( desired->channels == 0 ) {
   489         if (env) {
   472 		env = SDL_getenv("SDL_AUDIO_CHANNELS");
   490             desired->format = SDL_ParseAudioFormat(env);
   473 		if ( env ) {
   491         }
   474 			desired->channels = SDL_atoi(env);
   492     }
   475 		}
   493     if (desired->format == 0) {
   476 	}
   494         /* Pick some default audio format */
   477 	if ( desired->channels == 0 ) {
   495         desired->format = AUDIO_S16;
   478 		/* Pick a default number of channels */
   496     }
   479 		desired->channels = 2;
   497     if (desired->channels == 0) {
   480 	}
   498         env = SDL_getenv("SDL_AUDIO_CHANNELS");
   481 	switch ( desired->channels ) {
   499         if (env) {
   482 	    case 1:	/* Mono */
   500             desired->channels = SDL_atoi(env);
   483 	    case 2:	/* Stereo */
   501         }
   484 	    case 4:	/* surround */
   502     }
   485 	    case 6:	/* surround with center and lfe */
   503     if (desired->channels == 0) {
   486 		break;
   504         /* Pick a default number of channels */
   487 	    default:
   505         desired->channels = 2;
   488 		SDL_SetError("1 (mono) and 2 (stereo) channels supported");
   506     }
   489 		return(-1);
   507     switch (desired->channels) {
   490 	}
   508     case 1:                    /* Mono */
   491 	if ( desired->samples == 0 ) {
   509     case 2:                    /* Stereo */
   492 		env = SDL_getenv("SDL_AUDIO_SAMPLES");
   510     case 4:                    /* surround */
   493 		if ( env ) {
   511     case 6:                    /* surround with center and lfe */
   494 			desired->samples = SDL_atoi(env);
   512         break;
   495 		}
   513     default:
   496 	}
   514         SDL_SetError("1 (mono) and 2 (stereo) channels supported");
   497 	if ( desired->samples == 0 ) {
   515         return (-1);
   498 		/* Pick a default of ~46 ms at desired frequency */
   516     }
   499 		int samples = (desired->freq / 1000) * 46;
   517     if (desired->samples == 0) {
   500 		int power2 = 1;
   518         env = SDL_getenv("SDL_AUDIO_SAMPLES");
   501 		while ( power2 < samples ) {
   519         if (env) {
   502 			power2 *= 2;
   520             desired->samples = SDL_atoi(env);
   503 		}
   521         }
   504 		desired->samples = power2;
   522     }
   505 	}
   523     if (desired->samples == 0) {
   506 	if ( desired->callback == NULL ) {
   524         /* Pick a default of ~46 ms at desired frequency */
   507 		SDL_SetError("SDL_OpenAudio() passed a NULL callback");
   525         int samples = (desired->freq / 1000) * 46;
   508 		return(-1);
   526         int power2 = 1;
   509 	}
   527         while (power2 < samples) {
   510 
   528             power2 *= 2;
       
   529         }
       
   530         desired->samples = power2;
       
   531     }
       
   532     if (desired->callback == NULL) {
       
   533         SDL_SetError("SDL_OpenAudio() passed a NULL callback");
       
   534         return (-1);
       
   535     }
   511 #if defined(__MACOS__) || (defined(__RISCOS__) && SDL_THREADS_DISABLED)
   536 #if defined(__MACOS__) || (defined(__RISCOS__) && SDL_THREADS_DISABLED)
   512 	/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
   537     /* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
   513 #else
   538 #else
   514 #if defined(__MINT__) && SDL_THREADS_DISABLED
   539 #if defined(__MINT__) && SDL_THREADS_DISABLED
   515 	/* Uses interrupt driven audio, without thread */
   540     /* Uses interrupt driven audio, without thread */
   516 #else
   541 #else
   517 	/* Create a semaphore for locking the sound buffers */
   542     /* Create a semaphore for locking the sound buffers */
   518 	audio->mixer_lock = SDL_CreateMutex();
   543     audio->mixer_lock = SDL_CreateMutex();
   519 	if ( audio->mixer_lock == NULL ) {
   544     if (audio->mixer_lock == NULL) {
   520 		SDL_SetError("Couldn't create mixer lock");
   545         SDL_SetError("Couldn't create mixer lock");
   521 		SDL_CloseAudio();
   546         SDL_CloseAudio();
   522 		return(-1);
   547         return (-1);
   523 	}
   548     }
   524 #endif /* __MINT__ */
   549 #endif /* __MINT__ */
   525 #endif /* __MACOS__ */
   550 #endif /* __MACOS__ */
   526 
   551 
   527 	/* Calculate the silence and size of the audio specification */
   552     /* Calculate the silence and size of the audio specification */
   528 	SDL_CalculateAudioSpec(desired);
   553     SDL_CalculateAudioSpec(desired);
   529 
   554 
   530 	/* Open the audio subsystem */
   555     /* Open the audio subsystem */
   531 	SDL_memcpy(&audio->spec, desired, sizeof(audio->spec));
   556     SDL_memcpy(&audio->spec, desired, sizeof(audio->spec));
   532 	audio->convert.needed = 0;
   557     audio->convert.needed = 0;
   533 	audio->enabled = 1;
   558     audio->enabled = 1;
   534 	audio->paused  = 1;
   559     audio->paused = 1;
   535 
   560 
   536 #if !SDL_AUDIO_DRIVER_AHI
   561 #if !SDL_AUDIO_DRIVER_AHI
   537 
   562 
   538 /* AmigaOS opens audio inside the main loop */
   563 /* AmigaOS opens audio inside the main loop */
   539 	audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
   564     audio->opened = audio->OpenAudio(audio, &audio->spec) + 1;
   540 
   565 
   541 	if ( ! audio->opened ) {
   566     if (!audio->opened) {
   542 		SDL_CloseAudio();
   567         SDL_CloseAudio();
   543 		return(-1);
   568         return (-1);
   544 	}
   569     }
   545 #else
   570 #else
   546 	D(bug("Locking semaphore..."));
   571     D(bug("Locking semaphore..."));
   547 	SDL_mutexP(audio->mixer_lock);
   572     SDL_mutexP(audio->mixer_lock);
   548 
   573 
   549 
   574 
   550 	audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   575     audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   551 	D(bug("Created thread...\n"));
   576     D(bug("Created thread...\n"));
   552 
   577 
   553 	if ( audio->thread == NULL ) {
   578     if (audio->thread == NULL) {
   554 		SDL_mutexV(audio->mixer_lock);
   579         SDL_mutexV(audio->mixer_lock);
   555 		SDL_CloseAudio();
   580         SDL_CloseAudio();
   556 		SDL_SetError("Couldn't create audio thread");
   581         SDL_SetError("Couldn't create audio thread");
   557 		return(-1);
   582         return (-1);
   558 	}
   583     }
   559 
   584 
   560 	while(!audio_configured)
   585     while (!audio_configured)
   561 		SDL_Delay(100);
   586         SDL_Delay(100);
   562 #endif
   587 #endif
   563 
   588 
   564 	/* If the audio driver changes the buffer size, accept it */
   589     /* If the audio driver changes the buffer size, accept it */
   565 	if ( audio->spec.samples != desired->samples ) {
   590     if (audio->spec.samples != desired->samples) {
   566 		desired->samples = audio->spec.samples;
   591         desired->samples = audio->spec.samples;
   567 		SDL_CalculateAudioSpec(desired);
   592         SDL_CalculateAudioSpec(desired);
   568 	}
   593     }
   569 
   594 
   570 	/* Allocate a fake audio memory buffer */
   595     /* Allocate a fake audio memory buffer */
   571 	audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
   596     audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
   572 	if ( audio->fake_stream == NULL ) {
   597     if (audio->fake_stream == NULL) {
   573 		SDL_CloseAudio();
   598         SDL_CloseAudio();
   574 		SDL_OutOfMemory();
   599         SDL_OutOfMemory();
   575 		return(-1);
   600         return (-1);
   576 	}
   601     }
   577 
   602 
   578 	/* See if we need to do any conversion */
   603     /* See if we need to do any conversion */
   579 	if ( obtained != NULL ) {
   604     if (obtained != NULL) {
   580 		SDL_memcpy(obtained, &audio->spec, sizeof(audio->spec));
   605         SDL_memcpy(obtained, &audio->spec, sizeof(audio->spec));
   581 	} else if ( desired->freq != audio->spec.freq ||
   606     } else if (desired->freq != audio->spec.freq ||
   582                     desired->format != audio->spec.format ||
   607                desired->format != audio->spec.format ||
   583 	            desired->channels != audio->spec.channels ) {
   608                desired->channels != audio->spec.channels) {
   584 		/* Build an audio conversion block */
   609         /* Build an audio conversion block */
   585 		if ( SDL_BuildAudioCVT(&audio->convert,
   610         if (SDL_BuildAudioCVT(&audio->convert,
   586 			desired->format, desired->channels,
   611                               desired->format, desired->channels,
   587 					desired->freq,
   612                               desired->freq,
   588 			audio->spec.format, audio->spec.channels,
   613                               audio->spec.format, audio->spec.channels,
   589 					audio->spec.freq) < 0 ) {
   614                               audio->spec.freq) < 0) {
   590 			SDL_CloseAudio();
   615             SDL_CloseAudio();
   591 			return(-1);
   616             return (-1);
   592 		}
   617         }
   593 		if ( audio->convert.needed ) {
   618         if (audio->convert.needed) {
   594 			audio->convert.len = desired->size;
   619             audio->convert.len = desired->size;
   595 			audio->convert.buf =(Uint8 *)SDL_AllocAudioMem(
   620             audio->convert.buf =
   596 			   audio->convert.len*audio->convert.len_mult);
   621                 (Uint8 *) SDL_AllocAudioMem(audio->convert.len *
   597 			if ( audio->convert.buf == NULL ) {
   622                                             audio->convert.len_mult);
   598 				SDL_CloseAudio();
   623             if (audio->convert.buf == NULL) {
   599 				SDL_OutOfMemory();
   624                 SDL_CloseAudio();
   600 				return(-1);
   625                 SDL_OutOfMemory();
   601 			}
   626                 return (-1);
   602 		}
   627             }
   603 	}
   628         }
   604 
   629     }
   605 #if !SDL_AUDIO_DRIVER_AHI
   630 #if !SDL_AUDIO_DRIVER_AHI
   606 	/* Start the audio thread if necessary */
   631     /* Start the audio thread if necessary */
   607 	switch (audio->opened) {
   632     switch (audio->opened) {
   608 		case  1:
   633     case 1:
   609 			/* Start the audio thread */
   634         /* Start the audio thread */
   610 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   635 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   611 #undef SDL_CreateThread
   636 #undef SDL_CreateThread
   612 			audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
   637         audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
   613 #else
   638 #else
   614 			audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   639         audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   615 #endif
   640 #endif
   616 			if ( audio->thread == NULL ) {
   641         if (audio->thread == NULL) {
   617 				SDL_CloseAudio();
   642             SDL_CloseAudio();
   618 				SDL_SetError("Couldn't create audio thread");
   643             SDL_SetError("Couldn't create audio thread");
   619 				return(-1);
   644             return (-1);
   620 			}
   645         }
   621 			break;
   646         break;
   622 
   647 
   623 		default:
   648     default:
   624 			/* The audio is now playing */
   649         /* The audio is now playing */
   625 			break;
   650         break;
   626 	}
   651     }
   627 #else
   652 #else
   628 	SDL_mutexV(audio->mixer_lock);
   653     SDL_mutexV(audio->mixer_lock);
   629 	D(bug("SDL_OpenAudio USCITA...\n"));
   654     D(bug("SDL_OpenAudio USCITA...\n"));
   630 
   655 
   631 #endif
   656 #endif
   632 
   657 
   633 	return(0);
   658     return (0);
   634 }
   659 }
   635 
   660 
   636 SDL_audiostatus SDL_GetAudioStatus(void)
   661 SDL_audiostatus
   637 {
   662 SDL_GetAudioStatus(void)
   638 	SDL_AudioDevice *audio = current_audio;
   663 {
   639 	SDL_audiostatus status;
   664     SDL_AudioDevice *audio = current_audio;
   640 
   665     SDL_audiostatus status;
   641 	status = SDL_AUDIO_STOPPED;
   666 
   642 	if ( audio && audio->enabled ) {
   667     status = SDL_AUDIO_STOPPED;
   643 		if ( audio->paused ) {
   668     if (audio && audio->enabled) {
   644 			status = SDL_AUDIO_PAUSED;
   669         if (audio->paused) {
   645 		} else {
   670             status = SDL_AUDIO_PAUSED;
   646 			status = SDL_AUDIO_PLAYING;
   671         } else {
   647 		}
   672             status = SDL_AUDIO_PLAYING;
   648 	}
   673         }
   649 	return(status);
   674     }
   650 }
   675     return (status);
   651 
   676 }
   652 void SDL_PauseAudio (int pause_on)
   677 
   653 {
   678 void
   654 	SDL_AudioDevice *audio = current_audio;
   679 SDL_PauseAudio(int pause_on)
   655 
   680 {
   656 	if ( audio ) {
   681     SDL_AudioDevice *audio = current_audio;
   657 		audio->paused = pause_on;
   682 
   658 	}
   683     if (audio) {
   659 }
   684         audio->paused = pause_on;
   660 
   685     }
   661 void SDL_LockAudio (void)
   686 }
   662 {
   687 
   663 	SDL_AudioDevice *audio = current_audio;
   688 void
   664 
   689 SDL_LockAudio(void)
   665 	/* Obtain a lock on the mixing buffers */
   690 {
   666 	if ( audio && audio->LockAudio ) {
   691     SDL_AudioDevice *audio = current_audio;
   667 		audio->LockAudio(audio);
   692 
   668 	}
   693     /* Obtain a lock on the mixing buffers */
   669 }
   694     if (audio && audio->LockAudio) {
   670 
   695         audio->LockAudio(audio);
   671 void SDL_UnlockAudio (void)
   696     }
   672 {
   697 }
   673 	SDL_AudioDevice *audio = current_audio;
   698 
   674 
   699 void
   675 	/* Release lock on the mixing buffers */
   700 SDL_UnlockAudio(void)
   676 	if ( audio && audio->UnlockAudio ) {
   701 {
   677 		audio->UnlockAudio(audio);
   702     SDL_AudioDevice *audio = current_audio;
   678 	}
   703 
   679 }
   704     /* Release lock on the mixing buffers */
   680 
   705     if (audio && audio->UnlockAudio) {
   681 void SDL_CloseAudio (void)
   706         audio->UnlockAudio(audio);
   682 {
   707     }
   683 	SDL_QuitSubSystem(SDL_INIT_AUDIO);
   708 }
   684 }
   709 
   685 
   710 void
   686 void SDL_AudioQuit(void)
   711 SDL_CloseAudio(void)
   687 {
   712 {
   688 	SDL_AudioDevice *audio = current_audio;
   713     SDL_QuitSubSystem(SDL_INIT_AUDIO);
   689 
   714 }
   690 	if ( audio ) {
   715 
   691 		audio->enabled = 0;
   716 void
   692 		if ( audio->thread != NULL ) {
   717 SDL_AudioQuit(void)
   693 			SDL_WaitThread(audio->thread, NULL);
   718 {
   694 		}
   719     SDL_AudioDevice *audio = current_audio;
   695 		if ( audio->mixer_lock != NULL ) {
   720 
   696 			SDL_DestroyMutex(audio->mixer_lock);
   721     if (audio) {
   697 		}
   722         audio->enabled = 0;
   698 		if ( audio->fake_stream != NULL ) {
   723         if (audio->thread != NULL) {
   699 			SDL_FreeAudioMem(audio->fake_stream);
   724             SDL_WaitThread(audio->thread, NULL);
   700 		}
   725         }
   701 		if ( audio->convert.needed ) {
   726         if (audio->mixer_lock != NULL) {
   702 			SDL_FreeAudioMem(audio->convert.buf);
   727             SDL_DestroyMutex(audio->mixer_lock);
   703 
   728         }
   704 		}
   729         if (audio->fake_stream != NULL) {
       
   730             SDL_FreeAudioMem(audio->fake_stream);
       
   731         }
       
   732         if (audio->convert.needed) {
       
   733             SDL_FreeAudioMem(audio->convert.buf);
       
   734 
       
   735         }
   705 #if !SDL_AUDIO_DRIVER_AHI
   736 #if !SDL_AUDIO_DRIVER_AHI
   706 		if ( audio->opened ) {
   737         if (audio->opened) {
   707 			audio->CloseAudio(audio);
   738             audio->CloseAudio(audio);
   708 			audio->opened = 0;
   739             audio->opened = 0;
   709 		}
   740         }
   710 #endif
   741 #endif
   711 		/* Free the driver data */
   742         /* Free the driver data */
   712 		audio->free(audio);
   743         audio->free(audio);
   713 		current_audio = NULL;
   744         current_audio = NULL;
   714 	}
   745     }
   715 }
   746 }
   716 
   747 
   717 #define NUM_FORMATS	6
   748 #define NUM_FORMATS	6
   718 static int format_idx;
   749 static int format_idx;
   719 static int format_idx_sub;
   750 static int format_idx_sub;
   720 static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = {
   751 static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = {
   721  { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
   752     {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
   722  { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
   753      AUDIO_U16MSB},
   723  { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 },
   754     {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB,
   724  { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 },
   755      AUDIO_U16MSB},
   725  { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 },
   756     {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8,
   726  { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 },
   757      AUDIO_S8},
       
   758     {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8,
       
   759      AUDIO_S8},
       
   760     {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8,
       
   761      AUDIO_S8},
       
   762     {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8,
       
   763      AUDIO_S8},
   727 };
   764 };
   728 
   765 
   729 Uint16 SDL_FirstAudioFormat(Uint16 format)
   766 Uint16
   730 {
   767 SDL_FirstAudioFormat(Uint16 format)
   731 	for ( format_idx=0; format_idx < NUM_FORMATS; ++format_idx ) {
   768 {
   732 		if ( format_list[format_idx][0] == format ) {
   769     for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) {
   733 			break;
   770         if (format_list[format_idx][0] == format) {
   734 		}
   771             break;
   735 	}
   772         }
   736 	format_idx_sub = 0;
   773     }
   737 	return(SDL_NextAudioFormat());
   774     format_idx_sub = 0;
   738 }
   775     return (SDL_NextAudioFormat());
   739 
   776 }
   740 Uint16 SDL_NextAudioFormat(void)
   777 
   741 {
   778 Uint16
   742 	if ( (format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS) ) {
   779 SDL_NextAudioFormat(void)
   743 		return(0);
   780 {
   744 	}
   781     if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
   745 	return(format_list[format_idx][format_idx_sub++]);
   782         return (0);
   746 }
   783     }
   747 
   784     return (format_list[format_idx][format_idx_sub++]);
   748 void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
   785 }
   749 {
   786 
   750 	switch (spec->format) {
   787 void
   751 		case AUDIO_U8:
   788 SDL_CalculateAudioSpec(SDL_AudioSpec * spec)
   752 			spec->silence = 0x80;
   789 {
   753 			break;
   790     switch (spec->format) {
   754 		default:
   791     case AUDIO_U8:
   755 			spec->silence = 0x00;
   792         spec->silence = 0x80;
   756 			break;
   793         break;
   757 	}
   794     default:
   758 	spec->size = (spec->format&0xFF)/8;
   795         spec->silence = 0x00;
   759 	spec->size *= spec->channels;
   796         break;
   760 	spec->size *= spec->samples;
   797     }
   761 }
   798     spec->size = (spec->format & 0xFF) / 8;
       
   799     spec->size *= spec->channels;
       
   800     spec->size *= spec->samples;
       
   801 }
       
   802 
       
   803 /* vi: set ts=4 sw=4 expandtab: */