output/jack: support mono input
When MPD plays a mono song (audio_format.channel==1), connect only one source port to both destination ports.
This commit is contained in:
parent
a68da8a475
commit
979cd5a768
1
NEWS
1
NEWS
@ -37,6 +37,7 @@ ver 0.16 (20??/??/??)
|
|||||||
- jack: connect to server on MPD startup
|
- jack: connect to server on MPD startup
|
||||||
- jack: added option "client_name"
|
- jack: added option "client_name"
|
||||||
- jack: clear ring buffers before activating
|
- jack: clear ring buffers before activating
|
||||||
|
- jack: support mono input
|
||||||
- wildcards allowed in audio_format configuration
|
- wildcards allowed in audio_format configuration
|
||||||
- alsa: don't recover on CANCEL
|
- alsa: don't recover on CANCEL
|
||||||
- consistently lock audio output objects
|
- consistently lock audio output objects
|
||||||
|
@ -93,7 +93,7 @@ mpd_jack_process(jack_nframes_t nframes, void *arg)
|
|||||||
if (jd->pause) {
|
if (jd->pause) {
|
||||||
/* generate silence while MPD is paused */
|
/* 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);
|
out = jack_port_get_buffer(jd->ports[i], nframes);
|
||||||
|
|
||||||
for (jack_nframes_t f = 0; f < nframes; ++f)
|
for (jack_nframes_t f = 0; f < nframes; ++f)
|
||||||
@ -103,7 +103,7 @@ mpd_jack_process(jack_nframes_t nframes, void *arg)
|
|||||||
return 0;
|
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]);
|
available = jack_ringbuffer_read_space(jd->ringbuffer[i]);
|
||||||
assert(available % sample_size == 0);
|
assert(available % sample_size == 0);
|
||||||
available /= sample_size;
|
available /= sample_size;
|
||||||
@ -133,6 +133,8 @@ static void
|
|||||||
set_audioformat(struct jack_data *jd, struct audio_format *audio_format)
|
set_audioformat(struct jack_data *jd, struct audio_format *audio_format)
|
||||||
{
|
{
|
||||||
audio_format->sample_rate = jack_get_sample_rate(jd->client);
|
audio_format->sample_rate = jack_get_sample_rate(jd->client);
|
||||||
|
|
||||||
|
if (audio_format->channels > 2)
|
||||||
audio_format->channels = 2;
|
audio_format->channels = 2;
|
||||||
|
|
||||||
if (audio_format->bits != 16 && audio_format->bits != 24)
|
if (audio_format->bits != 16 && audio_format->bits != 24)
|
||||||
@ -328,8 +330,7 @@ mpd_jack_start(struct jack_data *jd, GError **error_r)
|
|||||||
{
|
{
|
||||||
const char *output_ports[2], **jports;
|
const char *output_ports[2], **jports;
|
||||||
|
|
||||||
if (jd->client == NULL && !mpd_jack_connect(jd, error_r))
|
assert(jd->client != NULL);
|
||||||
return false;
|
|
||||||
|
|
||||||
/* allocate the ring buffers on the first open(); these
|
/* allocate the ring buffers on the first open(); these
|
||||||
persist until MPD exits. It's too unsafe to delete them
|
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;
|
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;
|
int ret;
|
||||||
|
|
||||||
ret = jack_connect(jd->client, jack_port_name(jd->ports[i]),
|
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)
|
if (jports != NULL)
|
||||||
free(jports);
|
free(jports);
|
||||||
|
|
||||||
@ -410,12 +431,15 @@ mpd_jack_open(void *data, struct audio_format *audio_format, GError **error_r)
|
|||||||
|
|
||||||
jd->pause = false;
|
jd->pause = false;
|
||||||
|
|
||||||
if (!mpd_jack_start(jd, error_r))
|
if (jd->client == NULL && !mpd_jack_connect(jd, error_r))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
set_audioformat(jd, audio_format);
|
set_audioformat(jd, audio_format);
|
||||||
jd->audio_format = *audio_format;
|
jd->audio_format = *audio_format;
|
||||||
|
|
||||||
|
if (!mpd_jack_start(jd, error_r))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,11 +468,13 @@ mpd_jack_write_samples_16(struct jack_data *jd, const int16_t *src,
|
|||||||
jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
|
jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
|
||||||
sizeof(sample));
|
sizeof(sample));
|
||||||
|
|
||||||
|
if (jd->audio_format.channels >= 2) {
|
||||||
sample = sample_16_to_jack(*src++);
|
sample = sample_16_to_jack(*src++);
|
||||||
jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
|
jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
|
||||||
sizeof(sample));
|
sizeof(sample));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline jack_default_audio_sample_t
|
static inline jack_default_audio_sample_t
|
||||||
sample_24_to_jack(int32_t sample)
|
sample_24_to_jack(int32_t sample)
|
||||||
@ -467,11 +493,13 @@ mpd_jack_write_samples_24(struct jack_data *jd, const int32_t *src,
|
|||||||
jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
|
jack_ringbuffer_write(jd->ringbuffer[0], (void*)&sample,
|
||||||
sizeof(sample));
|
sizeof(sample));
|
||||||
|
|
||||||
|
if (jd->audio_format.channels >= 2) {
|
||||||
sample = sample_24_to_jack(*src++);
|
sample = sample_24_to_jack(*src++);
|
||||||
jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
|
jack_ringbuffer_write(jd->ringbuffer[1], (void*)&sample,
|
||||||
sizeof(sample));
|
sizeof(sample));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mpd_jack_write_samples(struct jack_data *jd, const void *src,
|
mpd_jack_write_samples(struct jack_data *jd, const void *src,
|
||||||
|
Loading…
Reference in New Issue
Block a user