diff options
author | Max Kellermann <max@duempel.org> | 2010-03-03 20:29:33 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2010-03-10 19:49:31 +0100 |
commit | e686d19154d8de8f9884cd768ef5e600991076ef (patch) | |
tree | 655e0cfc3577f98d20082ffe61f66aa7f81a55f7 | |
parent | 762565e9d11b19534cff2d74715af0645f3885d8 (diff) | |
download | mpd-e686d19154d8de8f9884cd768ef5e600991076ef.tar.gz mpd-e686d19154d8de8f9884cd768ef5e600991076ef.tar.xz mpd-e686d19154d8de8f9884cd768ef5e600991076ef.zip |
output: added option "always_on" for radio stations
Did you ever accidently click "stop" while feeding a radio station?
This option sets the output device to "pause" to disable the "close"
method. It falls back to "pause" then, which is specific to the
plugin. Some plugins implement it by feeding silence.
-rw-r--r-- | doc/user.xml | 12 | ||||
-rw-r--r-- | src/output_all.c | 23 | ||||
-rw-r--r-- | src/output_all.h | 7 | ||||
-rw-r--r-- | src/output_control.c | 15 | ||||
-rw-r--r-- | src/output_control.h | 9 | ||||
-rw-r--r-- | src/output_init.c | 1 | ||||
-rw-r--r-- | src/output_internal.h | 6 | ||||
-rw-r--r-- | src/player_thread.c | 2 |
8 files changed, 73 insertions, 2 deletions
diff --git a/doc/user.xml b/doc/user.xml index 30fcae696..e1e62eb92 100644 --- a/doc/user.xml +++ b/doc/user.xml @@ -339,6 +339,18 @@ cd mpd-version</programlisting> </row> <row> <entry> + <varname>always_on</varname> + <parameter>yes|no</parameter> + </entry> + <entry> + If set to "yes", then MPD attempts to keep this audio + output always open. This may be useful for streaming + servers, when you don't want to disconnect all + listeners even when playback is accidently stopped. + </entry> + </row> + <row> + <entry> <varname>mixer_type</varname> <parameter>hardware|software|none</parameter> </entry> diff --git a/src/output_all.c b/src/output_all.c index 4b7701144..dbd5a6ce6 100644 --- a/src/output_all.c +++ b/src/output_all.c @@ -559,6 +559,29 @@ audio_output_all_close(void) } void +audio_output_all_release(void) +{ + unsigned int i; + + for (i = 0; i < num_audio_outputs; ++i) + audio_output_release(&audio_outputs[i]); + + if (g_mp != NULL) { + assert(g_music_buffer != NULL); + + music_pipe_clear(g_mp, g_music_buffer); + music_pipe_free(g_mp); + g_mp = NULL; + } + + g_music_buffer = NULL; + + audio_format_clear(&input_audio_format); + + audio_output_all_elapsed_time = -1.0; +} + +void audio_output_all_song_border(void) { /* clear the elapsed_time pointer at the beginning of a new diff --git a/src/output_all.h b/src/output_all.h index 8c3f1e80d..a579bf5f1 100644 --- a/src/output_all.h +++ b/src/output_all.h @@ -92,6 +92,13 @@ void audio_output_all_close(void); /** + * Closes all audio outputs. Outputs with the "always_on" flag are + * put into pause mode. + */ +void +audio_output_all_release(void); + +/** * Enqueue a #music_chunk object for playing, i.e. pushes it to a * #music_pipe. * diff --git a/src/output_control.c b/src/output_control.c index b5d983ae1..17edc3d72 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -118,9 +118,13 @@ audio_output_open(struct audio_output *ao, if (ao->open && audio_format_equals(audio_format, &ao->in_audio_format)) { - assert(ao->pipe == mp); + assert(ao->pipe == mp || + (ao->always_on && ao->pause)); if (ao->pause) { + ao->chunk = NULL; + ao->pipe = mp; + /* unpause with the CANCEL command; this is a hack, but suits well for forcing the thread to leave the ao_pause() thread, and we need @@ -266,6 +270,15 @@ void audio_output_close(struct audio_output *ao) g_mutex_unlock(ao->mutex); } +void +audio_output_release(struct audio_output *ao) +{ + if (ao->always_on) + audio_output_pause(ao); + else + audio_output_close(ao); +} + void audio_output_finish(struct audio_output *ao) { audio_output_close(ao); diff --git a/src/output_control.h b/src/output_control.h index 9c2171a45..7f4f4a53c 100644 --- a/src/output_control.h +++ b/src/output_control.h @@ -71,7 +71,16 @@ void audio_output_drain_async(struct audio_output *ao); void audio_output_cancel(struct audio_output *ao); + void audio_output_close(struct audio_output *ao); + +/** + * Closes the audio output, but if the "always_on" flag is set, put it + * into pause mode instead. + */ +void +audio_output_release(struct audio_output *ao); + void audio_output_finish(struct audio_output *ao); #endif diff --git a/src/output_init.c b/src/output_init.c index f3d22ace1..6ee340edc 100644 --- a/src/output_init.c +++ b/src/output_init.c @@ -184,6 +184,7 @@ audio_output_init(struct audio_output *ao, const struct config_param *param, } ao->plugin = plugin; + ao->always_on = config_get_block_bool(param, "always_on", false); ao->enabled = config_get_block_bool(param, "enabled", true); ao->really_enabled = false; ao->open = false; diff --git a/src/output_internal.h b/src/output_internal.h index 2a438c62f..06df9531b 100644 --- a/src/output_internal.h +++ b/src/output_internal.h @@ -76,6 +76,12 @@ struct audio_output { struct mixer *mixer; /** + * Shall this output always play something (i.e. silence), + * even when playback is stopped? + */ + bool always_on; + + /** * Has the user enabled this device? */ bool enabled; diff --git a/src/player_thread.c b/src/player_thread.c index 3e234c4ff..2496f0cdb 100644 --- a/src/player_thread.c +++ b/src/player_thread.c @@ -978,7 +978,7 @@ static gpointer player_task(G_GNUC_UNUSED gpointer arg) case PLAYER_COMMAND_CLOSE_AUDIO: player_unlock(); - audio_output_all_close(); + audio_output_all_release(); player_lock(); player_command_finished_locked(); |