aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-05 20:02:04 +0100
committerMax Kellermann <max@duempel.org>2009-11-05 20:02:04 +0100
commit979cd5a7684ae6089abb1b6280539fe563a783fb (patch)
treee6ac653f293f65073a898980fff684a30e651b1e
parenta68da8a475292ba77cf144789b50c691ec83c719 (diff)
downloadmpd-979cd5a7684ae6089abb1b6280539fe563a783fb.tar.gz
mpd-979cd5a7684ae6089abb1b6280539fe563a783fb.tar.xz
mpd-979cd5a7684ae6089abb1b6280539fe563a783fb.zip
output/jack: support mono input
When MPD plays a mono song (audio_format.channel==1), connect only one source port to both destination ports.
-rw-r--r--NEWS1
-rw-r--r--src/output/jack_output_plugin.c54
2 files changed, 42 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index ddbdf63c4..653105f54 100644
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,7 @@ ver 0.16 (20??/??/??)
- jack: connect to server on MPD startup
- jack: added option "client_name"
- jack: clear ring buffers before activating
+ - jack: support mono input
- wildcards allowed in audio_format configuration
- alsa: don't recover on CANCEL
- consistently lock audio output objects
diff --git a/src/output/jack_output_plugin.c b/src/output/jack_output_plugin.c
index 8ada73efc..fcc736787 100644
--- a/src/output/jack_output_plugin.c
+++ b/src/output/jack_output_plugin.c
@@ -93,7 +93,7 @@ mpd_jack_process(jack_nframes_t nframes, void *arg)
if (jd->pause) {
/* generate silence while MPD is paused */
- for (unsigned i = 0; i < G_N_ELEMENTS(jd->ringbuffer); ++i) {
+ for (unsigned i = 0; i < jd->audio_format.channels; ++i) {
out = jack_port_get_buffer(jd->ports[i], nframes);
for (jack_nframes_t f = 0; f < nframes; ++f)
@@ -103,7 +103,7 @@ mpd_jack_process(jack_nframes_t nframes, void *arg)
return 0;
}
- for (unsigned i = 0; i < G_N_ELEMENTS(jd->ringbuffer); ++i) {
+ for (unsigned i = 0; i < jd->audio_format.channels; ++i) {
available = jack_ringbuffer_read_space(jd->ringbuffer[i]);
assert(available % sample_size == 0);
available /= sample_size;
@@ -133,7 +133,9 @@ static void
set_audioformat(struct jack_data *jd, struct audio_format *audio_format)
{
audio_format->sample_rate = jack_get_sample_rate(jd->client);
- audio_format->channels = 2;
+
+ if (audio_format->channels > 2)
+ audio_format->channels = 2;
if (audio_format->bits != 16 && audio_format->bits != 24)
audio_format->bits = 24;
@@ -328,8 +330,7 @@ mpd_jack_start(struct jack_data *jd, GError **error_r)
{
const char *output_ports[2], **jports;
- if (jd->client == NULL && !mpd_jack_connect(jd, error_r))
- return false;
+ assert(jd->client != NULL);
/* allocate the ring buffers on the first open(); these
persist until MPD exits. It's too unsafe to delete them
@@ -377,7 +378,7 @@ mpd_jack_start(struct jack_data *jd, GError **error_r)
jports = NULL;
}
- for (unsigned i = 0; i < G_N_ELEMENTS(jd->ports); ++i) {
+ for (unsigned i = 0; i < jd->audio_format.channels; ++i) {
int ret;
ret = jack_connect(jd->client, jack_port_name(jd->ports[i]),
@@ -395,6 +396,26 @@ mpd_jack_start(struct jack_data *jd, GError **error_r)
}
}
+ if (jd->audio_format.channels == 1) {
+ /* mono input file: connect the one source channel to
+ the both destination channels */
+ int ret;
+
+ ret = jack_connect(jd->client, jack_port_name(jd->ports[0]),
+ output_ports[1]);
+ if (ret != 0) {
+ g_set_error(error_r, jack_output_quark(), 0,
+ "Not a valid JACK port: %s",
+ output_ports[1]);
+
+ if (jports != NULL)
+ free(jports);
+
+ mpd_jack_stop(jd);
+ return false;
+ }
+ }
+
if (jports != NULL)
free(jports);
@@ -410,12 +431,15 @@ mpd_jack_open(void *data, struct audio_format *audio_format, GError **error_r)
jd->pause = false;
- if (!mpd_jack_start(jd, error_r))
+ if (jd->client == NULL && !mpd_jack_connect(jd, error_r))
return false;
set_audioformat(jd, audio_format);
jd->audio_format = *audio_format;
+ if (!mpd_jack_start(jd, error_r))
+ return false;
+
return true;
}
@@ -444,9 +468,11 @@ mpd_jack_write_samples_16(struct jack_data *jd, const int16_t *src,
jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
sizeof(sample));
- sample = sample_16_to_jack(*src++);
- jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
- sizeof(sample));
+ if (jd->audio_format.channels >= 2) {
+ sample = sample_16_to_jack(*src++);
+ jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
+ sizeof(sample));
+ }
}
}
@@ -467,9 +493,11 @@ mpd_jack_write_samples_24(struct jack_data *jd, const int32_t *src,
jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
sizeof(sample));
- sample = sample_24_to_jack(*src++);
- jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
- sizeof(sample));
+ if (jd->audio_format.channels >= 2) {
+ sample = sample_24_to_jack(*src++);
+ jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
+ sizeof(sample));
+ }
}
}