1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * ALSA SEQ < - > JACK MIDI bridge
5 * Copyright (c) 2006,2007 Dmitry S. Baikov <c0ff@konstruktiv.org>
6 * Copyright (c) 2007,2008 Nedko Arnaudov <nedko@arnaudov.name>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <alsa/asoundlib.h>
25 #include <jack/jack.h>
26 #include <jack/midiport.h>
27 #include <jack/ringbuffer.h>
34 #include "port_hash.h"
38 static bool g_freewheeling
= false;
41 * =================== Input/output port handling =========================
46 struct a2j_stream
* str
)
48 struct a2j_port
*port
;
49 while (jack_ringbuffer_read(str
->new_ports
, (char*)&port
, sizeof(port
))) {
50 a2j_debug("jack: inserted port %s", port
->name
);
51 a2j_port_insert(str
->port_hash
, port
);
56 * ============================ Input ==============================
59 a2j_process_incoming (
61 struct a2j_port
* port
,
62 jack_nframes_t nframes
)
64 struct a2j_alsa_midi_event ev
;
66 jack_nframes_t one_period
;
68 /* grab data queued by the ALSA input thread and write it into the JACK
69 port buffer. it will delivered during the JACK period that this
70 function is called from.
73 /* first clear the JACK port buffer in preparation for new data
76 // a2j_debug ("PORT: %s process input", jack_port_name (port->jack_port));
78 jack_midi_clear_buffer (port
->jack_buf
);
80 now
= jack_frame_time (self
->jack_client
);
81 one_period
= jack_get_buffer_size (self
->jack_client
);
83 while (jack_ringbuffer_peek (port
->inbound_events
, (char*)&ev
, sizeof(ev
))) {
85 jack_midi_data_t
* buf
;
86 jack_nframes_t offset
;
88 if (ev
.time
>= self
->cycle_start
) {
92 jack_ringbuffer_read_advance (port
->inbound_events
, sizeof (ev
));
94 offset
= self
->cycle_start
- ev
.time
;
95 if (offset
> one_period
) {
96 /* from a previous cycle, somehow. cram it in at the front */
99 /* offset from start of the current cycle */
100 offset
= one_period
- offset
;
103 a2j_debug ("event at %d offset %d", ev
.time
, offset
);
105 /* make sure there is space for it */
107 buf
= jack_midi_event_reserve (port
->jack_buf
, offset
, ev
.size
);
111 jack_ringbuffer_read (port
->inbound_events
, (char*)buf
, ev
.size
);
113 /* throw it away (no space) */
114 jack_ringbuffer_read_advance (port
->inbound_events
, ev
.size
);
115 a2j_error ("threw away MIDI event - not reserved at time %d", ev
.time
);
118 a2j_debug("input on %s: sucked %d bytes from inbound at %d", jack_port_name (port
->jack_port
), ev
.size
, ev
.time
);
126 snd_seq_event_t
* ev
)
128 const snd_seq_addr_t addr
= ev
->data
.addr
;
130 if (addr
.client
== self
->client_id
)
133 if (ev
->type
== SND_SEQ_EVENT_PORT_START
|| ev
->type
== SND_SEQ_EVENT_PORT_CHANGE
) {
134 assert (jack_ringbuffer_write_space(self
->port_add
) >= sizeof(addr
));
136 a2j_debug("port_event: add/change %d:%d", addr
.client
, addr
.port
);
137 jack_ringbuffer_write(self
->port_add
, (char*)&addr
, sizeof(addr
));
138 } else if (ev
->type
== SND_SEQ_EVENT_PORT_EXIT
) {
139 a2j_debug("port_event: del %d:%d", addr
.client
, addr
.port
);
140 a2j_port_setdead(self
->stream
[A2J_PORT_CAPTURE
].port_hash
, addr
);
141 a2j_port_setdead(self
->stream
[A2J_PORT_PLAYBACK
].port_hash
, addr
);
149 snd_seq_event_t
* alsa_event
)
151 jack_midi_data_t data
[MAX_EVENT_SIZE
];
152 struct a2j_stream
*str
= &self
->stream
[A2J_PORT_CAPTURE
];
154 struct a2j_port
*port
;
157 now
= jack_frame_time (self
->jack_client
);
159 if ((port
= a2j_port_get(str
->port_hash
, alsa_event
->source
)) == NULL
) {
164 * RPNs, NRPNs, Bank Change, etc. need special handling
165 * but seems, ALSA does it for us already.
167 snd_midi_event_reset_decode(str
->codec
);
168 if ((size
= snd_midi_event_decode(str
->codec
, data
, sizeof(data
), alsa_event
))<0) {
172 // fixup NoteOn with vel 0
173 if ((data
[0] & 0xF0) == 0x90 && data
[2] == 0x00) {
174 data
[0] = 0x80 + (data
[0] & 0x0F);
178 a2j_debug("input: %d bytes at event_frame=%u", (int)size
, now
);
180 if (jack_ringbuffer_write_space(port
->inbound_events
) >= (sizeof(struct a2j_alsa_midi_event
) + size
)) {
181 struct a2j_alsa_midi_event ev
;
184 jack_ringbuffer_write(port
->inbound_events
, (char*)&ev
, sizeof(ev
));
185 jack_ringbuffer_write(port
->inbound_events
, (char*)data
, size
);
187 a2j_error ("MIDI data lost (incoming event buffer full): %ld bytes lost", size
);
193 * ============================ Output ==============================
197 a2j_process_outgoing (
199 struct a2j_port
* port
)
201 /* collect data from JACK port buffer and queue it for later delivery by ALSA output thread */
204 jack_ringbuffer_data_t vec
[2];
208 struct a2j_delivery_event
* dev
;
210 jack_ringbuffer_get_write_vector (self
->outbound_events
, vec
);
212 dev
= (struct a2j_delivery_event
*) vec
[0].buf
;
213 limit
= vec
[0].len
/ sizeof (struct a2j_delivery_event
);
214 nevents
= jack_midi_get_event_count (port
->jack_buf
);
216 limit
= (limit
> nevents
? nevents
: limit
);
218 for (i
= 0; i
< limit
; ++i
) {
220 jack_midi_event_get (&dev
->jack_event
, port
->jack_buf
, i
);
221 dev
->time
= dev
->jack_event
.time
;
227 /* anything left? use the second part of the vector, as much as possible */
230 dev
= (struct a2j_delivery_event
*) vec
[1].buf
;
231 limit
+= (vec
[1].len
/ sizeof (struct a2j_delivery_event
));
234 jack_midi_event_get (&dev
->jack_event
, port
->jack_buf
, i
);
235 dev
->time
= dev
->jack_event
.time
;
243 /* clear JACK port buffer; advance ring buffer ptr */
245 jack_ringbuffer_write_advance (self
->outbound_events
, written
* sizeof (struct a2j_delivery_event
));
251 time_sorter (void* a
, void* b
)
253 struct a2j_delivery_event
* ae
= (struct a2j_delivery_event
*) a
;
254 struct a2j_delivery_event
* ab
= (struct a2j_delivery_event
*) b
;
256 if (ae
->time
< ab
->time
) {
258 } else if (ae
->time
> ab
->time
) {
265 a2j_alsa_output_thread (void *arg
)
267 struct a2j
* self
= (struct a2j
*) arg
;
268 struct a2j_stream
*str
= &self
->stream
[A2J_PORT_PLAYBACK
];
272 jack_ringbuffer_data_t vec
[2];
273 snd_seq_event_t alsa_event
;
274 struct a2j_delivery_event
* ev
;
280 while (g_keep_walking
) {
282 /* first, make a list of all events in the outbound_events FIFO */
286 jack_ringbuffer_get_read_vector (self
->outbound_events
, vec
);
288 a2j_debug ("output thread: got %d+%d events",
289 (vec
[0].len
/ sizeof (struct a2j_delivery_event
)),
290 (vec
[1].len
/ sizeof (struct a2j_delivery_event
)));
292 ev
= (struct a2j_delivery_event
*) vec
[0].buf
;
293 limit
= vec
[0].len
/ sizeof (struct a2j_delivery_event
);
294 for (i
= 0; i
< limit
; ++i
) {
295 evlist
= jack_slist_append (evlist
, ev
);
299 ev
= (struct a2j_delivery_event
*) vec
[1].buf
;
300 limit
= vec
[1].len
/ sizeof (struct a2j_delivery_event
);
301 for (i
= 0; i
< limit
; ++i
) {
302 evlist
= jack_slist_append (evlist
, ev
);
306 if (vec
[0].len
+ vec
[1].len
== 0) {
307 /* no events: wait for some */
308 a2j_debug ("output thread: wait for events");
309 sem_wait (&self
->io_semaphore
);
310 a2j_debug ("output thread: AWAKE ... loop back for events");
314 /* now sort this list by time */
316 evlist
= jack_slist_sort (evlist
, time_sorter
);
320 sr
= jack_get_sample_rate (self
->jack_client
);
322 for (iter
= evlist
; iter
; iter
= iter
->next
) {
324 ev
= (struct a2j_delivery_event
*) iter
->data
;
326 snd_seq_ev_clear(&alsa_event
);
327 snd_midi_event_reset_encode(str
->codec
);
328 if (!snd_midi_event_encode(str
->codec
, ev
->jack_event
.buffer
, ev
->jack_event
.size
, &alsa_event
)) {
329 continue; // invalid event
332 snd_seq_ev_set_source(&alsa_event
, self
->port_id
);
333 snd_seq_ev_set_dest(&alsa_event
, ev
->port
->remote
.client
, ev
->port
->remote
.port
);
334 snd_seq_ev_set_direct (&alsa_event
);
336 now
= jack_frame_time (self
->jack_client
);
338 ev
->time
+= self
->cycle_start
;
340 a2j_debug ("@ %d, next event @ %d", now
, ev
->time
);
342 /* do we need to wait a while before delivering? */
344 if (ev
->time
> now
) {
345 struct timespec nanoseconds
;
346 jack_nframes_t sleep_frames
= ev
->time
- now
;
347 float seconds
= sleep_frames
/ sr
;
349 /* if the gap is long enough, sleep */
351 if (seconds
> 0.001) {
352 nanoseconds
.tv_sec
= (time_t) seconds
;
353 nanoseconds
.tv_nsec
= (long) NSEC_PER_SEC
* (seconds
- nanoseconds
.tv_sec
);
355 a2j_debug ("output thread sleeps for %.2f msec", ((double) nanoseconds
.tv_nsec
/ NSEC_PER_SEC
) * 1000.0);
357 if (nanosleep (&nanoseconds
, NULL
) < 0) {
358 fprintf (stderr
, "BAD SLEEP\n");
364 /* its time to deliver */
365 err
= snd_seq_event_output(self
->seq
, &alsa_event
);
366 snd_seq_drain_output (self
->seq
);
367 now
= jack_frame_time (self
->jack_client
);
368 a2j_debug("alsa_out: written %d bytes to %s at %d, DELTA = %d", ev
->jack_event
.size
, ev
->port
->name
, now
,
369 (int32_t) (now
- ev
->time
));
372 /* release the sorted event list */
374 jack_slist_free (evlist
);
376 /* free up space in the FIFO */
378 jack_ringbuffer_read_advance (self
->outbound_events
, vec
[0].len
+ vec
[1].len
);
380 /* and head back for more */
386 #define a2j_ptr ((struct a2j *)arg)
391 a2j_alsa_input_thread (void* arg
)
393 struct a2j
* self
= (struct a2j
* ) arg
;
397 npfd
= snd_seq_poll_descriptors_count(self
->seq
, POLLIN
);
398 pfd
= (struct pollfd
*)alloca(npfd
* sizeof(struct pollfd
));
399 snd_seq_poll_descriptors(self
->seq
, pfd
, npfd
, POLLIN
);
401 while (g_keep_walking
) {
403 if ((ret
= poll(pfd
, npfd
, 1000)) > 0) {
405 snd_seq_event_t
*event
;
407 while (snd_seq_event_input (self
->seq
, &event
) > 0) {
408 if (event
->source
.client
== SND_SEQ_CLIENT_SYSTEM
) {
409 a2j_port_event(a2j_ptr
, event
);
411 a2j_input_event(a2j_ptr
, event
);
414 snd_seq_free_event (event
);
427 a2j_jack_process_internal(
430 jack_nframes_t nframes
)
432 struct a2j_stream
* stream_ptr
;
434 struct a2j_port
** port_ptr_ptr
;
435 struct a2j_port
* port_ptr
;
438 stream_ptr
= &self
->stream
[dir
];
439 a2j_add_ports (stream_ptr
);
442 for (i
= 0 ; i
< PORT_HASH_SIZE
; i
++)
444 port_ptr_ptr
= &stream_ptr
->port_hash
[i
];
445 while (*port_ptr_ptr
!= NULL
)
447 port_ptr
= *port_ptr_ptr
;
449 if (!port_ptr
->is_dead
)
451 port_ptr
->jack_buf
= jack_port_get_buffer(port_ptr
->jack_port
, nframes
);
453 if (dir
== A2J_PORT_CAPTURE
) {
454 a2j_process_incoming (self
, port_ptr
, nframes
);
456 nevents
+= a2j_process_outgoing (self
, port_ptr
);
459 } else if (jack_ringbuffer_write_space (self
->port_del
) >= sizeof(port_ptr
)) {
461 a2j_debug("jack: removed port %s", port_ptr
->name
);
462 *port_ptr_ptr
= port_ptr
->next
;
463 jack_ringbuffer_write(self
->port_del
, (char*)&port_ptr
, sizeof(port_ptr
));
468 port_ptr_ptr
= &port_ptr
->next
;
472 /* if we queued up anything for output, tell the output thread in
473 case its waiting for us.
478 sem_getvalue (&self
->io_semaphore
, &sv
);
479 sem_post (&self
->io_semaphore
);
486 jack_nframes_t nframes
,
489 struct a2j
* self
= (struct a2j
*) arg
;
494 self
->cycle_start
= jack_last_frame_time (self
->jack_client
);
496 a2j_jack_process_internal (self
, A2J_PORT_CAPTURE
, nframes
);
497 a2j_jack_process_internal (self
, A2J_PORT_PLAYBACK
, nframes
);
508 g_freewheeling
= starting
;
516 a2j_warning("JACK server shutdown notification received.");
517 g_stop_request
= true;
523 a2j_jack_client_create(
524 struct a2j
* a2j_ptr
,
525 const char * client_name
,
526 const char * server_name
)
528 jack_status_t status
;
529 jack_client_t
* jack_client
;
531 if (server_name
!= NULL
)
533 jack_client
= jack_client_open(client_name
, JackServerName
|JackNoStartServer
|JackUseExactName
, &status
, server_name
);
537 jack_client
= jack_client_open(client_name
, JackNoStartServer
|JackUseExactName
, &status
);
542 a2j_error("Cannot create jack client");
546 jack_set_process_callback(jack_client
, a2j_jack_process
, a2j_ptr
);
547 jack_set_freewheel_callback(jack_client
, a2j_jack_freewheel
, NULL
);
548 jack_on_shutdown(jack_client
, a2j_jack_shutdown
, NULL
);