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 */
31 #include <alsa/asoundlib.h>
33 #include "ringbuffer.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
);
43 NANOSLEEP_RESOLUTION
= 7000
46 #define NFRAMES_INF ULLONG_MAX
49 #ifndef JACK_MIDI_DEBUG
51 MAX_PORTS
= MAX_PFDS
-1,
57 MAX_PORTS
= MAX_PFDS
-1,
69 PORT_REMOVED_FROM_MIDI
,
70 PORT_REMOVED_FROM_JACK
,
75 int id
[4]; //card, dev, dir, sub;
84 typedef struct midi_port_t midi_port_t
;
96 snd_rawmidi_t
*rawmidi
;
100 jack_ringbuffer_t
*event_ring
;
101 jack_ringbuffer_t
*data_ring
;
105 typedef struct input_port_t
{
109 midi_unpack_t unpack
;
115 typedef struct output_port_t
{
122 event_head_t next_event
;
126 typedef struct alsa_rawmidi_t alsa_rawmidi_t
;
129 alsa_rawmidi_t
*midi
;
132 jack_time_t frame_time
;
133 jack_nframes_t nframes
;
137 alsa_rawmidi_t
*midi
;
140 struct pollfd
*rpfds
;
141 struct pollfd
*wpfds
;
143 jack_nframes_t cur_frames
;
144 jack_time_t cur_time
;
145 jack_time_t next_time
;
148 typedef struct midi_stream_t
{
149 alsa_rawmidi_t
*owner
;
156 jack_ringbuffer_t
*new_ports
;
158 midi_port_t
*ports
[MAX_PORTS
];
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
);
169 struct alsa_rawmidi_t
{
172 jack_client_t
*client
;
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
);
200 int stream_init(midi_stream_t
*s
, alsa_rawmidi_t
*midi
, const char *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
));
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
)
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
));
243 if (pipe(midi
->scan
.wake_pipe
)==-1) {
244 error_log("pipe() in alsa_midi_new failed: %s", strerror(errno
));
248 if (stream_init(&midi
->in
, midi
, "in"))
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"))
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;
278 stream_close(&midi
->out
);
280 stream_close(&midi
->in
);
281 close(midi
->scan
.wake_pipe
[1]);
282 close(midi
->scan
.wake_pipe
[0]);
290 midi_port_t
** scan_port_del(alsa_rawmidi_t
*midi
, midi_port_t
**list
);
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]);
307 static void* scan_thread(void *);
308 static void *midi_thread(void *arg
);
311 int alsa_rawmidi_attach(alsa_midi_t
*m
)
317 int alsa_rawmidi_detach(alsa_midi_t
*m
)
319 alsa_rawmidi_t
*midi
= (alsa_rawmidi_t
*)m
;
322 alsa_rawmidi_stop(m
);
324 list
= &midi
->scan
.ports
;
326 (*list
)->state
= PORT_REMOVED_FROM_JACK
;
327 list
= scan_port_del(midi
, list
);
333 int alsa_rawmidi_start(alsa_midi_t
*m
)
335 alsa_rawmidi_t
*midi
= (alsa_rawmidi_t
*)m
;
338 if (midi
->keep_walking
== 1)
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;
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
);
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
);
364 int alsa_rawmidi_stop(alsa_midi_t
*m
)
366 alsa_rawmidi_t
*midi
= (alsa_rawmidi_t
*)m
;
368 if (midi
->keep_walking
== 0)
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()
381 static void jack_process(midi_stream_t
*str
, jack_nframes_t nframes
);
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
);
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 * -----------------------------------------------------------------------------
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
;
407 void midi_port_init(const alsa_rawmidi_t
*midi
, midi_port_t
*port
, snd_rawmidi_info_t
*info
, const alsa_id_t
*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
);
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
)
425 port
->state
= PORT_CREATED
;
429 inline int midi_port_open_jack(alsa_rawmidi_t
*midi
, midi_port_t
*port
, int type
, const char *alias
)
433 if (type
& JackPortIsOutput
)
434 snprintf(name
, sizeof(name
), "system:midi_capture_%d", ++midi
->midi_in_cnt
);
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);
442 jack_port_set_alias(port
->jack
, alias
);
443 jack_port_set_device_metadata(port
->jack
, port
->device_name
);
446 return port
->jack
== NULL
;
450 int midi_port_open(alsa_rawmidi_t
*midi
, midi_port_t
*port
)
455 snd_rawmidi_t
**in
= NULL
;
456 snd_rawmidi_t
**out
= NULL
;
458 if (port
->id
.id
[2] == 0) {
460 type
= JackPortIsOutput
;
462 out
= &port
->rawmidi
;
463 type
= JackPortIsInput
;
466 if ((err
= snd_rawmidi_open(in
, out
, port
->dev
, SND_RAWMIDI_NONBLOCK
))<0)
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
)) {
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
))
479 if ((port
->event_ring
= jack_ringbuffer_create(MAX_EVENTS
*sizeof(event_head_t
)))==NULL
)
481 if ((port
->data_ring
= jack_ringbuffer_create(MAX_DATA
))==NULL
)
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
;
499 jack_port_unregister(midi
->client
, port
->jack
);
503 snd_rawmidi_close(port
->rawmidi
);
504 port
->rawmidi
= NULL
;
509 * ------------------------- Port scanning -------------------------------
513 int alsa_id_before(const alsa_id_t
*p1
, const alsa_id_t
*p2
)
516 for (i
=0; i
<4; ++i
) {
517 if (p1
->id
[i
] < p2
->id
[i
])
519 else if (p1
->id
[i
] > p2
->id
[i
])
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
);
537 void alsa_error(const char *func
, int err
)
539 error_log("%s() failed", snd_strerror(err
));
543 alsa_rawmidi_t
*midi
;
544 midi_port_t
**iterator
;
546 snd_rawmidi_info_t
*info
;
549 static midi_port_t
** scan_port_del(alsa_rawmidi_t
*midi
, midi_port_t
**list
);
552 void scan_cleanup(alsa_rawmidi_t
*midi
)
554 midi_port_t
**list
= &midi
->scan
.ports
;
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
)
568 //debug_log("scan: cleanup");
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) {
578 snprintf(name
, sizeof(name
), "hw:%d", card
);
579 if ((err
= snd_ctl_open(&scan
.ctl
, name
, SND_CTL_NONBLOCK
))>=0) {
581 snd_ctl_close(scan
.ctl
);
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
;
589 midi_port_t
*port
= *ports
;
590 if (port
->state
== PORT_CREATED
)
591 ports
= scan_port_open(midi
, ports
);
597 static void scan_device(scan_t
*scan
);
600 void scan_card(scan_t
*scan
)
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)
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)
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
);
627 void scan_device(scan_t
*scan
)
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
);
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
);
647 void scan_port_update(scan_t
*scan
)
649 midi_port_t
**list
= scan
->iterator
;
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
);
659 list
= &(*list
)->next
;
661 scan
->iterator
= list
;
665 midi_port_t
** scan_port_add(scan_t
*scan
, const alsa_id_t
*id
, midi_port_t
**list
)
668 midi_stream_t
*str
= id
->id
[2] ? &scan
->midi
->out
: &scan
->midi
->in
;
670 port
= calloc(1, str
->port_size
);
673 midi_port_init(scan
->midi
, port
, scan
->info
, id
);
677 info_log("scan: added port %s %s", port
->dev
, port
->name
);
682 midi_port_t
** scan_port_open(alsa_rawmidi_t
*midi
, midi_port_t
**list
)
689 str
= port
->id
.id
[2] ? &midi
->out
: &midi
->in
;
691 if (jack_ringbuffer_write_space(str
->jack
.new_ports
) < sizeof(port
))
694 ret
= midi_port_open(midi
, port
);
697 if ((str
->port_init
)(midi
, port
))
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
);
707 (str
->port_close
)(midi
, port
);
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
);
714 error_log("scan: can't open port %s %s", port
->dev
, port
->name
);
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
);
726 (midi
->out
.port_close
)(midi
, port
);
728 (midi
->in
.port_close
)(midi
, port
);
729 midi_port_close(midi
, port
);
733 //debug_log("can't delete port %s, wrong state: %d", port->name, (int)port->state);
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
) {
747 //error_log("scanning....");
749 res
= poll(&wakeup
, 1, 2000);
752 read(wakeup
.fd
, &c
, 1);
753 } else if (res
<0 && errno
!= EINTR
)
760 * ------------------------------- Input/Output ------------------------------
764 void jack_add_ports(midi_stream_t
*str
)
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
));
776 void jack_process(midi_stream_t
*str
, jack_nframes_t nframes
)
780 jack_nframes_t cur_frames
;
782 if (!str
->owner
->keep_walking
)
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
];
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
);
815 str
->jack
.ports
[w
] = port
;
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
826 write(str
->wake_pipe
[1], &r
, 1);
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
];
836 jack_time_t wait_nsec
= 1000*1000*1000; // 1 sec
840 proc
.mode
= str
->mode
;
842 pfds
[0].fd
= str
->wake_pipe
[0];
843 pfds
[0].events
= POLLIN
|POLLERR
|POLLNVAL
;
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
) {
854 int r
=1, w
=1; // read,write pos in pfds
855 int rp
=0, wp
=0; // read, write pos in ports
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
) {
867 ts
.tv_nsec
= wait_nanosleep
;
868 #ifdef CLOCK_MONOTONIC_RAW
869 clock_nanosleep(CLOCK_MONOTONIC_RAW
, 0, &ts
, NULL
);
871 clock_nanosleep(CLOCK_MONOTONIC
, 0, &ts
, NULL
);
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
)
881 error_log("midi_thread(%s) poll failed: %s", str
->name
, strerror(errno
));
886 if (pfds
[0].revents
& ~POLLIN
)
888 if (pfds
[0].revents
& POLLIN
) {
890 read(pfds
[0].fd
, &c
, 1);
894 while (jack_ringbuffer_read_space(str
->midi
.new_ports
) >= sizeof(midi_port_t
*) && str
->midi
.nports
< MAX_PORTS
) {
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
);
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
);
912 proc
.rpfds
= &pfds
[r
];
913 proc
.wpfds
= &pfds
[w
];
914 proc
.max_pfds
= MAX_PFDS
- w
;
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
922 str
->midi
.ports
[wp
] = port
;
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
;
930 debug_log("midi_%s: npfds %d -> %d", str
->name
, 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
);
948 wait_nsec
= 1000*1000*1000;
949 //debug_log("midi_thread(%s): wait_nsec = %lld", str->name, wait_nsec);
955 int midi_is_ready(process_midi_t
*proc
)
957 midi_port_t
*port
= proc
->port
;
959 unsigned short revents
= 0;
960 int res
= snd_rawmidi_poll_descriptors_revents(port
->rawmidi
, proc
->rpfds
, port
->npfds
, &revents
);
962 error_log("snd_rawmidi_poll_descriptors_revents failed on port %s with: %s", port
->name
, snd_strerror(res
));
966 if (revents
& ~proc
->mode
) {
967 debug_log("midi: port %s failed", port
->name
);
970 if (revents
& proc
->mode
) {
972 debug_log("midi: is_ready %s", port
->name
);
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
);
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
);
996 * ------------------------------------ Input ------------------------------
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
);
1008 void input_port_close(alsa_rawmidi_t
*midi
, midi_port_t
*port
)
1016 void do_jack_input(process_jack_t
*p
)
1018 input_port_t
*port
= (input_port_t
*) p
->port
;
1020 while (jack_ringbuffer_read_space(port
->base
.event_ring
) >= sizeof(event
)) {
1021 jack_ringbuffer_data_t vec
[2];
1022 jack_nframes_t time
;
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
)
1029 else if (event
.time
>= p
->frame_time
)
1030 time
= p
->nframes
-1;
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
);
1038 midi_unpack_reset(&port
->unpack
);
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
);
1050 jack_ringbuffer_read_advance(port
->base
.data_ring
, event
.size
);
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
))
1064 if (port
->base
.is_ready
) {
1065 jack_ringbuffer_data_t vec
[2];
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) {
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;
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
));
1082 } else if (res
> 0) {
1084 event
.time
= proc
->cur_time
;
1086 event
.overruns
= port
->overruns
;
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
))
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;
1115 static void output_port_close(alsa_rawmidi_t
*midi
, midi_port_t
*port
)
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
);
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
;
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
);
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
);
1150 int do_midi_output(process_midi_t
*proc
)
1153 output_port_t
*port
= (output_port_t
*) proc
->port
;
1155 if (!midi_is_ready(proc
))
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;
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
);
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
) {
1182 int size
= port
->todo
;
1184 jack_ringbuffer_data_t vec
[2];
1186 jack_ringbuffer_get_read_vector(port
->base
.data_ring
, vec
);
1187 if (size
> vec
[0].len
) {
1191 res
= snd_rawmidi_write(port
->base
.rawmidi
, vec
[0].buf
, size
);
1193 jack_ringbuffer_read_advance(port
->base
.data_ring
, res
);
1194 debug_log("midi_out: written %d bytes to %s", res
, port
->base
.name
);
1197 } else if (res
== -EWOULDBLOCK
) {
1198 port
->base
.is_ready
= 0;
1199 debug_log("midi_out: -EWOULDBLOCK on %s", port
->base
.name
);
1202 error_log("midi_out: writing to port %s failed: %s", port
->base
.name
, snd_strerror(res
));
1205 snd_rawmidi_drain(port
->base
.rawmidi
);
1208 // update pfds for this port
1209 if (!midi_update_pfds(proc
))
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
;
1221 for (i
=0; i
<port
->base
.npfds
; ++i
)
1222 proc
->wpfds
[i
].events
|= POLLOUT
;