Set pretty-name for ALSA raw MIDI ports
[jack2.git] / linux / alsa / alsa_rawmidi.c
blob19578531e499b8377641b441a6d20f1c2ccaa82a
1 /*
2 * ALSA RAWMIDI < - > JACK MIDI bridge
4 * Copyright (c) 2006,2007 Dmitry S. Baikov
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* Required for clock_nanosleep(). Thanks, Nedko */
22 #define _GNU_SOURCE
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <pthread.h>
28 #include <time.h>
29 #include <limits.h>
30 #include <ctype.h>
31 #include <alsa/asoundlib.h>
33 #include "ringbuffer.h"
34 #include "midiport.h"
35 #include "alsa_midi_impl.h"
36 #include "midi_pack.h"
37 #include "midi_unpack.h"
38 #include "JackError.h"
40 extern int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem);
42 enum {
43 NANOSLEEP_RESOLUTION = 7000
46 #define NFRAMES_INF ULLONG_MAX
48 enum {
49 #ifndef JACK_MIDI_DEBUG
50 MAX_PFDS = 64,
51 MAX_PORTS = MAX_PFDS-1,
52 MAX_EVENTS = 4096,
53 MAX_DATA = 64*1024,
54 MIDI_THREAD_PRIO = 80
55 #else
56 MAX_PFDS = 6,
57 MAX_PORTS = MAX_PFDS-1,
58 MAX_EVENTS = 16,
59 MAX_DATA = 64,
60 MIDI_THREAD_PRIO = 80
61 #endif
64 enum PortState {
65 PORT_DESTROYED,
66 PORT_CREATED,
67 PORT_ADDED_TO_JACK,
68 PORT_ADDED_TO_MIDI,
69 PORT_REMOVED_FROM_MIDI,
70 PORT_REMOVED_FROM_JACK,
71 PORT_ZOMBIFIED,
74 typedef struct {
75 int id[4]; //card, dev, dir, sub;
76 } alsa_id_t;
78 typedef struct {
79 jack_time_t time;
80 int size;
81 int overruns;
82 } event_head_t;
84 typedef struct midi_port_t midi_port_t;
85 struct midi_port_t {
86 midi_port_t *next;
88 enum PortState state;
90 alsa_id_t id;
91 char dev[16];
92 char name[64];
93 char device_name[64];
95 jack_port_t *jack;
96 snd_rawmidi_t *rawmidi;
97 int npfds;
98 int is_ready;
100 jack_ringbuffer_t *event_ring;
101 jack_ringbuffer_t *data_ring;
105 typedef struct input_port_t {
106 midi_port_t base;
108 // jack
109 midi_unpack_t unpack;
111 // midi
112 int overruns;
113 } input_port_t;
115 typedef struct output_port_t {
116 midi_port_t base;
118 // jack
119 midi_pack_t packer;
121 // midi
122 event_head_t next_event;
123 int todo;
124 } output_port_t;
126 typedef struct alsa_rawmidi_t alsa_rawmidi_t;
128 typedef struct {
129 alsa_rawmidi_t *midi;
130 midi_port_t *port;
131 void *buffer;
132 jack_time_t frame_time;
133 jack_nframes_t nframes;
134 } process_jack_t;
136 typedef struct {
137 alsa_rawmidi_t *midi;
138 int mode;
139 midi_port_t *port;
140 struct pollfd *rpfds;
141 struct pollfd *wpfds;
142 int max_pfds;
143 jack_nframes_t cur_frames;
144 jack_time_t cur_time;
145 jack_time_t next_time;
146 } process_midi_t;
148 typedef struct midi_stream_t {
149 alsa_rawmidi_t *owner;
150 int mode;
151 const char *name;
152 pthread_t thread;
153 int wake_pipe[2];
155 struct {
156 jack_ringbuffer_t *new_ports;
157 int nports;
158 midi_port_t *ports[MAX_PORTS];
159 } jack, midi;
161 size_t port_size;
162 int (*port_init)(alsa_rawmidi_t *midi, midi_port_t *port);
163 void (*port_close)(alsa_rawmidi_t *midi, midi_port_t *port);
164 void (*process_jack)(process_jack_t *j);
165 int (*process_midi)(process_midi_t *m);
166 } midi_stream_t;
169 struct alsa_rawmidi_t {
170 alsa_midi_t ops;
172 jack_client_t *client;
173 int keep_walking;
175 struct {
176 pthread_t thread;
177 midi_port_t *ports;
178 int wake_pipe[2];
179 } scan;
181 midi_stream_t in;
182 midi_stream_t out;
183 int midi_in_cnt;
184 int midi_out_cnt;
187 static int input_port_init(alsa_rawmidi_t *midi, midi_port_t *port);
188 static void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port);
190 static void do_jack_input(process_jack_t *j);
191 static int do_midi_input(process_midi_t *m);
193 static int output_port_init(alsa_rawmidi_t *midi, midi_port_t *port);
194 static void output_port_close(alsa_rawmidi_t *midi, midi_port_t *port);
196 static void do_jack_output(process_jack_t *j);
197 static int do_midi_output(process_midi_t *m);
199 static
200 int stream_init(midi_stream_t *s, alsa_rawmidi_t *midi, const char *name)
202 s->owner = midi;
203 s->name = name;
204 if (pipe(s->wake_pipe)==-1) {
205 s->wake_pipe[0] = -1;
206 error_log("pipe() in stream_init(%s) failed: %s", name, strerror(errno));
207 return -errno;
209 s->jack.new_ports = jack_ringbuffer_create(sizeof(midi_port_t*)*MAX_PORTS);
210 s->midi.new_ports = jack_ringbuffer_create(sizeof(midi_port_t*)*MAX_PORTS);
211 if (!s->jack.new_ports || !s->midi.new_ports)
212 return -ENOMEM;
213 return 0;
216 static
217 void stream_close(midi_stream_t *s)
219 if (s->wake_pipe[0] != -1) {
220 close(s->wake_pipe[0]);
221 close(s->wake_pipe[1]);
223 if (s->jack.new_ports)
224 jack_ringbuffer_free(s->jack.new_ports);
225 if (s->midi.new_ports)
226 jack_ringbuffer_free(s->midi.new_ports);
229 static void alsa_rawmidi_delete(alsa_midi_t *m);
230 static int alsa_rawmidi_attach(alsa_midi_t *m);
231 static int alsa_rawmidi_detach(alsa_midi_t *m);
232 static int alsa_rawmidi_start(alsa_midi_t *m);
233 static int alsa_rawmidi_stop(alsa_midi_t *m);
234 static void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes);
235 static void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes);
237 alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack)
239 alsa_rawmidi_t *midi = calloc(1, sizeof(alsa_rawmidi_t));
240 if (!midi)
241 goto fail_0;
242 midi->client = jack;
243 if (pipe(midi->scan.wake_pipe)==-1) {
244 error_log("pipe() in alsa_midi_new failed: %s", strerror(errno));
245 goto fail_1;
248 if (stream_init(&midi->in, midi, "in"))
249 goto fail_2;
250 midi->in.mode = POLLIN;
251 midi->in.port_size = sizeof(input_port_t);
252 midi->in.port_init = input_port_init;
253 midi->in.port_close = input_port_close;
254 midi->in.process_jack = do_jack_input;
255 midi->in.process_midi = do_midi_input;
257 if (stream_init(&midi->out, midi, "out"))
258 goto fail_3;
259 midi->out.mode = POLLOUT;
260 midi->out.port_size = sizeof(output_port_t);
261 midi->out.port_init = output_port_init;
262 midi->out.port_close = output_port_close;
263 midi->out.process_jack = do_jack_output;
264 midi->out.process_midi = do_midi_output;
266 midi->ops.destroy = alsa_rawmidi_delete;
267 midi->ops.attach = alsa_rawmidi_attach;
268 midi->ops.detach = alsa_rawmidi_detach;
269 midi->ops.start = alsa_rawmidi_start;
270 midi->ops.stop = alsa_rawmidi_stop;
271 midi->ops.read = alsa_rawmidi_read;
272 midi->ops.write = alsa_rawmidi_write;
273 midi->midi_in_cnt = 0;
274 midi->midi_out_cnt = 0;
276 return &midi->ops;
277 fail_3:
278 stream_close(&midi->out);
279 fail_2:
280 stream_close(&midi->in);
281 close(midi->scan.wake_pipe[1]);
282 close(midi->scan.wake_pipe[0]);
283 fail_1:
284 free(midi);
285 fail_0:
286 return NULL;
289 static
290 midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list);
292 static
293 void alsa_rawmidi_delete(alsa_midi_t *m)
295 alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
297 alsa_rawmidi_detach(m);
299 stream_close(&midi->out);
300 stream_close(&midi->in);
301 close(midi->scan.wake_pipe[0]);
302 close(midi->scan.wake_pipe[1]);
304 free(midi);
307 static void* scan_thread(void *);
308 static void *midi_thread(void *arg);
310 static
311 int alsa_rawmidi_attach(alsa_midi_t *m)
313 return 0;
316 static
317 int alsa_rawmidi_detach(alsa_midi_t *m)
319 alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
320 midi_port_t **list;
322 alsa_rawmidi_stop(m);
324 list = &midi->scan.ports;
325 while (*list) {
326 (*list)->state = PORT_REMOVED_FROM_JACK;
327 list = scan_port_del(midi, list);
329 return 0;
332 static
333 int alsa_rawmidi_start(alsa_midi_t *m)
335 alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
336 int err;
337 char c = 'q';
338 if (midi->keep_walking == 1)
339 return -EALREADY;
341 midi->keep_walking = 1;
342 if ((err = jack_client_create_thread(midi->client, &midi->in.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->in))) {
343 midi->keep_walking = 0;
344 return err;
346 if ((err = jack_client_create_thread(midi->client, &midi->out.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->out))) {
347 midi->keep_walking = 0;
348 write(midi->in.wake_pipe[1], &c, 1);
349 pthread_join(midi->in.thread, NULL);
350 return err;
352 if ((err = jack_client_create_thread(midi->client, &midi->scan.thread, 0, 0, scan_thread, midi))) {
353 midi->keep_walking = 0;
354 write(midi->in.wake_pipe[1], &c, 1);
355 write(midi->out.wake_pipe[1], &c, 1);
356 pthread_join(midi->in.thread, NULL);
357 pthread_join(midi->out.thread, NULL);
358 return err;
360 return 0;
363 static
364 int alsa_rawmidi_stop(alsa_midi_t *m)
366 alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
367 char c = 'q';
368 if (midi->keep_walking == 0)
369 return -EALREADY;
370 midi->keep_walking = 0;
371 write(midi->in.wake_pipe[1], &c, 1);
372 write(midi->out.wake_pipe[1], &c, 1);
373 write(midi->scan.wake_pipe[1], &c, 1);
374 pthread_join(midi->in.thread, NULL);
375 pthread_join(midi->out.thread, NULL);
376 pthread_join(midi->scan.thread, NULL);
377 // ports are freed in alsa_midi_detach()
378 return 0;
381 static void jack_process(midi_stream_t *str, jack_nframes_t nframes);
383 static
384 void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes)
386 alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
387 jack_process(&midi->in, nframes);
390 static
391 void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes)
393 alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
394 jack_process(&midi->out, nframes);
398 * -----------------------------------------------------------------------------
400 static inline
401 int can_pass(size_t sz, jack_ringbuffer_t *in, jack_ringbuffer_t *out)
403 return jack_ringbuffer_read_space(in) >= sz && jack_ringbuffer_write_space(out) >= sz;
406 static
407 void midi_port_init(const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_info_t *info, const alsa_id_t *id)
409 const char *name;
410 char *c;
412 port->id = *id;
413 snprintf(port->dev, sizeof(port->dev), "hw:%d,%d,%d", id->id[0], id->id[1], id->id[3]);
414 snprintf(port->device_name, sizeof(port->device_name), snd_rawmidi_info_get_name(info));
415 name = snd_rawmidi_info_get_subdevice_name(info);
416 if (!strlen(name))
417 name = port->device_name;
418 snprintf(port->name, sizeof(port->name), "%s %s %s", port->id.id[2] ? "out":"in", port->dev, name);
420 // replace all offending characters with '-'
421 for (c=port->name; *c; ++c)
422 if (!isalnum(*c))
423 *c = '-';
425 port->state = PORT_CREATED;
428 static
429 inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *alias)
431 char name[128];
433 if (type & JackPortIsOutput)
434 snprintf(name, sizeof(name), "system_midi:capture_%d", ++midi->midi_in_cnt);
435 else
436 snprintf(name, sizeof(name), "system_midi:playback_%d", ++midi->midi_out_cnt);
438 port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE,
439 type | JackPortIsPhysical | JackPortIsTerminal, 0);
441 if (port->jack) {
442 jack_port_set_alias(port->jack, alias);
443 jack_port_set_device_metadata(port->jack, port->device_name);
446 return port->jack == NULL;
449 static
450 int midi_port_open(alsa_rawmidi_t *midi, midi_port_t *port)
452 int err;
453 int type;
454 char name[64];
455 snd_rawmidi_t **in = NULL;
456 snd_rawmidi_t **out = NULL;
458 if (port->id.id[2] == 0) {
459 in = &port->rawmidi;
460 type = JackPortIsOutput;
461 } else {
462 out = &port->rawmidi;
463 type = JackPortIsInput;
466 if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0)
467 return err;
469 /* Some devices (emu10k1) have subdevs with the same name,
470 * and we need to generate unique port name for jack */
471 snprintf(name, sizeof(name), "%s", port->name);
472 if (midi_port_open_jack(midi, port, type, name)) {
473 int num;
474 num = port->id.id[3] ? port->id.id[3] : port->id.id[1];
475 snprintf(name, sizeof(name), "%s %d", port->name, num);
476 if (midi_port_open_jack(midi, port, type, name))
477 return 2;
479 if ((port->event_ring = jack_ringbuffer_create(MAX_EVENTS*sizeof(event_head_t)))==NULL)
480 return 3;
481 if ((port->data_ring = jack_ringbuffer_create(MAX_DATA))==NULL)
482 return 4;
484 return 0;
487 static
488 void midi_port_close(const alsa_rawmidi_t *midi, midi_port_t *port)
490 if (port->data_ring) {
491 jack_ringbuffer_free(port->data_ring);
492 port->data_ring = NULL;
494 if (port->event_ring) {
495 jack_ringbuffer_free(port->event_ring);
496 port->event_ring = NULL;
498 if (port->jack) {
499 jack_port_unregister(midi->client, port->jack);
500 port->jack = NULL;
502 if (port->rawmidi) {
503 snd_rawmidi_close(port->rawmidi);
504 port->rawmidi = NULL;
509 * ------------------------- Port scanning -------------------------------
512 static
513 int alsa_id_before(const alsa_id_t *p1, const alsa_id_t *p2)
515 int i;
516 for (i=0; i<4; ++i) {
517 if (p1->id[i] < p2->id[i])
518 return 1;
519 else if (p1->id[i] > p2->id[i])
520 return 0;
522 return 0;
525 static
526 void alsa_get_id(alsa_id_t *id, snd_rawmidi_info_t *info)
528 id->id[0] = snd_rawmidi_info_get_card(info);
529 id->id[1] = snd_rawmidi_info_get_device(info);
530 id->id[2] = snd_rawmidi_info_get_stream(info) == SND_RAWMIDI_STREAM_OUTPUT ? 1 : 0;
531 id->id[3] = snd_rawmidi_info_get_subdevice(info);
534 #include <stdio.h>
536 static inline
537 void alsa_error(const char *func, int err)
539 error_log("%s() failed", snd_strerror(err));
542 typedef struct {
543 alsa_rawmidi_t *midi;
544 midi_port_t **iterator;
545 snd_ctl_t *ctl;
546 snd_rawmidi_info_t *info;
547 } scan_t;
549 static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list);
551 static
552 void scan_cleanup(alsa_rawmidi_t *midi)
554 midi_port_t **list = &midi->scan.ports;
555 while (*list)
556 list = scan_port_del(midi, list);
559 static void scan_card(scan_t *scan);
560 static midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list);
562 void scan_cycle(alsa_rawmidi_t *midi)
564 int card = -1, err;
565 scan_t scan;
566 midi_port_t **ports;
568 //debug_log("scan: cleanup");
569 scan_cleanup(midi);
571 scan.midi = midi;
572 scan.iterator = &midi->scan.ports;
573 snd_rawmidi_info_alloca(&scan.info);
575 //debug_log("scan: rescan");
576 while ((err = snd_card_next(&card))>=0 && card>=0) {
577 char name[32];
578 snprintf(name, sizeof(name), "hw:%d", card);
579 if ((err = snd_ctl_open(&scan.ctl, name, SND_CTL_NONBLOCK))>=0) {
580 scan_card(&scan);
581 snd_ctl_close(scan.ctl);
582 } else
583 alsa_error("scan: snd_ctl_open", err);
586 // delayed open to workaround alsa<1.0.14 bug (can't open more than 1 subdevice if ctl is opened).
587 ports = &midi->scan.ports;
588 while (*ports) {
589 midi_port_t *port = *ports;
590 if (port->state == PORT_CREATED)
591 ports = scan_port_open(midi, ports);
592 else
593 ports = &port->next;
597 static void scan_device(scan_t *scan);
599 static
600 void scan_card(scan_t *scan)
602 int device = -1;
603 int err;
605 while ((err = snd_ctl_rawmidi_next_device(scan->ctl, &device))>=0 && device >=0) {
606 snd_rawmidi_info_set_device(scan->info, device);
608 snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_INPUT);
609 snd_rawmidi_info_set_subdevice(scan->info, 0);
610 if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0)
611 scan_device(scan);
612 else if (err != -ENOENT)
613 alsa_error("scan: snd_ctl_rawmidi_info on device", err);
615 snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_OUTPUT);
616 snd_rawmidi_info_set_subdevice(scan->info, 0);
617 if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0)
618 scan_device(scan);
619 else if (err != -ENOENT)
620 alsa_error("scan: snd_ctl_rawmidi_info on device", err);
624 static void scan_port_update(scan_t *scan);
626 static
627 void scan_device(scan_t *scan)
629 int err;
630 int sub, nsubs = 0;
631 nsubs = snd_rawmidi_info_get_subdevices_count(scan->info);
633 for (sub=0; sub<nsubs; ++sub) {
634 snd_rawmidi_info_set_subdevice(scan->info, sub);
635 if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info)) < 0) {
636 alsa_error("scan: snd_ctl_rawmidi_info on subdevice", err);
637 continue;
640 scan_port_update(scan);
644 static midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list);
646 static
647 void scan_port_update(scan_t *scan)
649 midi_port_t **list = scan->iterator;
650 alsa_id_t id;
651 alsa_get_id(&id, scan->info);
653 while (*list && alsa_id_before(&(*list)->id, &id))
654 list = scan_port_del(scan->midi, list);
656 if (!*list || alsa_id_before(&id, &(*list)->id))
657 list = scan_port_add(scan, &id, list);
658 else if (*list)
659 list = &(*list)->next;
661 scan->iterator = list;
664 static
665 midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list)
667 midi_port_t *port;
668 midi_stream_t *str = id->id[2] ? &scan->midi->out : &scan->midi->in;
670 port = calloc(1, str->port_size);
671 if (!port)
672 return list;
673 midi_port_init(scan->midi, port, scan->info, id);
675 port->next = *list;
676 *list = port;
677 info_log("scan: added port %s %s", port->dev, port->name);
678 return &port->next;
681 static
682 midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list)
684 int ret;
685 midi_stream_t *str;
686 midi_port_t *port;
688 port = *list;
689 str = port->id.id[2] ? &midi->out : &midi->in;
691 if (jack_ringbuffer_write_space(str->jack.new_ports) < sizeof(port))
692 goto fail_0;
694 ret = midi_port_open(midi, port);
695 if (ret)
696 goto fail_1;
697 if ((str->port_init)(midi, port))
698 goto fail_2;
700 port->state = PORT_ADDED_TO_JACK;
701 jack_ringbuffer_write(str->jack.new_ports, (char*) &port, sizeof(port));
703 info_log("scan: opened port %s %s", port->dev, port->name);
704 return &port->next;
706 fail_2:
707 (str->port_close)(midi, port);
708 fail_1:
709 midi_port_close(midi, port);
710 port->state = PORT_ZOMBIFIED;
711 error_log("scan: can't open port %s %s, error code %d, zombified", port->dev, port->name, ret);
712 return &port->next;
713 fail_0:
714 error_log("scan: can't open port %s %s", port->dev, port->name);
715 return &port->next;
718 static
719 midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list)
721 midi_port_t *port = *list;
722 if (port->state == PORT_REMOVED_FROM_JACK) {
723 info_log("scan: deleted port %s %s", port->dev, port->name);
724 *list = port->next;
725 if (port->id.id[2] )
726 (midi->out.port_close)(midi, port);
727 else
728 (midi->in.port_close)(midi, port);
729 midi_port_close(midi, port);
730 free(port);
731 return list;
732 } else {
733 //debug_log("can't delete port %s, wrong state: %d", port->name, (int)port->state);
734 return &port->next;
738 void* scan_thread(void *arg)
740 alsa_rawmidi_t *midi = arg;
741 struct pollfd wakeup;
743 wakeup.fd = midi->scan.wake_pipe[0];
744 wakeup.events = POLLIN|POLLERR|POLLNVAL;
745 while (midi->keep_walking) {
746 int res;
747 //error_log("scanning....");
748 scan_cycle(midi);
749 res = poll(&wakeup, 1, 2000);
750 if (res>0) {
751 char c;
752 read(wakeup.fd, &c, 1);
753 } else if (res<0 && errno != EINTR)
754 break;
756 return NULL;
760 * ------------------------------- Input/Output ------------------------------
763 static
764 void jack_add_ports(midi_stream_t *str)
766 midi_port_t *port;
767 while (can_pass(sizeof(port), str->jack.new_ports, str->midi.new_ports) && str->jack.nports < MAX_PORTS) {
768 jack_ringbuffer_read(str->jack.new_ports, (char*)&port, sizeof(port));
769 str->jack.ports[str->jack.nports++] = port;
770 port->state = PORT_ADDED_TO_MIDI;
771 jack_ringbuffer_write(str->midi.new_ports, (char*)&port, sizeof(port));
775 static
776 void jack_process(midi_stream_t *str, jack_nframes_t nframes)
778 int r, w;
779 process_jack_t proc;
780 jack_nframes_t cur_frames;
782 if (!str->owner->keep_walking)
783 return;
785 proc.midi = str->owner;
786 proc.nframes = nframes;
787 proc.frame_time = jack_last_frame_time(proc.midi->client);
788 cur_frames = jack_frame_time(proc.midi->client);
789 int periods_diff = cur_frames - proc.frame_time;
790 if (periods_diff < proc.nframes) {
791 int periods_lost = periods_diff / proc.nframes;
792 proc.frame_time += periods_lost * proc.nframes;
793 debug_log("xrun detected: %d periods lost", periods_lost);
796 // process existing ports
797 for (r=0, w=0; r<str->jack.nports; ++r) {
798 midi_port_t *port = str->jack.ports[r];
799 proc.port = port;
801 assert (port->state > PORT_ADDED_TO_JACK && port->state < PORT_REMOVED_FROM_JACK);
803 proc.buffer = jack_port_get_buffer(port->jack, nframes);
804 if (str->mode == POLLIN)
805 jack_midi_clear_buffer(proc.buffer);
807 if (port->state == PORT_REMOVED_FROM_MIDI) {
808 port->state = PORT_REMOVED_FROM_JACK; // this signals to scan thread
809 continue; // this effectively removes port from the midi->in.jack.ports[]
812 (str->process_jack)(&proc);
814 if (r != w)
815 str->jack.ports[w] = port;
816 ++w;
818 if (str->jack.nports != w) {
819 debug_log("jack_%s: nports %d -> %d", str->name, str->jack.nports, w);
821 str->jack.nports = w;
823 jack_add_ports(str); // it makes no sense to add them earlier since they have no data yet
825 // wake midi thread
826 write(str->wake_pipe[1], &r, 1);
829 static
830 void *midi_thread(void *arg)
832 midi_stream_t *str = arg;
833 alsa_rawmidi_t *midi = str->owner;
834 struct pollfd pfds[MAX_PFDS];
835 int npfds;
836 jack_time_t wait_nsec = 1000*1000*1000; // 1 sec
837 process_midi_t proc;
839 proc.midi = midi;
840 proc.mode = str->mode;
842 pfds[0].fd = str->wake_pipe[0];
843 pfds[0].events = POLLIN|POLLERR|POLLNVAL;
844 npfds = 1;
846 if (jack_is_realtime(midi->client))
847 set_threaded_log_function();
849 //debug_log("midi_thread(%s): enter", str->name);
851 while (midi->keep_walking) {
852 int poll_timeout;
853 int wait_nanosleep;
854 int r=1, w=1; // read,write pos in pfds
855 int rp=0, wp=0; // read, write pos in ports
857 // sleep
858 //if (wait_nsec != 1000*1000*1000) {
859 // debug_log("midi_thread(%s): ", str->name);
860 // assert (wait_nsec == 1000*1000*1000);
862 poll_timeout = wait_nsec / (1000*1000);
863 wait_nanosleep = wait_nsec % (1000*1000);
864 if (wait_nanosleep > NANOSLEEP_RESOLUTION) {
865 struct timespec ts;
866 ts.tv_sec = 0;
867 ts.tv_nsec = wait_nanosleep;
868 #ifdef CLOCK_MONOTONIC_RAW
869 clock_nanosleep(CLOCK_MONOTONIC_RAW, 0, &ts, NULL);
870 #else
871 clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
872 #endif
874 int res = poll((struct pollfd*)&pfds, npfds, poll_timeout);
875 //debug_log("midi_thread(%s): poll exit: %d", str->name, res);
876 if (!midi->keep_walking)
877 break;
878 if (res < 0) {
879 if (errno == EINTR)
880 continue;
881 error_log("midi_thread(%s) poll failed: %s", str->name, strerror(errno));
882 break;
885 // check wakeup pipe
886 if (pfds[0].revents & ~POLLIN)
887 break;
888 if (pfds[0].revents & POLLIN) {
889 char c;
890 read(pfds[0].fd, &c, 1);
893 // add new ports
894 while (jack_ringbuffer_read_space(str->midi.new_ports) >= sizeof(midi_port_t*) && str->midi.nports < MAX_PORTS) {
895 midi_port_t *port;
896 jack_ringbuffer_read(str->midi.new_ports, (char*)&port, sizeof(port));
897 str->midi.ports[str->midi.nports++] = port;
898 debug_log("midi_thread(%s): added port %s", str->name, port->name);
901 // if (res == 0)
902 // continue;
904 // process ports
905 proc.cur_time = 0; //jack_frame_time(midi->client);
906 proc.next_time = NFRAMES_INF;
908 for (rp = 0; rp < str->midi.nports; ++rp) {
909 midi_port_t *port = str->midi.ports[rp];
910 proc.cur_time = jack_frame_time(midi->client);
911 proc.port = port;
912 proc.rpfds = &pfds[r];
913 proc.wpfds = &pfds[w];
914 proc.max_pfds = MAX_PFDS - w;
915 r += port->npfds;
916 if (!(str->process_midi)(&proc)) {
917 port->state = PORT_REMOVED_FROM_MIDI; // this signals to jack thread
918 continue; // this effectively removes port from array
920 w += port->npfds;
921 if (rp != wp)
922 str->midi.ports[wp] = port;
923 ++wp;
925 if (str->midi.nports != wp) {
926 debug_log("midi_%s: nports %d -> %d", str->name, str->midi.nports, wp);
928 str->midi.nports = wp;
929 if (npfds != w) {
930 debug_log("midi_%s: npfds %d -> %d", str->name, npfds, w);
932 npfds = w;
935 * Input : ports do not set proc.next_time.
936 * Output: port sets proc.next_time ONLY if it does not have queued data.
937 * So, zero timeout will not cause busy-looping.
939 if (proc.next_time < proc.cur_time) {
940 debug_log("%s: late: next_time = %d, cur_time = %d", str->name, (int)proc.next_time, (int)proc.cur_time);
941 wait_nsec = 0; // we are late
942 } else if (proc.next_time != NFRAMES_INF) {
943 jack_time_t wait_frames = proc.next_time - proc.cur_time;
944 jack_nframes_t rate = jack_get_sample_rate(midi->client);
945 wait_nsec = (wait_frames * (1000*1000*1000)) / rate;
946 debug_log("midi_%s: timeout = %d", str->name, (int)wait_frames);
947 } else
948 wait_nsec = 1000*1000*1000;
949 //debug_log("midi_thread(%s): wait_nsec = %lld", str->name, wait_nsec);
951 return NULL;
954 static
955 int midi_is_ready(process_midi_t *proc)
957 midi_port_t *port = proc->port;
958 if (port->npfds) {
959 unsigned short revents = 0;
960 int res = snd_rawmidi_poll_descriptors_revents(port->rawmidi, proc->rpfds, port->npfds, &revents);
961 if (res) {
962 error_log("snd_rawmidi_poll_descriptors_revents failed on port %s with: %s", port->name, snd_strerror(res));
963 return 0;
966 if (revents & ~proc->mode) {
967 debug_log("midi: port %s failed", port->name);
968 return 0;
970 if (revents & proc->mode) {
971 port->is_ready = 1;
972 debug_log("midi: is_ready %s", port->name);
975 return 1;
978 static
979 int midi_update_pfds(process_midi_t *proc)
981 midi_port_t *port = proc->port;
982 if (port->npfds == 0) {
983 port->npfds = snd_rawmidi_poll_descriptors_count(port->rawmidi);
984 if (port->npfds > proc->max_pfds) {
985 debug_log("midi: not enough pfds for port %s", port->name);
986 return 0;
988 snd_rawmidi_poll_descriptors(port->rawmidi, proc->wpfds, port->npfds);
989 } else if (proc->rpfds != proc->wpfds) {
990 memmove(proc->wpfds, proc->rpfds, sizeof(struct pollfd) * port->npfds);
992 return 1;
996 * ------------------------------------ Input ------------------------------
999 static
1000 int input_port_init(alsa_rawmidi_t *midi, midi_port_t *port)
1002 input_port_t *in = (input_port_t*)port;
1003 midi_unpack_init(&in->unpack);
1004 return 0;
1007 static
1008 void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port)
1012 * Jack-level input.
1015 static
1016 void do_jack_input(process_jack_t *p)
1018 input_port_t *port = (input_port_t*) p->port;
1019 event_head_t event;
1020 while (jack_ringbuffer_read_space(port->base.event_ring) >= sizeof(event)) {
1021 jack_ringbuffer_data_t vec[2];
1022 jack_nframes_t time;
1023 int i, todo;
1025 jack_ringbuffer_read(port->base.event_ring, (char*)&event, sizeof(event));
1026 // TODO: take into account possible warping
1027 if ((event.time + p->nframes) < p->frame_time)
1028 time = 0;
1029 else if (event.time >= p->frame_time)
1030 time = p->nframes -1;
1031 else
1032 time = event.time + p->nframes - p->frame_time;
1034 jack_ringbuffer_get_read_vector(port->base.data_ring, vec);
1035 assert ((vec[0].len + vec[1].len) >= event.size);
1037 if (event.overruns)
1038 midi_unpack_reset(&port->unpack);
1040 todo = event.size;
1041 for (i=0; i<2 && todo>0; ++i) {
1042 int avail = todo < vec[i].len ? todo : vec[i].len;
1043 int done = midi_unpack_buf(&port->unpack, (unsigned char*)vec[i].buf, avail, p->buffer, time);
1044 if (done != avail) {
1045 debug_log("jack_in: buffer overflow in port %s", port->base.name);
1046 break;
1048 todo -= done;
1050 jack_ringbuffer_read_advance(port->base.data_ring, event.size);
1055 * Low level input.
1057 static
1058 int do_midi_input(process_midi_t *proc)
1060 input_port_t *port = (input_port_t*) proc->port;
1061 if (!midi_is_ready(proc))
1062 return 0;
1064 if (port->base.is_ready) {
1065 jack_ringbuffer_data_t vec[2];
1066 int res;
1068 jack_ringbuffer_get_write_vector(port->base.data_ring, vec);
1069 if (jack_ringbuffer_write_space(port->base.event_ring) < sizeof(event_head_t) || vec[0].len < 1) {
1070 port->overruns++;
1071 if (port->base.npfds) {
1072 debug_log("midi_in: internal overflow on %s", port->base.name);
1074 // remove from poll to prevent busy-looping
1075 port->base.npfds = 0;
1076 return 1;
1078 res = snd_rawmidi_read(port->base.rawmidi, vec[0].buf, vec[0].len);
1079 if (res < 0 && res != -EWOULDBLOCK) {
1080 error_log("midi_in: reading from port %s failed: %s", port->base.name, snd_strerror(res));
1081 return 0;
1082 } else if (res > 0) {
1083 event_head_t event;
1084 event.time = proc->cur_time;
1085 event.size = res;
1086 event.overruns = port->overruns;
1087 port->overruns = 0;
1088 debug_log("midi_in: read %d bytes at %d", (int)event.size, (int)event.time);
1089 jack_ringbuffer_write_advance(port->base.data_ring, event.size);
1090 jack_ringbuffer_write(port->base.event_ring, (char*)&event, sizeof(event));
1092 port->base.is_ready = 0;
1095 if (!midi_update_pfds(proc))
1096 return 0;
1098 return 1;
1102 * ------------------------------------ Output ------------------------------
1105 static int output_port_init(alsa_rawmidi_t *midi, midi_port_t *port)
1107 output_port_t *out = (output_port_t*)port;
1108 midi_pack_reset(&out->packer);
1109 out->next_event.time = 0;
1110 out->next_event.size = 0;
1111 out->todo = 0;
1112 return 0;
1115 static void output_port_close(alsa_rawmidi_t *midi, midi_port_t *port)
1118 static
1119 void do_jack_output(process_jack_t *proc)
1121 output_port_t *port = (output_port_t*) proc->port;
1122 int nevents = jack_midi_get_event_count(proc->buffer);
1123 int i;
1124 if (nevents) {
1125 debug_log("jack_out: %d events in %s", nevents, port->base.name);
1127 for (i=0; i<nevents; ++i) {
1128 jack_midi_event_t event;
1129 event_head_t hdr;
1131 jack_midi_event_get(&event, proc->buffer, i);
1133 if (jack_ringbuffer_write_space(port->base.data_ring) < event.size || jack_ringbuffer_write_space(port->base.event_ring) < sizeof(hdr)) {
1134 debug_log("jack_out: output buffer overflow on %s", port->base.name);
1135 break;
1138 midi_pack_event(&port->packer, &event);
1140 jack_ringbuffer_write(port->base.data_ring, (char*)event.buffer, event.size);
1142 hdr.time = proc->frame_time + event.time + proc->nframes;
1143 hdr.size = event.size;
1144 jack_ringbuffer_write(port->base.event_ring, (char*)&hdr, sizeof(hdr));
1145 debug_log("jack_out: sent %d-byte event at %ld", (int)event.size, (long)event.time);
1149 static
1150 int do_midi_output(process_midi_t *proc)
1152 int worked = 0;
1153 output_port_t *port = (output_port_t*) proc->port;
1155 if (!midi_is_ready(proc))
1156 return 0;
1158 // eat events
1159 while (port->next_event.time <= proc->cur_time) {
1160 port->todo += port->next_event.size;
1161 if (jack_ringbuffer_read(port->base.event_ring, (char*)&port->next_event, sizeof(port->next_event))!=sizeof(port->next_event)) {
1162 port->next_event.time = 0;
1163 port->next_event.size = 0;
1164 break;
1165 } else {
1166 debug_log("midi_out: at %ld got %d bytes for %ld", (long)proc->cur_time, (int)port->next_event.size, (long)port->next_event.time);
1170 if (port->todo) {
1171 debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time);
1174 // calc next wakeup time
1175 if (!port->todo && port->next_event.time && port->next_event.time < proc->next_time) {
1176 proc->next_time = port->next_event.time;
1177 debug_log("midi_out: next_time = %ld", (long)proc->next_time);
1180 if (port->todo && port->base.is_ready) {
1181 // write data
1182 int size = port->todo;
1183 int res;
1184 jack_ringbuffer_data_t vec[2];
1186 jack_ringbuffer_get_read_vector(port->base.data_ring, vec);
1187 if (size > vec[0].len) {
1188 size = vec[0].len;
1189 assert (size > 0);
1191 res = snd_rawmidi_write(port->base.rawmidi, vec[0].buf, size);
1192 if (res > 0) {
1193 jack_ringbuffer_read_advance(port->base.data_ring, res);
1194 debug_log("midi_out: written %d bytes to %s", res, port->base.name);
1195 port->todo -= res;
1196 worked = 1;
1197 } else if (res == -EWOULDBLOCK) {
1198 port->base.is_ready = 0;
1199 debug_log("midi_out: -EWOULDBLOCK on %s", port->base.name);
1200 return 1;
1201 } else {
1202 error_log("midi_out: writing to port %s failed: %s", port->base.name, snd_strerror(res));
1203 return 0;
1205 snd_rawmidi_drain(port->base.rawmidi);
1208 // update pfds for this port
1209 if (!midi_update_pfds(proc))
1210 return 0;
1212 if (!port->todo) {
1213 int i;
1214 if (worked) {
1215 debug_log("midi_out: relaxing on %s", port->base.name);
1217 for (i=0; i<port->base.npfds; ++i)
1218 proc->wpfds[i].events &= ~POLLOUT;
1219 } else {
1220 int i;
1221 for (i=0; i<port->base.npfds; ++i)
1222 proc->wpfds[i].events |= POLLOUT;
1224 return 1;