From 1ff39476eb3d14e4535f9b7600213c905b346185 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 21 Oct 2009 18:33:05 +0200 Subject: output/jack: implement the "pause" method Don't disconnect from JACK during pause. --- NEWS | 1 + src/output/jack_output_plugin.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/NEWS b/NEWS index 4906fa3f3..569782512 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ ver 0.16 (20??/??/??) - pulse: announce "media.role=music" - pulse: renamed context to "Music Player Daemon" - pulse: connect to server on MPD startup, implement pause + - jack: don't disconnect during pause * mixers: - removed support for legacy mixer configuration - reimplemented software volume as mixer+filter plugin diff --git a/src/output/jack_output_plugin.c b/src/output/jack_output_plugin.c index 0c935633a..a73f80c48 100644 --- a/src/output/jack_output_plugin.c +++ b/src/output/jack_output_plugin.c @@ -58,6 +58,12 @@ struct jack_data { jack_ringbuffer_t *ringbuffer[2]; bool shutdown; + + /** + * While this flag is set, the "process" callback generates + * silence. + */ + bool pause; }; /** @@ -116,6 +122,19 @@ mpd_jack_process(jack_nframes_t nframes, void *arg) if (nframes <= 0) return 0; + if (jd->pause) { + /* generate silence while MPD is paused */ + + for (unsigned i = 0; i < G_N_ELEMENTS(jd->ringbuffer); ++i) { + out = jack_port_get_buffer(jd->ports[i], nframes); + + for (jack_nframes_t f = 0; f < nframes; ++f) + out[f] = 0.0; + } + + return 0; + } + for (unsigned i = 0; i < G_N_ELEMENTS(jd->ringbuffer); ++i) { available = jack_ringbuffer_read_space(jd->ringbuffer[i]); assert(available % sample_size == 0); @@ -308,6 +327,8 @@ mpd_jack_open(void *data, struct audio_format *audio_format, GError **error) assert(jd != NULL); + jd->pause = false; + if (!mpd_jack_connect(jd, error)) { mpd_jack_client_free(jd); return false; @@ -405,6 +426,8 @@ mpd_jack_play(void *data, const void *chunk, size_t size, GError **error) const size_t frame_size = audio_format_frame_size(&jd->audio_format); size_t space = 0, space1; + jd->pause = false; + assert(size % frame_size == 0); size /= frame_size; @@ -438,6 +461,23 @@ mpd_jack_play(void *data, const void *chunk, size_t size, GError **error) return size * frame_size; } +static bool +mpd_jack_pause(void *data) +{ + struct jack_data *jd = data; + + if (jd->shutdown) + return false; + + jd->pause = true; + + /* due to a MPD API limitation, we have to sleep a little bit + here, to avoid hogging the CPU */ + g_usleep(50000); + + return true; +} + const struct audio_output_plugin jack_output_plugin = { .name = "jack", .test_default_device = mpd_jack_test_default_device, @@ -446,5 +486,6 @@ const struct audio_output_plugin jack_output_plugin = { .open = mpd_jack_open, .play = mpd_jack_play, .cancel = mpd_jack_cancel, + .pause = mpd_jack_pause, .close = mpd_jack_close, }; -- cgit v1.2.3