restore files deleted by previous commit
[a2jmidid.git] / jack.c
blob25d6c1beb21798195649fcdc110ced16108395b0
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
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
22 #include <stdbool.h>
23 #include <time.h>
24 #include <alsa/asoundlib.h>
25 #include <jack/jack.h>
26 #include <jack/midiport.h>
27 #include <jack/ringbuffer.h>
29 #include "jslist.h"
30 #include "list.h"
31 #include "structs.h"
32 #include "jack.h"
33 #include "log.h"
34 #include "port_hash.h"
35 #include "port.h"
36 #include "a2jmidid.h"
38 static bool g_freewheeling = false;
41 * =================== Input/output port handling =========================
44 void
45 a2j_add_ports(
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 ==============================
58 void
59 a2j_process_incoming (
60 struct a2j * self,
61 struct a2j_port * port,
62 jack_nframes_t nframes)
64 struct a2j_alsa_midi_event ev;
65 jack_nframes_t now;
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) {
89 break;
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 */
97 offset = 0;
98 } else {
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);
109 if (buf) {
110 /* grab the event */
111 jack_ringbuffer_read (port->inbound_events, (char*)buf, ev.size);
112 } else {
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);
122 static
123 void
124 a2j_port_event(
125 struct a2j * self,
126 snd_seq_event_t * ev)
128 const snd_seq_addr_t addr = ev->data.addr;
130 if (addr.client == self->client_id)
131 return;
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);
145 static
146 void
147 a2j_input_event(
148 struct a2j * self,
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];
153 long size;
154 struct a2j_port *port;
155 jack_nframes_t now;
157 now = jack_frame_time (self->jack_client);
159 if ((port = a2j_port_get(str->port_hash, alsa_event->source)) == NULL) {
160 return;
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) {
169 return;
172 // fixup NoteOn with vel 0
173 if ((data[0] & 0xF0) == 0x90 && data[2] == 0x00) {
174 data[0] = 0x80 + (data[0] & 0x0F);
175 data[2] = 0x40;
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;
182 ev.time = now;
183 ev.size = size;
184 jack_ringbuffer_write(port->inbound_events, (char*)&ev, sizeof(ev));
185 jack_ringbuffer_write(port->inbound_events, (char*)data, size);
186 } else {
187 a2j_error ("MIDI data lost (incoming event buffer full): %ld bytes lost", size);
193 * ============================ Output ==============================
197 a2j_process_outgoing (
198 struct a2j * self,
199 struct a2j_port * port)
201 /* collect data from JACK port buffer and queue it for later delivery by ALSA output thread */
203 int nevents;
204 jack_ringbuffer_data_t vec[2];
205 int i;
206 int written = 0;
207 size_t limit;
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;
222 dev->port = port;
223 written++;
224 ++dev;
227 /* anything left? use the second part of the vector, as much as possible */
229 if (i < nevents) {
230 dev = (struct a2j_delivery_event*) vec[1].buf;
231 limit += (vec[1].len / sizeof (struct a2j_delivery_event));
233 while (i < limit) {
234 jack_midi_event_get (&dev->jack_event, port->jack_buf, i);
235 dev->time = dev->jack_event.time;
236 dev->port = port;
237 written++;
238 ++dev;
239 ++i;
243 /* clear JACK port buffer; advance ring buffer ptr */
245 jack_ringbuffer_write_advance (self->outbound_events, written * sizeof (struct a2j_delivery_event));
247 return nevents;
250 static int
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) {
257 return -1;
258 } else if (ae->time > ab->time) {
259 return 1;
261 return 0;
264 void*
265 a2j_alsa_output_thread (void *arg)
267 struct a2j * self = (struct a2j*) arg;
268 struct a2j_stream *str = &self->stream[A2J_PORT_PLAYBACK];
269 int i;
270 JSList* evlist;
271 JSList* iter;
272 jack_ringbuffer_data_t vec[2];
273 snd_seq_event_t alsa_event;
274 struct a2j_delivery_event* ev;
275 float sr;
276 jack_nframes_t now;
277 int err;
278 int limit;
280 while (g_keep_walking) {
282 /* first, make a list of all events in the outbound_events FIFO */
284 evlist = NULL;
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);
296 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);
303 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");
311 continue;
314 /* now sort this list by time */
316 evlist = jack_slist_sort (evlist, time_sorter);
318 /* now deliver */
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");
359 /* do something ? */
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 */
383 return (void*) 0;
386 #define a2j_ptr ((struct a2j *)arg)
388 /* ALSA */
390 void*
391 a2j_alsa_input_thread (void* arg)
393 struct a2j* self = (struct a2j* ) arg;
394 int npfd;
395 struct pollfd *pfd;
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) {
402 int ret;
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);
410 } else {
411 a2j_input_event(a2j_ptr, event);
414 snd_seq_free_event (event);
419 return (void*) 0;
423 /* JACK */
425 static
426 void
427 a2j_jack_process_internal(
428 struct a2j * self,
429 int dir,
430 jack_nframes_t nframes)
432 struct a2j_stream * stream_ptr;
433 int i;
434 struct a2j_port ** port_ptr_ptr;
435 struct a2j_port * port_ptr;
436 int nevents = 0;
438 stream_ptr = &self->stream[dir];
439 a2j_add_ports (stream_ptr);
441 // process ports
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);
455 } else {
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));
464 continue;
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.
476 if (nevents > 0) {
477 int sv;
478 sem_getvalue (&self->io_semaphore, &sv);
479 sem_post (&self->io_semaphore);
483 static
485 a2j_jack_process(
486 jack_nframes_t nframes,
487 void * arg)
489 struct a2j* self = (struct a2j *) arg;
491 if (g_freewheeling)
492 return 0;
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);
499 return 0;
502 static
503 void
504 a2j_jack_freewheel(
505 int starting,
506 void * arg)
508 g_freewheeling = starting;
511 static
512 void
513 a2j_jack_shutdown(
514 void * arg)
516 a2j_warning("JACK server shutdown notification received.");
517 g_stop_request = true;
520 #undef a2j_ptr
522 jack_client_t *
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);
535 else
537 jack_client = jack_client_open(client_name, JackNoStartServer|JackUseExactName, &status);
540 if (!jack_client)
542 a2j_error("Cannot create jack client");
543 return NULL;
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);
550 return jack_client;