From d8e5475fe58d6e055df2ef3b6b41b5a62c3b3c22 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Mon, 19 Feb 2007 00:45:28 +0000 Subject: [PATCH] Added ability to shutdown audio output --- ChangeLog | 2 ++ src/audio/audio.c | 16 ++++++++++++++++ src/module/sdl.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 782cea4..3bb18c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ 2007-02-18 + -Added ability to close of SDL audio output. + -Added crossfading to audio output system. -Revamped audio output API to move resource access to the ao plugin, allowing for the plugin to have more control over how things are played. diff --git a/src/audio/audio.c b/src/audio/audio.c index 014b9d2..328eb83 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -37,6 +37,14 @@ struct audio_data *ao_open(const char *resource, int flags) return ao->open(resource, flags); } +void ao_close(struct audio_data *data) +{ + if (!ao) + return NULL; + + return ao->close(data); +} + int ao_play(struct audio_data *data, int nloops, double volume) { if (!ao) @@ -69,6 +77,14 @@ int ao_init(int flags) return ao->init(flags); } +int ao_fini(int force) +{ + if (!ao) + return -1; + + return ao->fini(force); +} + static int ao_register(const char *name, void *data) { ao = data; diff --git a/src/module/sdl.c b/src/module/sdl.c index 811c32b..336d4bb 100644 --- a/src/module/sdl.c +++ b/src/module/sdl.c @@ -61,6 +61,8 @@ static struct channel { } *channels; static int nchannels; +static unsigned int opensounds; + /* Sets a channel to fade to the target volume over the course of nsec seconds. */ static void setfade(int c, double target, double nsec) @@ -81,6 +83,7 @@ static void data_delete(struct audio_data *data) { free(data->data); free(data); + opensounds--; } /* Stop a channel */ @@ -228,6 +231,10 @@ static struct audio_data *sdl_ao_open(const char *resource, int flags) goto err; } + SDL_LockAudio(); + opensounds++; + SDL_UnlockAudio(); + return new; err: free(new); @@ -236,10 +243,14 @@ err: static void sdl_ao_close(struct audio_data *data) { + SDL_LockAudio(); + data->delete = 1; - + if (!data->playing) data_delete(data); + + SDL_UnlockAudio(); } static int setupchannel(int c, struct audio_data *data, int nloops) @@ -302,7 +313,7 @@ static int sdl_ao_stop(int id) static int sdl_ao_fade(int id, struct audio_data *data, int nloops, double vol) { - int i, chan = -1; + int i, rc, chan = -1; SDL_LockAudio(); @@ -318,13 +329,13 @@ static int sdl_ao_fade(int id, struct audio_data *data, int nloops, double vol) if (chan == -1) return -1; - setupchannel(chan, data, nloops); + rc = setupchannel(chan, data, nloops); channels[chan].volume = 0; setfade(chan, vol, 4); SDL_UnlockAudio(); - return 0; + return rc; } /* Open the SDL audio device. TO DO: This is ugly, fix it. */ @@ -384,18 +395,48 @@ static int sdl_ao_init(int flags) SDL_PauseAudio(0); + logger.write(LOG_INFO, SDL_MODULE, + "Audio output initialized successfully."); + return 0; err: SDL_CloseAudio(); return -1; } +static int sdl_ao_fini(int force) +{ + int i; + + SDL_LockAudio(); + + /* IF our refcounts are OK, opensounds > 0 means nothing is playing. */ + if (!force && opensounds) { + logger.write(LOG_WARNING, SDL_MODULE, + "Can't shutdown while sounds still open."); + return -1; + } + + SDL_UnlockAudio(); + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + + for (i = 0; i < nchannels; i++) + if (channels[i].data) + stop(i); + + logger.write(LOG_INFO, SDL_MODULE, "%s audio shutdown successful.", + (force) ? "Forced" : "Normal"); + + return 0; +} + int init(plugin_useservice_t useservice) { static struct audio_output ao_sdl = { #undef init .init = sdl_ao_init, -// .fini = sdl_ao_fini, + .fini = sdl_ao_fini, .open = sdl_ao_open, .close = sdl_ao_close, .play = sdl_ao_play, -- 2.11.4.GIT