src/audio/SDL_audio.c
changeset 1402 d910939febfa
parent 1379 c0a74f199ecf
child 1406 39ca9a4b22f3
equal deleted inserted replaced
1401:1819fd069e89 1402:d910939febfa
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    18 
    19     Sam Lantinga
    19     Sam Lantinga
    20     slouken@libsdl.org
    20     slouken@libsdl.org
    21 */
    21 */
       
    22 #include "SDL_config.h"
    22 
    23 
    23 /* Allow access to a raw mixing buffer */
    24 /* Allow access to a raw mixing buffer */
    24 
    25 
    25 #include "SDL.h"
    26 #include "SDL.h"
    26 #include "SDL_audio_c.h"
    27 #include "SDL_audio_c.h"
    95 	&DISKAUD_bootstrap,
    96 	&DISKAUD_bootstrap,
    96 #endif
    97 #endif
    97 #if SDL_AUDIO_DRIVER_DC
    98 #if SDL_AUDIO_DRIVER_DC
    98 	&DCAUD_bootstrap,
    99 	&DCAUD_bootstrap,
    99 #endif
   100 #endif
   100 #if SDL_AUDIO_DRIVER_DRENDERER
       
   101 	&DRENDERER_bootstrap,
       
   102 #endif
       
   103 #if SDL_AUDIO_DRIVER_MMEAUDIO
   101 #if SDL_AUDIO_DRIVER_MMEAUDIO
   104 	&MMEAUDIO_bootstrap,
   102 	&MMEAUDIO_bootstrap,
   105 #endif
   103 #endif
   106 #if SDL_AUDIO_DRIVER_DART
   104 #if SDL_AUDIO_DRIVER_DART
   107 	&DART_bootstrap,
   105 	&DART_bootstrap,
   112 
   110 
   113 /* Various local functions */
   111 /* Various local functions */
   114 int SDL_AudioInit(const char *driver_name);
   112 int SDL_AudioInit(const char *driver_name);
   115 void SDL_AudioQuit(void);
   113 void SDL_AudioQuit(void);
   116 
   114 
   117 #ifdef ENABLE_AHI
   115 #if SDL_AUDIO_DRIVER_AHI
   118 static int audio_configured = 0;
   116 static int audio_configured = 0;
   119 #endif
   117 #endif
   120 
   118 
   121 /* The general mixing thread function */
   119 /* The general mixing thread function */
   122 int SDL_RunAudio(void *audiop)
   120 int SDL_RunAudio(void *audiop)
   125 	Uint8 *stream;
   123 	Uint8 *stream;
   126 	int    stream_len;
   124 	int    stream_len;
   127 	void  *udata;
   125 	void  *udata;
   128 	void (*fill)(void *userdata,Uint8 *stream, int len);
   126 	void (*fill)(void *userdata,Uint8 *stream, int len);
   129 	int    silence;
   127 	int    silence;
   130 #ifdef ENABLE_AHI
   128 #if SDL_AUDIO_DRIVER_AHI
   131 	int started = 0;
   129 	int started = 0;
   132 
   130 
   133 /* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
   131 /* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
   134 
   132 
   135 	D(bug("Task audio started audio struct:<%lx>...\n",audiop));
   133 	D(bug("Task audio started audio struct:<%lx>...\n",audiop));
   151 
   149 
   152 	/* Set up the mixing function */
   150 	/* Set up the mixing function */
   153 	fill  = audio->spec.callback;
   151 	fill  = audio->spec.callback;
   154 	udata = audio->spec.userdata;
   152 	udata = audio->spec.userdata;
   155 
   153 
   156 #ifdef ENABLE_AHI
   154 #if SDL_AUDIO_DRIVER_AHI
   157 	audio_configured = 1;
   155 	audio_configured = 1;
   158 
   156 
   159 	D(bug("Audio configured... Checking for conversion\n"));
   157 	D(bug("Audio configured... Checking for conversion\n"));
   160 	SDL_mutexP(audio->mixer_lock);
   158 	SDL_mutexP(audio->mixer_lock);
   161 	D(bug("Semaphore obtained...\n"));
   159 	D(bug("Semaphore obtained...\n"));
   172 		silence = audio->spec.silence;
   170 		silence = audio->spec.silence;
   173 		stream_len = audio->spec.size;
   171 		stream_len = audio->spec.size;
   174 	}
   172 	}
   175 	stream = audio->fake_stream;
   173 	stream = audio->fake_stream;
   176 
   174 
   177 #ifdef ENABLE_AHI
   175 #if SDL_AUDIO_DRIVER_AHI
   178 	SDL_mutexV(audio->mixer_lock);
   176 	SDL_mutexV(audio->mixer_lock);
   179 	D(bug("Entering audio loop...\n"));
   177 	D(bug("Entering audio loop...\n"));
   180 #endif
   178 #endif
   181 
   179 
   182 #ifdef __OS2__
   180 #ifdef __OS2__
   195 
   193 
   196 		/* Wait for new current buffer to finish playing */
   194 		/* Wait for new current buffer to finish playing */
   197 		if ( stream == audio->fake_stream ) {
   195 		if ( stream == audio->fake_stream ) {
   198 			SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
   196 			SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
   199 		} else {
   197 		} else {
   200 #ifdef ENABLE_AHI
   198 #if SDL_AUDIO_DRIVER_AHI
   201 			if ( started > 1 )
   199 			if ( started > 1 )
   202 #endif
   200 #endif
   203 			audio->WaitAudio(audio);
   201 			audio->WaitAudio(audio);
   204 		}
   202 		}
   205 
   203 
   236 		}
   234 		}
   237 
   235 
   238 		/* Ready current buffer for play and change current buffer */
   236 		/* Ready current buffer for play and change current buffer */
   239 		if ( stream != audio->fake_stream ) {
   237 		if ( stream != audio->fake_stream ) {
   240 			audio->PlayAudio(audio);
   238 			audio->PlayAudio(audio);
   241 #ifdef ENABLE_AHI
   239 #if SDL_AUDIO_DRIVER_AHI
   242 /* AmigaOS don't have to wait the first time audio is played! */
   240 /* AmigaOS don't have to wait the first time audio is played! */
   243 			started++;
   241 			started++;
   244 #endif
   242 #endif
   245 		}
   243 		}
   246 	}
   244 	}
   247 	/* Wait for the audio to drain.. */
   245 	/* Wait for the audio to drain.. */
   248 	if ( audio->WaitDone ) {
   246 	if ( audio->WaitDone ) {
   249 		audio->WaitDone(audio);
   247 		audio->WaitDone(audio);
   250 	}
   248 	}
   251 
   249 
   252 #ifdef ENABLE_AHI
   250 #if SDL_AUDIO_DRIVER_AHI
   253 	D(bug("WaitAudio...Done\n"));
   251 	D(bug("WaitAudio...Done\n"));
   254 
   252 
   255 	audio->CloseAudio(audio);
   253 	audio->CloseAudio(audio);
   256 
   254 
   257 	D(bug("CloseAudio..Done, subtask exiting...\n"));
   255 	D(bug("CloseAudio..Done, subtask exiting...\n"));
   411 	    default:
   409 	    default:
   412 		SDL_SetError("1 (mono) and 2 (stereo) channels supported");
   410 		SDL_SetError("1 (mono) and 2 (stereo) channels supported");
   413 		return(-1);
   411 		return(-1);
   414 	}
   412 	}
   415 
   413 
   416 #if defined(macintosh) || (defined(__riscos__) && SDL_THREADS_DISABLED)
   414 #if defined(__MACOS__) || (defined(__RISCOS__) && SDL_THREADS_DISABLED)
   417 	/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
   415 	/* FIXME: Need to implement PPC interrupt asm for SDL_LockAudio() */
   418 #else
   416 #else
   419 #if defined(__MINT__) && SDL_THREADS_DISABLED
   417 #if defined(__MINT__) && SDL_THREADS_DISABLED
   420 	/* Uses interrupt driven audio, without thread */
   418 	/* Uses interrupt driven audio, without thread */
   421 #else
   419 #else
   425 		SDL_SetError("Couldn't create mixer lock");
   423 		SDL_SetError("Couldn't create mixer lock");
   426 		SDL_CloseAudio();
   424 		SDL_CloseAudio();
   427 		return(-1);
   425 		return(-1);
   428 	}
   426 	}
   429 #endif /* __MINT__ */
   427 #endif /* __MINT__ */
   430 #endif /* macintosh */
   428 #endif /* __MACOS__ */
   431 
   429 
   432 	/* Calculate the silence and size of the audio specification */
   430 	/* Calculate the silence and size of the audio specification */
   433 	SDL_CalculateAudioSpec(desired);
   431 	SDL_CalculateAudioSpec(desired);
   434 
   432 
   435 	/* Open the audio subsystem */
   433 	/* Open the audio subsystem */
   436 	SDL_memcpy(&audio->spec, desired, sizeof(audio->spec));
   434 	SDL_memcpy(&audio->spec, desired, sizeof(audio->spec));
   437 	audio->convert.needed = 0;
   435 	audio->convert.needed = 0;
   438 	audio->enabled = 1;
   436 	audio->enabled = 1;
   439 	audio->paused  = 1;
   437 	audio->paused  = 1;
   440 
   438 
   441 #ifndef ENABLE_AHI
   439 #if SDL_AUDIO_DRIVER_AHI
   442 
   440 
   443 /* AmigaOS opens audio inside the main loop */
   441 /* AmigaOS opens audio inside the main loop */
   444 	audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
   442 	audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
   445 
   443 
   446 	if ( ! audio->opened ) {
   444 	if ( ! audio->opened ) {
   448 		return(-1);
   446 		return(-1);
   449 	}
   447 	}
   450 #else
   448 #else
   451 	D(bug("Locking semaphore..."));
   449 	D(bug("Locking semaphore..."));
   452 	SDL_mutexP(audio->mixer_lock);
   450 	SDL_mutexP(audio->mixer_lock);
   453 
   451 #endif
   454 #if (defined(_WIN32) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   452 
       
   453 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   455 #undef SDL_CreateThread
   454 #undef SDL_CreateThread
   456 	audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
   455 	audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
   457 #else
   456 #else
   458 	audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   457 	audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   459 #endif
   458 #endif
   464 		SDL_CloseAudio();
   463 		SDL_CloseAudio();
   465 		SDL_SetError("Couldn't create audio thread");
   464 		SDL_SetError("Couldn't create audio thread");
   466 		return(-1);
   465 		return(-1);
   467 	}
   466 	}
   468 
   467 
       
   468 #if SDL_AUDIO_DRIVER_AHI
   469 	while(!audio_configured)
   469 	while(!audio_configured)
   470 		SDL_Delay(100);
   470 		SDL_Delay(100);
   471 #endif
   471 #endif
   472 
   472 
   473 	/* If the audio driver changes the buffer size, accept it */
   473 	/* If the audio driver changes the buffer size, accept it */
   509 				return(-1);
   509 				return(-1);
   510 			}
   510 			}
   511 		}
   511 		}
   512 	}
   512 	}
   513 
   513 
   514 #ifndef ENABLE_AHI
   514 #if SDL_AUDIO_DRIVER_AHI
   515 	/* Start the audio thread if necessary */
   515 	/* Start the audio thread if necessary */
   516 	switch (audio->opened) {
   516 	switch (audio->opened) {
   517 		case  1:
   517 		case  1:
   518 			/* Start the audio thread */
   518 			/* Start the audio thread */
   519 #if (defined(_WIN32) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   519 #if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
   520 #undef SDL_CreateThread
   520 #undef SDL_CreateThread
   521 			audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
   521 			audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
   522 #else
   522 #else
   523 			audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   523 			audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
   524 #endif
   524 #endif
   609 		}
   609 		}
   610 		if ( audio->convert.needed ) {
   610 		if ( audio->convert.needed ) {
   611 			SDL_FreeAudioMem(audio->convert.buf);
   611 			SDL_FreeAudioMem(audio->convert.buf);
   612 
   612 
   613 		}
   613 		}
   614 #ifndef ENABLE_AHI
   614 #if SDL_AUDIO_DRIVER_AHI
   615 		if ( audio->opened ) {
   615 		if ( audio->opened ) {
   616 			audio->CloseAudio(audio);
   616 			audio->CloseAudio(audio);
   617 			audio->opened = 0;
   617 			audio->opened = 0;
   618 		}
   618 		}
   619 #endif
   619 #endif