1 /*
2  * ALSA RAWMIDI < - > JACK MIDI bridge
3  *
4  * Copyright (c) 2006,2007 Dmitry S. Baikov
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 /* Required for clock_nanosleep(). Thanks, Nedko */
22 #define _GNU_SOURCE
23 
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>
32 
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"
39 
40 extern int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem);
41 
42 enum {
43 	NANOSLEEP_RESOLUTION = 7000
44 };
45 
46 #define NFRAMES_INF ULLONG_MAX
47 
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
62 };
63 
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,
72 };
73 
74 typedef struct {
75 	int id[4]; //card, dev, dir, sub;
76 } alsa_id_t;
77 
78 typedef struct {
79 	jack_time_t time;
80 	int size;
81 	int overruns;
82 } event_head_t;
83 
84 typedef struct midi_port_t midi_port_t;
85 struct midi_port_t {
86 	midi_port_t *next;
87 
88 	enum PortState state;
89 
90 	alsa_id_t id;
91 	char dev[16];
92 	char name[64];
93 	char device_name[64];
94 
95 	jack_port_t *jack;
96 	snd_rawmidi_t *rawmidi;
97 	int npfds;
98 	int is_ready;
99 
100 	jack_ringbuffer_t *event_ring;
101 	jack_ringbuffer_t *data_ring;
102 
103 };
104 
105 typedef struct input_port_t {
106 	midi_port_t base;
107 
108 	// jack
109 	midi_unpack_t unpack;
110 
111 	// midi
112 	int overruns;
113 } input_port_t;
114 
115 typedef struct output_port_t {
116 	midi_port_t base;
117 
118 	// jack
119 	midi_pack_t packer;
120 
121 	// midi
122 	event_head_t next_event;
123 	int todo;
124 } output_port_t;
125 
126 typedef struct alsa_rawmidi_t alsa_rawmidi_t;
127 
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;
135 
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;
147 
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];
154 
155 	struct {
156 		jack_ringbuffer_t *new_ports;
157 		int nports;
158 		midi_port_t *ports[MAX_PORTS];
159 	} jack, midi;
160 
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;
167 
168 
169 struct alsa_rawmidi_t {
170 	alsa_midi_t ops;
171 
172 	jack_client_t *client;
173 	int keep_walking;
174 
175 	struct {
176 		pthread_t thread;
177 		midi_port_t *ports;
178 		int wake_pipe[2];
179 	} scan;
180 
181 	midi_stream_t in;
182 	midi_stream_t out;
183 	int midi_in_cnt;
184 	int midi_out_cnt;
185 };
186 
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);
189 
190 static void do_jack_input(process_jack_t *j);
191 static int do_midi_input(process_midi_t *m);
192 
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);
195 
196 static void do_jack_output(process_jack_t *j);
197 static int do_midi_output(process_midi_t *m);
198 
199 static
stream_init(midi_stream_t * s,alsa_rawmidi_t * midi,const char * name)200 int stream_init(midi_stream_t *s, alsa_rawmidi_t *midi, const char *name)
201 {
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;
208 	}
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;
214 }
215 
216 static
stream_close(midi_stream_t * s)217 void stream_close(midi_stream_t *s)
218 {
219 	if (s->wake_pipe[0] != -1) {
220 		close(s->wake_pipe[0]);
221 		close(s->wake_pipe[1]);
222 	}
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);
227 }
228 
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);
236 
alsa_rawmidi_new(jack_client_t * jack)237 alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack)
238 {
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;
246 	}
247 
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;
256 
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;
265 
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;
275 
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;
287 }
288 
289 static
290 midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list);
291 
292 static
alsa_rawmidi_delete(alsa_midi_t * m)293 void alsa_rawmidi_delete(alsa_midi_t *m)
294 {
295 	alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
296 
297 	alsa_rawmidi_detach(m);
298 
299 	stream_close(&midi->out);
300 	stream_close(&midi->in);
301 	close(midi->scan.wake_pipe[0]);
302 	close(midi->scan.wake_pipe[1]);
303 
304 	free(midi);
305 }
306 
307 static void* scan_thread(void *);
308 static void *midi_thread(void *arg);
309 
310 static
alsa_rawmidi_attach(alsa_midi_t * m)311 int alsa_rawmidi_attach(alsa_midi_t *m)
312 {
313 	return 0;
314 }
315 
316 static
alsa_rawmidi_detach(alsa_midi_t * m)317 int alsa_rawmidi_detach(alsa_midi_t *m)
318 {
319 	alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
320 	midi_port_t **list;
321 
322 	alsa_rawmidi_stop(m);
323 
324 	list = &midi->scan.ports;
325 	while (*list) {
326 		(*list)->state = PORT_REMOVED_FROM_JACK;
327 		list = scan_port_del(midi, list);
328 	}
329 	return 0;
330 }
331 
332 static
alsa_rawmidi_start(alsa_midi_t * m)333 int alsa_rawmidi_start(alsa_midi_t *m)
334 {
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;
340 
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;
345 	}
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;
351 	}
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;
359 	}
360 	return 0;
361 }
362 
363 static
alsa_rawmidi_stop(alsa_midi_t * m)364 int alsa_rawmidi_stop(alsa_midi_t *m)
365 {
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;
379 }
380 
381 static void jack_process(midi_stream_t *str, jack_nframes_t nframes);
382 
383 static
alsa_rawmidi_read(alsa_midi_t * m,jack_nframes_t nframes)384 void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes)
385 {
386 	alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
387 	jack_process(&midi->in, nframes);
388 }
389 
390 static
alsa_rawmidi_write(alsa_midi_t * m,jack_nframes_t nframes)391 void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes)
392 {
393 	alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m;
394 	jack_process(&midi->out, nframes);
395 }
396 
397 /*
398  * -----------------------------------------------------------------------------
399  */
400 static inline
can_pass(size_t sz,jack_ringbuffer_t * in,jack_ringbuffer_t * out)401 int can_pass(size_t sz, jack_ringbuffer_t *in, jack_ringbuffer_t *out)
402 {
403 	return jack_ringbuffer_read_space(in) >= sz && jack_ringbuffer_write_space(out) >= sz;
404 }
405 
406 static
midi_port_init(const alsa_rawmidi_t * midi,midi_port_t * port,snd_rawmidi_info_t * info,const alsa_id_t * id)407 void midi_port_init(const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_info_t *info, const alsa_id_t *id)
408 {
409 	const char *name;
410 	char *c;
411 
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 	strncpy(port->device_name, snd_rawmidi_info_get_name(info), sizeof(port->device_name));
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);
419 
420 	// replace all offending characters with '-'
421 	for (c=port->name; *c; ++c)
422 	        if (!isalnum(*c))
423 			*c = '-';
424 
425 	port->state = PORT_CREATED;
426 }
427 
428 static
midi_port_open_jack(alsa_rawmidi_t * midi,midi_port_t * port,int type,const char * alias)429 inline int midi_port_open_jack(alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *alias)
430 {
431 	char name[128];
432 
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);
437 
438 	port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE,
439 		type | JackPortIsPhysical | JackPortIsTerminal, 0);
440 
441 	if (port->jack) {
442 		jack_port_set_alias(port->jack, alias);
443 		jack_port_set_default_metadata(port->jack, port->device_name);
444 	}
445 
446 	return port->jack == NULL;
447 }
448 
449 static
midi_port_open(alsa_rawmidi_t * midi,midi_port_t * port)450 int midi_port_open(alsa_rawmidi_t *midi, midi_port_t *port)
451 {
452 	int err;
453 	int type;
454 	char name[64];
455 	snd_rawmidi_t **in = NULL;
456 	snd_rawmidi_t **out = NULL;
457 
458 	if (port->id.id[2] == 0) {
459 		in = &port->rawmidi;
460 		type = JackPortIsOutput;
461 	} else {
462 		out = &port->rawmidi;
463 		type = JackPortIsInput;
464 	}
465 
466 	if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0)
467 		return err;
468 
469 	/* Some devices (emu10k1) have subdevs with the same name,
470 	 * and we need to generate unique port name for jack */
471 	strncpy(name, port->name, sizeof(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;
478 	}
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;
483 
484 	return 0;
485 }
486 
487 static
midi_port_close(const alsa_rawmidi_t * midi,midi_port_t * port)488 void midi_port_close(const alsa_rawmidi_t *midi, midi_port_t *port)
489 {
490 	if (port->data_ring) {
491 		jack_ringbuffer_free(port->data_ring);
492 		port->data_ring = NULL;
493 	}
494 	if (port->event_ring) {
495 		jack_ringbuffer_free(port->event_ring);
496 		port->event_ring = NULL;
497 	}
498 	if (port->jack) {
499 		jack_port_unregister(midi->client, port->jack);
500 		port->jack = NULL;
501 	}
502 	if (port->rawmidi) {
503 		snd_rawmidi_close(port->rawmidi);
504 		port->rawmidi = NULL;
505 	}
506 }
507 
508 /*
509  * ------------------------- Port scanning -------------------------------
510  */
511 
512 static
alsa_id_before(const alsa_id_t * p1,const alsa_id_t * p2)513 int alsa_id_before(const alsa_id_t *p1, const alsa_id_t *p2)
514 {
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;
521 	}
522 	return 0;
523 }
524 
525 static
alsa_get_id(alsa_id_t * id,snd_rawmidi_info_t * info)526 void alsa_get_id(alsa_id_t *id, snd_rawmidi_info_t *info)
527 {
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);
532 }
533 
534 #include <stdio.h>
535 
536 static inline
alsa_error(const char * func,int err)537 void alsa_error(const char *func, int err)
538 {
539 	error_log("%s() failed", snd_strerror(err));
540 }
541 
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;
548 
549 static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list);
550 
551 static
scan_cleanup(alsa_rawmidi_t * midi)552 void scan_cleanup(alsa_rawmidi_t *midi)
553 {
554 	midi_port_t **list = &midi->scan.ports;
555 	while (*list)
556 		list = scan_port_del(midi, list);
557 }
558 
559 static void scan_card(scan_t *scan);
560 static midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list);
561 
scan_cycle(alsa_rawmidi_t * midi)562 void scan_cycle(alsa_rawmidi_t *midi)
563 {
564 	int card = -1, err;
565 	scan_t scan;
566 	midi_port_t **ports;
567 
568 	//debug_log("scan: cleanup");
569 	scan_cleanup(midi);
570 
571 	scan.midi = midi;
572 	scan.iterator = &midi->scan.ports;
573 	snd_rawmidi_info_alloca(&scan.info);
574 
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);
584 	}
585 
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;
594 	}
595 }
596 
597 static void scan_device(scan_t *scan);
598 
599 static
scan_card(scan_t * scan)600 void scan_card(scan_t *scan)
601 {
602 	int device = -1;
603 	int err;
604 
605 	while ((err = snd_ctl_rawmidi_next_device(scan->ctl, &device))>=0 && device >=0) {
606 		snd_rawmidi_info_set_device(scan->info, device);
607 
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);
614 
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);
621 	}
622 }
623 
624 static void scan_port_update(scan_t *scan);
625 
626 static
scan_device(scan_t * scan)627 void scan_device(scan_t *scan)
628 {
629 	int err;
630 	int sub, nsubs = 0;
631 	nsubs = snd_rawmidi_info_get_subdevices_count(scan->info);
632 
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;
638 		}
639 
640 		scan_port_update(scan);
641 	}
642 }
643 
644 static midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list);
645 
646 static
scan_port_update(scan_t * scan)647 void scan_port_update(scan_t *scan)
648 {
649 	midi_port_t **list = scan->iterator;
650 	alsa_id_t id;
651 	alsa_get_id(&id, scan->info);
652 
653 	while (*list && alsa_id_before(&(*list)->id, &id))
654 		list = scan_port_del(scan->midi, list);
655 
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;
660 
661 	scan->iterator = list;
662 }
663 
664 static
scan_port_add(scan_t * scan,const alsa_id_t * id,midi_port_t ** list)665 midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list)
666 {
667 	midi_port_t *port;
668 	midi_stream_t *str = id->id[2] ? &scan->midi->out : &scan->midi->in;
669 
670 	port = calloc(1, str->port_size);
671 	if (!port)
672 		return list;
673 	midi_port_init(scan->midi, port, scan->info, id);
674 
675 	port->next = *list;
676 	*list = port;
677 	info_log("scan: added port %s %s", port->dev, port->name);
678 	return &port->next;
679 }
680 
681 static
scan_port_open(alsa_rawmidi_t * midi,midi_port_t ** list)682 midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list)
683 {
684 	int ret;
685 	midi_stream_t *str;
686 	midi_port_t *port;
687 
688 	port = *list;
689 	str = port->id.id[2] ? &midi->out : &midi->in;
690 
691 	if (jack_ringbuffer_write_space(str->jack.new_ports) < sizeof(port))
692 		goto fail_0;
693 
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;
699 
700 	port->state = PORT_ADDED_TO_JACK;
701 	jack_ringbuffer_write(str->jack.new_ports, (char*) &port, sizeof(port));
702 
703 	info_log("scan: opened port %s %s", port->dev, port->name);
704 	return &port->next;
705 
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;
716 }
717 
718 static
scan_port_del(alsa_rawmidi_t * midi,midi_port_t ** list)719 midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list)
720 {
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;
735 	}
736 }
737 
scan_thread(void * arg)738 void* scan_thread(void *arg)
739 {
740 	alsa_rawmidi_t *midi = arg;
741 	struct pollfd wakeup;
742 
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;
755 	}
756 	return NULL;
757 }
758 
759 /*
760  * ------------------------------- Input/Output  ------------------------------
761  */
762 
763 static
jack_add_ports(midi_stream_t * str)764 void jack_add_ports(midi_stream_t *str)
765 {
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));
772 	}
773 }
774 
775 static
jack_process(midi_stream_t * str,jack_nframes_t nframes)776 void jack_process(midi_stream_t *str, jack_nframes_t nframes)
777 {
778 	int r, w;
779 	process_jack_t proc;
780 	jack_nframes_t cur_frames;
781 
782 	if (!str->owner->keep_walking)
783 		return;
784 
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);
794 	}
795 
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;
800 
801 		assert (port->state > PORT_ADDED_TO_JACK && port->state < PORT_REMOVED_FROM_JACK);
802 
803 		proc.buffer = jack_port_get_buffer(port->jack, nframes);
804 		if (str->mode == POLLIN)
805 			jack_midi_clear_buffer(proc.buffer);
806 
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[]
810 		}
811 
812 		(str->process_jack)(&proc);
813 
814 		if (r != w)
815 			str->jack.ports[w] = port;
816 		++w;
817 	}
818 	if (str->jack.nports != w) {
819 		debug_log("jack_%s: nports %d -> %d", str->name, str->jack.nports, w);
820 	}
821 	str->jack.nports = w;
822 
823 	jack_add_ports(str); // it makes no sense to add them earlier since they have no data yet
824 
825 	// wake midi thread
826 	write(str->wake_pipe[1], &r, 1);
827 }
828 
829 static
midi_thread(void * arg)830 void *midi_thread(void *arg)
831 {
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;
838 
839 	proc.midi = midi;
840 	proc.mode = str->mode;
841 
842 	pfds[0].fd = str->wake_pipe[0];
843 	pfds[0].events = POLLIN|POLLERR|POLLNVAL;
844 	npfds = 1;
845 
846  	if (jack_is_realtime(midi->client))
847 	    set_threaded_log_function();
848 
849 	//debug_log("midi_thread(%s): enter", str->name);
850 
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
856 
857 		// sleep
858 		//if (wait_nsec != 1000*1000*1000) {
859 		//	debug_log("midi_thread(%s): ", str->name);
860 		//	assert (wait_nsec == 1000*1000*1000);
861 		//}
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
873 		}
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;
883 		}
884 
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);
891 		}
892 
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);
899 		}
900 
901 //		if (res == 0)
902 //			continue;
903 
904 		// process ports
905 		proc.cur_time = 0; //jack_frame_time(midi->client);
906 		proc.next_time = NFRAMES_INF;
907 
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
919 			}
920 			w += port->npfds;
921 			if (rp != wp)
922 				str->midi.ports[wp] = port;
923 			++wp;
924 		}
925 		if (str->midi.nports != wp) {
926 			debug_log("midi_%s: nports %d -> %d", str->name, str->midi.nports, wp);
927 		}
928 		str->midi.nports = wp;
929 		if (npfds != w) {
930 			debug_log("midi_%s: npfds %d -> %d", str->name, npfds, w);
931 		}
932 		npfds = w;
933 
934 		/*
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.
938 		 */
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);
950 	}
951 	return NULL;
952 }
953 
954 static
midi_is_ready(process_midi_t * proc)955 int midi_is_ready(process_midi_t *proc)
956 {
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;
964 		}
965 
966 		if (revents & ~proc->mode) {
967 			debug_log("midi: port %s failed", port->name);
968 			return 0;
969 		}
970 		if (revents & proc->mode) {
971 			port->is_ready = 1;
972 			debug_log("midi: is_ready %s", port->name);
973 		}
974 	}
975 	return 1;
976 }
977 
978 static
midi_update_pfds(process_midi_t * proc)979 int midi_update_pfds(process_midi_t *proc)
980 {
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;
987 		}
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);
991 	}
992 	return 1;
993 }
994 
995 /*
996  * ------------------------------------ Input ------------------------------
997  */
998 
999 static
input_port_init(alsa_rawmidi_t * midi,midi_port_t * port)1000 int input_port_init(alsa_rawmidi_t *midi, midi_port_t *port)
1001 {
1002 	input_port_t *in = (input_port_t*)port;
1003 	midi_unpack_init(&in->unpack);
1004 	return 0;
1005 }
1006 
1007 static
input_port_close(alsa_rawmidi_t * midi,midi_port_t * port)1008 void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port)
1009 {}
1010 
1011 /*
1012  * Jack-level input.
1013  */
1014 
1015 static
do_jack_input(process_jack_t * p)1016 void do_jack_input(process_jack_t *p)
1017 {
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;
1024 
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;
1033 
1034 		jack_ringbuffer_get_read_vector(port->base.data_ring, vec);
1035 		assert ((vec[0].len + vec[1].len) >= event.size);
1036 
1037 		if (event.overruns)
1038 			midi_unpack_reset(&port->unpack);
1039 
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;
1047 			}
1048 			todo -= done;
1049 		}
1050 		jack_ringbuffer_read_advance(port->base.data_ring, event.size);
1051 	}
1052 }
1053 
1054 /*
1055  * Low level input.
1056  */
1057 static
do_midi_input(process_midi_t * proc)1058 int do_midi_input(process_midi_t *proc)
1059 {
1060 	input_port_t *port = (input_port_t*) proc->port;
1061 	if (!midi_is_ready(proc))
1062 		return 0;
1063 
1064 	if (port->base.is_ready) {
1065 		jack_ringbuffer_data_t vec[2];
1066 		int res;
1067 
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);
1073 			}
1074 			// remove from poll to prevent busy-looping
1075 			port->base.npfds = 0;
1076 			return 1;
1077 		}
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));
1091 		}
1092 		port->base.is_ready = 0;
1093 	}
1094 
1095 	if (!midi_update_pfds(proc))
1096 		return 0;
1097 
1098 	return 1;
1099 }
1100 
1101 /*
1102  * ------------------------------------ Output ------------------------------
1103  */
1104 
output_port_init(alsa_rawmidi_t * midi,midi_port_t * port)1105 static int output_port_init(alsa_rawmidi_t *midi, midi_port_t *port)
1106 {
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;
1113 }
1114 
output_port_close(alsa_rawmidi_t * midi,midi_port_t * port)1115 static void output_port_close(alsa_rawmidi_t *midi, midi_port_t *port)
1116 {}
1117 
1118 static
do_jack_output(process_jack_t * proc)1119 void do_jack_output(process_jack_t *proc)
1120 {
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);
1126 	}
1127 	for (i=0; i<nevents; ++i) {
1128 		jack_midi_event_t event;
1129 		event_head_t hdr;
1130 
1131 		jack_midi_event_get(&event, proc->buffer, i);
1132 
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;
1136 		}
1137 
1138 		midi_pack_event(&port->packer, &event);
1139 
1140 		jack_ringbuffer_write(port->base.data_ring, (char*)event.buffer, event.size);
1141 
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);
1146 	}
1147 }
1148 
1149 static
do_midi_output(process_midi_t * proc)1150 int do_midi_output(process_midi_t *proc)
1151 {
1152 	int worked = 0;
1153 	output_port_t *port = (output_port_t*) proc->port;
1154 
1155 	if (!midi_is_ready(proc))
1156 		return 0;
1157 
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);
1167 		}
1168 	}
1169 
1170 	if (port->todo) {
1171 		debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time);
1172 	}
1173 
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);
1178 	}
1179 
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];
1185 
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);
1190 		}
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;
1204 		}
1205 		snd_rawmidi_drain(port->base.rawmidi);
1206 	}
1207 
1208 	// update pfds for this port
1209 	if (!midi_update_pfds(proc))
1210 		return 0;
1211 
1212 	if (!port->todo) {
1213 		int i;
1214 		if (worked) {
1215 			debug_log("midi_out: relaxing on %s", port->base.name);
1216 		}
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;
1223 	}
1224 	return 1;
1225 }
1226