4 * Copyright (c) 2003 by Maarten de Boer <mdeboer@iua.upf.es>
5 * 2005 Takashi Iwai <tiwai@suse.de>
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <jack/jack.h>
30 #include <alsa/asoundlib.h>
31 #include <alsa/pcm_external.h>
34 #define MAX_PERIODS_MULTIPLE 64
36 typedef struct snd_pcm_jack_port_list {
37 struct snd_pcm_jack_port_list *next;
38 /* will always be allocated with size of the string.
39 * See snd_pcm_jack_port_list_add().
42 } snd_pcm_jack_port_list_t;
48 int activated; /* jack is activated? */
49 pthread_mutex_t running_mutex;
50 int running; /* jack is running? */
52 snd_pcm_jack_port_list_t **port_names;
53 unsigned int num_ports;
54 snd_pcm_uframes_t boundary;
55 snd_pcm_uframes_t hw_ptr;
56 unsigned int sample_bits;
57 snd_pcm_uframes_t min_avail;
58 int use_period_alignment;
60 snd_pcm_channel_area_t *areas;
63 jack_client_t *client;
65 /* JACK thread -> ALSA thread */
69 /* snd_pcm_ioplug_avail() was introduced after alsa-lib 1.1.6 */
70 #if SND_LIB_VERSION < 0x10107
71 static snd_pcm_uframes_t snd_pcm_ioplug_avail(const snd_pcm_ioplug_t *io,
72 const snd_pcm_uframes_t hw_ptr,
73 const snd_pcm_uframes_t appl_ptr)
75 return io->buffer_size - snd_pcm_ioplug_hw_avail(io, hw_ptr, appl_ptr);
79 /* adds one element to the head of the list */
80 static int snd_pcm_jack_port_list_add(snd_pcm_jack_t *jack,
81 const unsigned int channel,
82 const char * const name)
84 const size_t name_size = strlen(name) + 1;
85 const size_t elem_size = sizeof(snd_pcm_jack_port_list_t) + name_size;
86 snd_pcm_jack_port_list_t * const elem = calloc(1, elem_size);
91 /* Above it is guaranteed that elem->name is big enough for the size of
92 * name because strlen(name) + 1 will be used to allocate the buffer.
94 strcpy(elem->name, name);
95 elem->next = jack->port_names[channel];
97 jack->port_names[channel] = elem;
102 static int pcm_poll_block_check(snd_pcm_ioplug_t *io)
105 snd_pcm_uframes_t avail;
106 snd_pcm_jack_t *jack = io->private_data;
108 if (io->state == SND_PCM_STATE_RUNNING ||
109 io->state == SND_PCM_STATE_DRAINING ||
110 (io->state == SND_PCM_STATE_PREPARED && io->stream == SND_PCM_STREAM_CAPTURE)) {
111 avail = snd_pcm_ioplug_avail(io, jack->hw_ptr, io->appl_ptr);
112 if (avail < jack->min_avail) {
113 while (read(io->poll_fd, &buf, sizeof(buf)) == sizeof(buf))
122 static int pcm_poll_unblock_check(snd_pcm_ioplug_t *io)
125 snd_pcm_uframes_t avail;
126 snd_pcm_jack_t *jack = io->private_data;
128 avail = snd_pcm_ioplug_avail(io, jack->hw_ptr, io->appl_ptr);
129 /* In draining state poll_fd is used to wait
130 * till all pending frames are played.
131 * Therefore it has to be guarantee that a poll event is also generated
132 * if the buffer contains less than min_avail frames
134 if (avail >= jack->min_avail || io->state == SND_PCM_STATE_DRAINING) {
135 write(jack->fd, &buf, 1);
142 static void snd_pcm_jack_free(snd_pcm_jack_t *jack)
148 jack_client_close(jack->client);
149 if (jack->port_names) {
152 for (i = 0; i < jack->num_ports; i++) {
153 snd_pcm_jack_port_list_t *port_elem =
156 while (port_elem != NULL) {
157 snd_pcm_jack_port_list_t *next_port_elem =
160 port_elem = next_port_elem;
163 free(jack->port_names);
164 jack->port_names = NULL;
166 pthread_mutex_destroy (&jack->running_mutex);
169 if (jack->io.poll_fd >= 0)
170 close(jack->io.poll_fd);
176 static int snd_pcm_jack_close(snd_pcm_ioplug_t *io)
178 snd_pcm_jack_t *jack = io->private_data;
179 snd_pcm_jack_free(jack);
183 static int snd_pcm_jack_poll_revents(snd_pcm_ioplug_t *io,
184 struct pollfd *pfds, unsigned int nfds,
185 unsigned short *revents)
187 assert(pfds && nfds == 1 && revents);
189 *revents = pfds[0].revents & ~(POLLIN | POLLOUT);
190 if (pfds[0].revents & POLLIN && !pcm_poll_block_check(io))
191 *revents |= (io->stream == SND_PCM_STREAM_PLAYBACK) ? POLLOUT : POLLIN;
195 static snd_pcm_sframes_t snd_pcm_jack_pointer(snd_pcm_ioplug_t *io)
197 snd_pcm_jack_t *jack = io->private_data;
199 if (jack->xrun_detected)
202 #ifdef SND_PCM_IOPLUG_FLAG_BOUNDARY_WA
205 return jack->hw_ptr % io->buffer_size;
210 snd_pcm_jack_process_cb(jack_nframes_t nframes, snd_pcm_ioplug_t *io)
212 snd_pcm_jack_t *jack = io->private_data;
213 snd_pcm_uframes_t xfer = 0;
214 unsigned int channel;
216 if (pthread_mutex_trylock (&jack->running_mutex) == EBUSY) {
217 /* Note that locking should only ever fail if
218 * snd_pcm_jack_start or snd_pcm_jack_stop is called at the
219 * same time, in which case dropping the current buffer is not
223 if (!jack->running) {
224 pthread_mutex_unlock (&jack->running_mutex);
228 for (channel = 0; channel < io->channels; channel++) {
229 jack->areas[channel].addr =
230 jack_port_get_buffer (jack->ports[channel], nframes);
231 jack->areas[channel].first = 0;
232 jack->areas[channel].step = jack->sample_bits;
235 if (io->state == SND_PCM_STATE_RUNNING ||
236 io->state == SND_PCM_STATE_DRAINING) {
237 snd_pcm_uframes_t hw_ptr = jack->hw_ptr;
238 const snd_pcm_uframes_t hw_avail = snd_pcm_ioplug_hw_avail(io, hw_ptr,
242 const snd_pcm_channel_area_t *areas = snd_pcm_ioplug_mmap_areas(io);
243 const snd_pcm_uframes_t offset = hw_ptr % io->buffer_size;
249 if (io->stream == SND_PCM_STREAM_PLAYBACK)
250 snd_pcm_areas_copy_wrap(jack->areas, 0, nframes,
256 snd_pcm_areas_copy_wrap(areas, offset,
258 jack->areas, 0, nframes,
263 if (hw_ptr >= jack->boundary)
264 hw_ptr -= jack->boundary;
265 jack->hw_ptr = hw_ptr;
269 /* check if requested frames were copied */
270 if (xfer < nframes) {
271 /* always fill the not yet written JACK buffer with silence */
272 if (io->stream == SND_PCM_STREAM_PLAYBACK) {
273 const snd_pcm_uframes_t frames = nframes - xfer;
275 snd_pcm_areas_silence(jack->areas, xfer, io->channels,
279 if (io->state == SND_PCM_STATE_RUNNING ||
280 io->state == SND_PCM_STATE_DRAINING) {
281 /* report Xrun to user application */
282 jack->xrun_detected = true;
286 pcm_poll_unblock_check(io); /* unblock socket for polling if needed */
288 pthread_mutex_unlock (&jack->running_mutex);
293 static void jack_allocate_and_register_ports(snd_pcm_ioplug_t *io)
295 snd_pcm_jack_t *jack = io->private_data;
298 jack->ports = calloc(io->channels, sizeof(jack_port_t *));
300 for (i = 0; i < io->channels; i++) {
303 if (io->stream == SND_PCM_STREAM_PLAYBACK) {
304 sprintf(port_name, "out_%03d", i);
305 jack->ports[i] = jack_port_register(jack->client, port_name,
306 JACK_DEFAULT_AUDIO_TYPE,
307 JackPortIsOutput, 0);
309 sprintf(port_name, "in_%03d", i);
310 jack->ports[i] = jack_port_register(jack->client, port_name,
311 JACK_DEFAULT_AUDIO_TYPE,
317 static int snd_pcm_jack_prepare(snd_pcm_ioplug_t *io)
319 snd_pcm_jack_t *jack = io->private_data;
321 snd_pcm_sw_params_t *swparams;
324 if (io->channels != jack->num_ports) {
325 SNDERR("Channel count %d not equal to no. of ports %d in JACK",
326 io->channels, jack->num_ports);
331 jack->xrun_detected = false;
333 jack->min_avail = io->period_size;
334 snd_pcm_sw_params_alloca(&swparams);
335 err = snd_pcm_sw_params_current(io->pcm, swparams);
337 snd_pcm_sw_params_get_avail_min(swparams, &jack->min_avail);
338 /* get boundary for available calulation */
339 snd_pcm_sw_params_get_boundary(swparams, &jack->boundary);
342 if (io->stream == SND_PCM_STREAM_PLAYBACK)
343 pcm_poll_unblock_check(io); /* playback pcm initially accepts writes */
345 pcm_poll_block_check(io); /* block capture pcm if that's XRUN recovery */
348 jack_allocate_and_register_ports(io);
349 jack_set_process_callback(jack->client,
350 (JackProcessCallback)snd_pcm_jack_process_cb, io);
356 if (jack_activate(jack->client))
361 for (i = 0; i < io->channels && i < jack->num_ports; i++) {
362 const char * const own_port = jack_port_name(jack->ports[i]);
363 snd_pcm_jack_port_list_t *port_elem;
365 for (port_elem = jack->port_names[i]; port_elem != NULL;
366 port_elem = port_elem->next) {
367 const char *src, *dst;
368 if (io->stream == SND_PCM_STREAM_PLAYBACK) {
370 dst = port_elem->name;
372 src = port_elem->name;
375 if (jack_connect(jack->client, src, dst)) {
376 fprintf(stderr, "cannot connect %s to %s\n",
385 static int snd_pcm_jack_start(snd_pcm_ioplug_t *io)
387 snd_pcm_jack_t *jack = io->private_data;
388 pthread_mutex_lock (&jack->running_mutex);
390 pthread_mutex_unlock (&jack->running_mutex);
392 * Since the processing of jack_activate() and jack_connect() take a
393 * while longer, snd_pcm_jack_start() was blocked.
394 * Consider a usecase of reading the data from capture device and
395 * writing to a playback device, since the capture device is
396 * already started and the starting of playback device is blocked,
397 * it leads to XRUNs for capture device.
398 * Therefore these calls are moved to snd_pcm_jack_prepare(),
399 * So that the capture and playback devices can be prepared in advance
400 * and starting of the device doesn't take too long.
405 static int snd_pcm_jack_stop(snd_pcm_ioplug_t *io)
407 snd_pcm_jack_t *jack = io->private_data;
408 pthread_mutex_lock (&jack->running_mutex);
410 pthread_mutex_unlock (&jack->running_mutex);
414 static int snd_pcm_jack_hw_free(snd_pcm_ioplug_t *io)
416 snd_pcm_jack_t *jack = io->private_data;
418 if (jack->activated) {
419 jack_deactivate(jack->client);
424 for (i = 0; i < io->channels; i++) {
425 if (jack->ports[i]) {
426 jack_port_unregister(jack->client, jack->ports[i]);
427 jack->ports[i] = NULL;
434 static int snd_pcm_jack_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params)
436 snd_pcm_jack_t *jack = io->private_data;
437 snd_pcm_sw_params_get_avail_min(params, &jack->min_avail);
441 static snd_pcm_ioplug_callback_t jack_pcm_callback = {
442 .close = snd_pcm_jack_close,
443 .start = snd_pcm_jack_start,
444 .stop = snd_pcm_jack_stop,
445 .pointer = snd_pcm_jack_pointer,
446 .hw_free = snd_pcm_jack_hw_free,
447 .prepare = snd_pcm_jack_prepare,
448 .poll_revents = snd_pcm_jack_poll_revents,
449 .sw_params = snd_pcm_jack_sw_params,
452 #define ARRAY_SIZE(ary) (sizeof(ary)/sizeof(ary[0]))
454 static int jack_set_hw_constraint(snd_pcm_jack_t *jack)
456 unsigned int access_list[] = {
457 SND_PCM_ACCESS_MMAP_INTERLEAVED,
458 SND_PCM_ACCESS_MMAP_NONINTERLEAVED,
459 SND_PCM_ACCESS_RW_INTERLEAVED,
460 SND_PCM_ACCESS_RW_NONINTERLEAVED
462 unsigned int format = SND_PCM_FORMAT_FLOAT;
463 unsigned int rate = jack_get_sample_rate(jack->client);
464 unsigned int psize_list[MAX_PERIODS_MULTIPLE];
465 unsigned int nframes = jack_get_buffer_size(jack->client);
466 unsigned int jack_buffer_bytes = (snd_pcm_format_size(format, nframes) *
471 if (!jack_buffer_bytes) {
472 SNDERR("Buffer size is zero");
475 for (i = 1; i <= ARRAY_SIZE(psize_list); i++)
476 psize_list[i-1] = jack_buffer_bytes * i;
478 jack->sample_bits = snd_pcm_format_physical_width(format);
479 if ((err = snd_pcm_ioplug_set_param_list(&jack->io, SND_PCM_IOPLUG_HW_ACCESS,
480 ARRAY_SIZE(access_list), access_list)) < 0 ||
481 (err = snd_pcm_ioplug_set_param_list(&jack->io, SND_PCM_IOPLUG_HW_FORMAT,
483 (err = snd_pcm_ioplug_set_param_minmax(&jack->io, SND_PCM_IOPLUG_HW_CHANNELS,
484 jack->num_ports, jack->num_ports)) < 0 ||
485 (err = snd_pcm_ioplug_set_param_minmax(&jack->io, SND_PCM_IOPLUG_HW_RATE,
487 (err = jack->use_period_alignment ?
488 snd_pcm_ioplug_set_param_list(&jack->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, ARRAY_SIZE(psize_list), psize_list) :
489 snd_pcm_ioplug_set_param_minmax(&jack->io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 128, 64*1024) ) < 0 ||
490 (err = snd_pcm_ioplug_set_param_minmax(&jack->io, SND_PCM_IOPLUG_HW_PERIODS,
497 static int parse_ports(snd_pcm_jack_t *jack, snd_config_t *conf)
499 snd_config_iterator_t i, next;
500 snd_pcm_jack_port_list_t **ports = NULL;
501 unsigned int cnt = 0;
502 unsigned int channel;
507 snd_config_for_each(i, next, conf) {
508 snd_config_t *n = snd_config_iterator_entry(i);
511 if (snd_config_get_id(n, &id) < 0)
515 jack->port_names = ports = calloc(cnt, sizeof(jack->port_names[0]));
518 jack->num_ports = cnt;
519 snd_config_for_each(i, next, conf) {
520 snd_config_t *n = snd_config_iterator_entry(i);
525 if (snd_config_get_id(n, &id) < 0)
528 if (snd_config_get_string(n, &port) >= 0) {
529 err = snd_pcm_jack_port_list_add(jack, channel, port);
532 } else if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
533 snd_config_iterator_t k, next_k;
535 snd_config_for_each(k, next_k, n) {
536 snd_config_t *m = snd_config_iterator_entry(k);
538 if (snd_config_get_string(m, &port) < 0)
540 err = snd_pcm_jack_port_list_add(jack, channel,
553 static int make_nonblock(int fd)
557 if ((fl = fcntl(fd, F_GETFL)) < 0)
563 return fcntl(fd, F_SETFL, fl | O_NONBLOCK);
566 static int snd_pcm_jack_open(snd_pcm_t **pcmp, const char *name,
567 const char *client_name,
568 snd_config_t *playback_conf,
569 snd_config_t *capture_conf,
570 int use_period_alignment,
571 snd_pcm_stream_t stream, int mode)
573 snd_pcm_jack_t *jack;
576 static unsigned int num = 0;
577 char jack_client_name[32];
580 jack = calloc(1, sizeof(*jack));
584 pthread_mutex_init (&jack->running_mutex, NULL);
587 jack->io.poll_fd = -1;
588 jack->use_period_alignment = use_period_alignment;
590 err = parse_ports(jack, stream == SND_PCM_STREAM_PLAYBACK ?
591 playback_conf : capture_conf);
593 snd_pcm_jack_free(jack);
597 if (jack->num_ports == 0) {
598 SNDERR("define the %s_ports section",
599 stream == SND_PCM_STREAM_PLAYBACK ? "playback" : "capture");
600 snd_pcm_jack_free(jack);
604 if (client_name == NULL) {
605 #if defined(_GNU_SOURCE)
606 const char *pname = program_invocation_short_name;
608 const char *pname = getprogname();
613 err = snprintf(jack_client_name, sizeof(jack_client_name),
614 "%s.%s.%d.%d", pname,
615 stream == SND_PCM_STREAM_PLAYBACK ? "P" : "C",
618 err = snprintf(jack_client_name, sizeof(jack_client_name),
621 if (err >= (int)sizeof(jack_client_name)) {
622 fprintf(stderr, "%s: WARNING: JACK client name '%s' truncated to %d characters, might not be unique\n",
623 __func__, jack_client_name, (int)strlen(jack_client_name));
626 jack->client = jack_client_open(jack_client_name, JackNoStartServer, NULL);
628 if (jack->client == 0) {
629 snd_pcm_jack_free(jack);
633 jack->areas = calloc(jack->num_ports, sizeof(snd_pcm_channel_area_t));
635 snd_pcm_jack_free(jack);
639 socketpair(AF_LOCAL, SOCK_STREAM, 0, fd);
641 make_nonblock(fd[0]);
642 make_nonblock(fd[1]);
646 jack->io.version = SND_PCM_IOPLUG_VERSION;
647 jack->io.name = "ALSA <-> JACK PCM I/O Plugin";
648 jack->io.callback = &jack_pcm_callback;
649 jack->io.private_data = jack;
650 jack->io.poll_fd = fd[1];
651 jack->io.poll_events = POLLIN;
652 jack->io.mmap_rw = 1;
654 #ifdef SND_PCM_IOPLUG_FLAG_BOUNDARY_WA
655 jack->io.flags = SND_PCM_IOPLUG_FLAG_BOUNDARY_WA;
657 #warning hw_ptr updates of buffer_size will not be recognized by the ALSA library. Consider to update your ALSA library.
660 err = snd_pcm_ioplug_create(&jack->io, name, stream, mode);
662 snd_pcm_jack_free(jack);
666 err = jack_set_hw_constraint(jack);
668 snd_pcm_ioplug_delete(&jack->io);
672 *pcmp = jack->io.pcm;
678 SND_PCM_PLUGIN_DEFINE_FUNC(jack)
680 snd_config_iterator_t i, next;
681 snd_config_t *playback_conf = NULL;
682 snd_config_t *capture_conf = NULL;
683 const char *client_name = NULL;
685 int align_jack_period = 1; /*by default we allow only JACK aligned period size*/
687 snd_config_for_each(i, next, conf) {
688 snd_config_t *n = snd_config_iterator_entry(i);
690 if (snd_config_get_id(n, &id) < 0)
692 if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || strcmp(id, "hint") == 0)
694 if (strcmp(id, "name") == 0) {
695 snd_config_get_string(n, &client_name);
698 if (strcmp(id, "playback_ports") == 0) {
699 if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
700 SNDERR("Invalid type for %s", id);
706 if (strcmp(id, "capture_ports") == 0) {
707 if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
708 SNDERR("Invalid type for %s", id);
714 if (strcmp(id, "align_psize") == 0) {
715 err = snd_config_get_bool(n);
718 align_jack_period = err ? 1 : 0;
721 SNDERR("Unknown field %s", id);
725 err = snd_pcm_jack_open(pcmp, name, client_name, playback_conf, capture_conf, align_jack_period, stream, mode);
730 SND_PCM_PLUGIN_SYMBOL(jack);