Added support to loopwave for hotplugging audio devices

This commit is contained in:
Sam Lantinga 2017-03-09 14:50:23 -08:00
parent c1802ef646
commit aae481294d
1 changed files with 53 additions and 26 deletions

View File

@ -38,6 +38,7 @@ static struct
int soundpos; /* Current play position */ int soundpos; /* Current play position */
} wave; } wave;
static SDL_AudioDeviceID device;
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void static void
@ -47,6 +48,37 @@ quit(int rc)
exit(rc); exit(rc);
} }
static void
close_audio()
{
if (device != 0) {
SDL_CloseAudioDevice(device);
device = 0;
}
}
static void
open_audio()
{
/* Initialize fillerup() variables */
device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0);
if (!device) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
SDL_FreeWAV(wave.sound);
quit(2);
}
/* Let the audio run */
SDL_PauseAudioDevice(device, SDL_FALSE);
}
static void reopen_audio()
{
close_audio();
open_audio();
}
void SDLCALL void SDLCALL
fillerup(void *unused, Uint8 * stream, int len) fillerup(void *unused, Uint8 * stream, int len)
@ -82,7 +114,7 @@ poked(int sig)
void void
loop() loop()
{ {
if(done || (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING)) if(done || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING))
emscripten_cancel_main_loop(); emscripten_cancel_main_loop();
} }
#endif #endif
@ -97,7 +129,7 @@ main(int argc, char *argv[])
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* Load the SDL library */ /* Load the SDL library */
if (SDL_Init(SDL_INIT_AUDIO) < 0) { if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_EVENTS) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
return (1); return (1);
} }
@ -114,17 +146,6 @@ main(int argc, char *argv[])
} }
wave.spec.callback = fillerup; wave.spec.callback = fillerup;
#if HAVE_SIGNAL_H
/* Set the signals */
#ifdef SIGHUP
signal(SIGHUP, poked);
#endif
signal(SIGINT, poked);
#ifdef SIGQUIT
signal(SIGQUIT, poked);
#endif
signal(SIGTERM, poked);
#endif /* HAVE_SIGNAL_H */
/* Show the list of available drivers */ /* Show the list of available drivers */
SDL_Log("Available audio drivers:"); SDL_Log("Available audio drivers:");
@ -132,27 +153,33 @@ main(int argc, char *argv[])
SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
} }
/* Initialize fillerup() variables */
if (SDL_OpenAudio(&wave.spec, NULL) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError());
SDL_FreeWAV(wave.sound);
quit(2);
}
SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
/* Let the audio run */ open_audio();
SDL_PauseAudio(0);
SDL_FlushEvents(SDL_AUDIODEVICEADDED, SDL_AUDIODEVICEREMOVED);
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
emscripten_set_main_loop(loop, 0, 1); emscripten_set_main_loop(loop, 0, 1);
#else #else
while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING)) while (!done) {
SDL_Delay(1000); SDL_Event event;
while (SDL_PollEvent(&event) > 0) {
if (event.type == SDL_QUIT) {
done = 1;
}
if ((event.type == SDL_AUDIODEVICEADDED && !event.adevice.iscapture) ||
(event.type == SDL_AUDIODEVICEREMOVED && !event.adevice.iscapture && event.adevice.which == device)) {
reopen_audio();
}
}
SDL_Delay(100);
}
#endif #endif
/* Clean up on signal */ /* Clean up on signal */
SDL_CloseAudio(); close_audio();
SDL_FreeWAV(wave.sound); SDL_FreeWAV(wave.sound);
SDL_Quit(); SDL_Quit();
return (0); return (0);