diff options
Diffstat (limited to 'drivers/am')
-rw-r--r-- | drivers/am/alsa_midi.h | 6 | ||||
-rw-r--r-- | drivers/am/alsa_midi_driver.c | 70 | ||||
-rw-r--r-- | drivers/am/alsa_rawmidi.c | 704 | ||||
-rw-r--r-- | drivers/am/alsa_seqmidi.c | 609 | ||||
-rw-r--r-- | drivers/am/midi_pack.h | 7 | ||||
-rw-r--r-- | drivers/am/midi_unpack.h | 87 |
6 files changed, 793 insertions, 690 deletions
diff --git a/drivers/am/alsa_midi.h b/drivers/am/alsa_midi.h index b49228a..d0cf258 100644 --- a/drivers/am/alsa_midi.h +++ b/drivers/am/alsa_midi.h @@ -38,10 +38,10 @@ alsa_midi_t* alsa_seqmidi_new(jack_client_t *jack, const char* alsa_name); typedef struct _alsa_midi_driver { - JACK_DRIVER_DECL; + JACK_DRIVER_DECL; - alsa_midi_t *midi; - jack_client_t *client; + alsa_midi_t *midi; + jack_client_t *client; } alsa_midi_driver_t; diff --git a/drivers/am/alsa_midi_driver.c b/drivers/am/alsa_midi_driver.c index b27f03c..4da85ed 100644 --- a/drivers/am/alsa_midi_driver.c +++ b/drivers/am/alsa_midi_driver.c @@ -3,48 +3,49 @@ #include <string.h> static int -alsa_midi_driver_attach( alsa_midi_driver_t *driver, jack_engine_t *engine ) +alsa_midi_driver_attach ( alsa_midi_driver_t *driver, jack_engine_t *engine ) { - return driver->midi->attach(driver->midi); + return driver->midi->attach (driver->midi); } static int -alsa_midi_driver_detach( alsa_midi_driver_t *driver, jack_engine_t *engine ) +alsa_midi_driver_detach ( alsa_midi_driver_t *driver, jack_engine_t *engine ) { - return driver->midi->detach(driver->midi); + return driver->midi->detach (driver->midi); } static int -alsa_midi_driver_read( alsa_midi_driver_t *driver, jack_nframes_t nframes ) +alsa_midi_driver_read ( alsa_midi_driver_t *driver, jack_nframes_t nframes ) { - driver->midi->read(driver->midi, nframes); + driver->midi->read (driver->midi, nframes); return 0; } static int -alsa_midi_driver_write( alsa_midi_driver_t *driver, jack_nframes_t nframes ) +alsa_midi_driver_write ( alsa_midi_driver_t *driver, jack_nframes_t nframes ) { - driver->midi->write(driver->midi, nframes); + driver->midi->write (driver->midi, nframes); return 0; } static int -alsa_midi_driver_start( alsa_midi_driver_t *driver ) +alsa_midi_driver_start ( alsa_midi_driver_t *driver ) { - return driver->midi->start(driver->midi); + return driver->midi->start (driver->midi); } static int -alsa_midi_driver_stop( alsa_midi_driver_t *driver ) +alsa_midi_driver_stop ( alsa_midi_driver_t *driver ) { - return driver->midi->stop(driver->midi); + return driver->midi->stop (driver->midi); } static void -alsa_midi_driver_delete( alsa_midi_driver_t *driver ) +alsa_midi_driver_delete ( alsa_midi_driver_t *driver ) { - if (driver->midi) + if (driver->midi) { (driver->midi->destroy)(driver->midi); + } free (driver); } @@ -54,24 +55,24 @@ alsa_midi_driver_new (jack_client_t *client, const char *name) { alsa_midi_driver_t *driver; - jack_info ("creating alsa_midi driver ..."); + jack_info ("creating alsa_midi driver ..."); - driver = (alsa_midi_driver_t *) calloc (1, sizeof (alsa_midi_driver_t)); + driver = (alsa_midi_driver_t*)calloc (1, sizeof(alsa_midi_driver_t)); - jack_driver_init ((jack_driver_t *) driver); + jack_driver_init ((jack_driver_t*)driver); - driver->attach = (JackDriverAttachFunction) alsa_midi_driver_attach; - driver->detach = (JackDriverDetachFunction) alsa_midi_driver_detach; - driver->read = (JackDriverReadFunction) alsa_midi_driver_read; - driver->write = (JackDriverWriteFunction) alsa_midi_driver_write; - driver->start = (JackDriverStartFunction) alsa_midi_driver_start; - driver->stop = (JackDriverStartFunction) alsa_midi_driver_stop; + driver->attach = (JackDriverAttachFunction)alsa_midi_driver_attach; + driver->detach = (JackDriverDetachFunction)alsa_midi_driver_detach; + driver->read = (JackDriverReadFunction)alsa_midi_driver_read; + driver->write = (JackDriverWriteFunction)alsa_midi_driver_write; + driver->start = (JackDriverStartFunction)alsa_midi_driver_start; + driver->stop = (JackDriverStartFunction)alsa_midi_driver_stop; - driver->midi = alsa_seqmidi_new(client, NULL); + driver->midi = alsa_seqmidi_new (client, NULL); driver->client = client; - return (jack_driver_t *) driver; + return (jack_driver_t*)driver; } /* DRIVER "PLUGIN" INTERFACE */ @@ -83,14 +84,15 @@ driver_get_descriptor () { jack_driver_desc_t * desc; jack_driver_param_desc_t * params; + //unsigned int i; - desc = calloc (1, sizeof (jack_driver_desc_t)); + desc = calloc (1, sizeof(jack_driver_desc_t)); - strcpy (desc->name,"alsa_midi"); + strcpy (desc->name, "alsa_midi"); desc->nparams = 0; - - params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t)); + + params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t)); desc->params = params; @@ -104,19 +106,19 @@ driver_initialize (jack_client_t *client, const JSList * params) const jack_driver_param_t * param; for (node = params; node; node = jack_slist_next (node)) { - param = (const jack_driver_param_t *) node->data; + param = (const jack_driver_param_t*)node->data; switch (param->character) { - default: - break; + default: + break; } } - + return alsa_midi_driver_new (client, NULL); } void driver_finish (jack_driver_t *driver) { - alsa_midi_driver_delete ((alsa_midi_driver_t *) driver); + alsa_midi_driver_delete ((alsa_midi_driver_t*)driver); } diff --git a/drivers/am/alsa_rawmidi.c b/drivers/am/alsa_rawmidi.c index 9db97fb..ba73561 100644 --- a/drivers/am/alsa_rawmidi.c +++ b/drivers/am/alsa_rawmidi.c @@ -38,16 +38,16 @@ #ifdef STANDALONE -#define MESSAGE(...) fprintf(stderr, __VA_ARGS__) +#define MESSAGE(...) fprintf (stderr, __VA_ARGS__) #else #include "messagebuffer.h" #endif -#define info_log(...) MESSAGE(__VA_ARGS__) -#define error_log(...) MESSAGE(__VA_ARGS__) +#define info_log(...) MESSAGE (__VA_ARGS__) +#define error_log(...) MESSAGE (__VA_ARGS__) #ifdef JACK_MIDI_DEBUG -#define debug_log(...) MESSAGE(__VA_ARGS__) +#define debug_log(...) MESSAGE (__VA_ARGS__) #else #define debug_log(...) #endif @@ -62,13 +62,13 @@ enum { enum { #ifndef JACK_MIDI_DEBUG MAX_PFDS = 64, - MAX_PORTS = MAX_PFDS-1, + MAX_PORTS = MAX_PFDS - 1, MAX_EVENTS = 4096, - MAX_DATA = 64*1024, + MAX_DATA = 64 * 1024, MIDI_THREAD_PRIO = 80 #else MAX_PFDS = 6, - MAX_PORTS = MAX_PFDS-1, + MAX_PORTS = MAX_PFDS - 1, MAX_EVENTS = 16, MAX_DATA = 64, MIDI_THREAD_PRIO = 80 @@ -122,7 +122,7 @@ typedef struct input_port_t { // jack midi_unpack_t unpack; - + // midi int overruns; } input_port_t; @@ -132,7 +132,7 @@ typedef struct output_port_t { // jack midi_pack_t packer; - + // midi event_head_t next_event; int todo; @@ -212,33 +212,36 @@ static int do_midi_output(process_midi_t *m); static -int stream_init(midi_stream_t *s, alsa_rawmidi_t *midi, const char *name) +int stream_init (midi_stream_t *s, alsa_rawmidi_t *midi, const char *name) { s->owner = midi; s->name = name; - if (pipe(s->wake_pipe)==-1) { + if (pipe (s->wake_pipe) == -1) { s->wake_pipe[0] = -1; - error_log("pipe() in stream_init(%s) failed: %s", name, strerror(errno)); + error_log ("pipe() in stream_init(%s) failed: %s", name, strerror (errno)); return -errno; } - s->jack.new_ports = jack_ringbuffer_create(sizeof(midi_port_t*)*MAX_PORTS); - s->midi.new_ports = jack_ringbuffer_create(sizeof(midi_port_t*)*MAX_PORTS); - if (!s->jack.new_ports || !s->midi.new_ports) + s->jack.new_ports = jack_ringbuffer_create (sizeof(midi_port_t*) * MAX_PORTS); + s->midi.new_ports = jack_ringbuffer_create (sizeof(midi_port_t*) * MAX_PORTS); + if (!s->jack.new_ports || !s->midi.new_ports) { return -ENOMEM; + } return 0; } static -void stream_close(midi_stream_t *s) +void stream_close (midi_stream_t *s) { if (s->wake_pipe[0] != -1) { - close(s->wake_pipe[0]); - close(s->wake_pipe[1]); + close (s->wake_pipe[0]); + close (s->wake_pipe[1]); + } + if (s->jack.new_ports) { + jack_ringbuffer_free (s->jack.new_ports); + } + if (s->midi.new_ports) { + jack_ringbuffer_free (s->midi.new_ports); } - if (s->jack.new_ports) - jack_ringbuffer_free(s->jack.new_ports); - if (s->midi.new_ports) - jack_ringbuffer_free(s->midi.new_ports); } static void alsa_rawmidi_delete(alsa_midi_t *m); @@ -249,19 +252,22 @@ static int alsa_rawmidi_stop(alsa_midi_t *m); static void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes); static void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes); -alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack) +alsa_midi_t* alsa_rawmidi_new (jack_client_t *jack) { - alsa_rawmidi_t *midi = calloc(1, sizeof(alsa_rawmidi_t)); - if (!midi) + alsa_rawmidi_t *midi = calloc (1, sizeof(alsa_rawmidi_t)); + + if (!midi) { goto fail_0; + } midi->client = jack; - if (pipe(midi->scan.wake_pipe)==-1) { - error_log("pipe() in alsa_midi_new failed: %s", strerror(errno)); + if (pipe (midi->scan.wake_pipe) == -1) { + error_log ("pipe() in alsa_midi_new failed: %s", strerror (errno)); goto fail_1; } - if (stream_init(&midi->in, midi, "in")) + if (stream_init (&midi->in, midi, "in")) { goto fail_2; + } midi->in.mode = POLLIN; midi->in.port_size = sizeof(input_port_t); midi->in.port_init = input_port_init; @@ -269,8 +275,9 @@ alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack) midi->in.process_jack = do_jack_input; midi->in.process_midi = do_midi_input; - if (stream_init(&midi->out, midi, "out")) + if (stream_init (&midi->out, midi, "out")) { goto fail_3; + } midi->out.mode = POLLOUT; midi->out.port_size = sizeof(output_port_t); midi->out.port_init = output_port_init; @@ -287,15 +294,15 @@ alsa_midi_t* alsa_rawmidi_new(jack_client_t *jack) midi->ops.write = alsa_rawmidi_write; return &midi->ops; - fail_3: - stream_close(&midi->out); - fail_2: - stream_close(&midi->in); - close(midi->scan.wake_pipe[1]); - close(midi->scan.wake_pipe[0]); - fail_1: - free(midi); - fail_0: +fail_3: + stream_close (&midi->out); +fail_2: + stream_close (&midi->in); + close (midi->scan.wake_pipe[1]); + close (midi->scan.wake_pipe[0]); +fail_1: + free (midi); +fail_0: return NULL; } @@ -303,90 +310,94 @@ static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list); static -void alsa_rawmidi_delete(alsa_midi_t *m) +void alsa_rawmidi_delete (alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; - alsa_rawmidi_detach(m); + alsa_rawmidi_detach (m); - stream_close(&midi->out); - stream_close(&midi->in); - close(midi->scan.wake_pipe[0]); - close(midi->scan.wake_pipe[1]); + stream_close (&midi->out); + stream_close (&midi->in); + close (midi->scan.wake_pipe[0]); + close (midi->scan.wake_pipe[1]); - free(midi); + free (midi); } static void* scan_thread(void *); static void *midi_thread(void *arg); static -int alsa_rawmidi_attach(alsa_midi_t *m) +int alsa_rawmidi_attach (alsa_midi_t *m) { return 0; } static -int alsa_rawmidi_detach(alsa_midi_t *m) +int alsa_rawmidi_detach (alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; midi_port_t **list; - alsa_rawmidi_stop(m); + alsa_rawmidi_stop (m); list = &midi->scan.ports; while (*list) { (*list)->state = PORT_REMOVED_FROM_JACK; - list = scan_port_del(midi, list); + list = scan_port_del (midi, list); } return 0; } static -int alsa_rawmidi_start(alsa_midi_t *m) +int alsa_rawmidi_start (alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; int err; char c = 'q'; - if (midi->keep_walking == 1) + + if (midi->keep_walking == 1) { return -EALREADY; + } midi->keep_walking = 1; - if ((err = jack_client_create_thread(midi->client, &midi->in.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->in))) { + if ((err = jack_client_create_thread (midi->client, &midi->in.thread, MIDI_THREAD_PRIO, jack_is_realtime (midi->client), midi_thread, &midi->in))) { midi->keep_walking = 0; return err; } - if ((err = jack_client_create_thread(midi->client, &midi->out.thread, MIDI_THREAD_PRIO, jack_is_realtime(midi->client), midi_thread, &midi->out))) { + if ((err = jack_client_create_thread (midi->client, &midi->out.thread, MIDI_THREAD_PRIO, jack_is_realtime (midi->client), midi_thread, &midi->out))) { midi->keep_walking = 0; - write(midi->in.wake_pipe[1], &c, 1); - pthread_join(midi->in.thread, NULL); + write (midi->in.wake_pipe[1], &c, 1); + pthread_join (midi->in.thread, NULL); return err; } - if ((err = jack_client_create_thread(midi->client, &midi->scan.thread, 0, 0, scan_thread, midi))) { + if ((err = jack_client_create_thread (midi->client, &midi->scan.thread, 0, 0, scan_thread, midi))) { midi->keep_walking = 0; - write(midi->in.wake_pipe[1], &c, 1); - write(midi->out.wake_pipe[1], &c, 1); - pthread_join(midi->in.thread, NULL); - pthread_join(midi->out.thread, NULL); + write (midi->in.wake_pipe[1], &c, 1); + write (midi->out.wake_pipe[1], &c, 1); + pthread_join (midi->in.thread, NULL); + pthread_join (midi->out.thread, NULL); return err; } return 0; } static -int alsa_rawmidi_stop(alsa_midi_t *m) +int alsa_rawmidi_stop (alsa_midi_t *m) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; char c = 'q'; - if (midi->keep_walking == 0) + + if (midi->keep_walking == 0) { return -EALREADY; + } midi->keep_walking = 0; - write(midi->in.wake_pipe[1], &c, 1); - write(midi->out.wake_pipe[1], &c, 1); - write(midi->scan.wake_pipe[1], &c, 1); - pthread_join(midi->in.thread, NULL); - pthread_join(midi->out.thread, NULL); - pthread_join(midi->scan.thread, NULL); + write (midi->in.wake_pipe[1], &c, 1); + write (midi->out.wake_pipe[1], &c, 1); + write (midi->scan.wake_pipe[1], &c, 1); + pthread_join (midi->in.thread, NULL); + pthread_join (midi->out.thread, NULL); + pthread_join (midi->scan.thread, NULL); // ports are freed in alsa_midi_detach() return 0; } @@ -394,59 +405,63 @@ int alsa_rawmidi_stop(alsa_midi_t *m) static void jack_process(midi_stream_t *str, jack_nframes_t nframes); static -void alsa_rawmidi_read(alsa_midi_t *m, jack_nframes_t nframes) +void alsa_rawmidi_read (alsa_midi_t *m, jack_nframes_t nframes) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; - jack_process(&midi->in, nframes); + + jack_process (&midi->in, nframes); } static -void alsa_rawmidi_write(alsa_midi_t *m, jack_nframes_t nframes) +void alsa_rawmidi_write (alsa_midi_t *m, jack_nframes_t nframes) { alsa_rawmidi_t *midi = (alsa_rawmidi_t*)m; - jack_process(&midi->out, nframes); + + jack_process (&midi->out, nframes); } /* * ----------------------------------------------------------------------------- */ static inline -int can_pass(size_t sz, jack_ringbuffer_t *in, jack_ringbuffer_t *out) +int can_pass (size_t sz, jack_ringbuffer_t *in, jack_ringbuffer_t *out) { - return jack_ringbuffer_read_space(in) >= sz && jack_ringbuffer_write_space(out) >= sz; + return jack_ringbuffer_read_space (in) >= sz && jack_ringbuffer_write_space (out) >= sz; } static -void midi_port_init(const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_info_t *info, const alsa_id_t *id) +void midi_port_init (const alsa_rawmidi_t *midi, midi_port_t *port, snd_rawmidi_info_t *info, const alsa_id_t *id) { const char *name; char *c; port->id = *id; - snprintf(port->dev, sizeof(port->dev), "hw:%d,%d,%d", id->id[0], id->id[1], id->id[3]); - name = snd_rawmidi_info_get_subdevice_name(info); - if (!strlen(name)) - name = snd_rawmidi_info_get_name(info); - snprintf(port->name, sizeof(port->name), "%s %s %s", port->id.id[2] ? "out":"in", port->dev, name); + snprintf (port->dev, sizeof(port->dev), "hw:%d,%d,%d", id->id[0], id->id[1], id->id[3]); + name = snd_rawmidi_info_get_subdevice_name (info); + if (!strlen (name)) { + name = snd_rawmidi_info_get_name (info); + } + snprintf (port->name, sizeof(port->name), "%s %s %s", port->id.id[2] ? "out" : "in", port->dev, name); // replace all offending characters with '-' - for (c=port->name; *c; ++c) - if (!isalnum(*c)) + for (c = port->name; *c; ++c) + if (!isalnum (*c)) { *c = '-'; + } port->state = PORT_CREATED; } static -inline int midi_port_open_jack(const alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *name) +inline int midi_port_open_jack (const alsa_rawmidi_t *midi, midi_port_t *port, int type, const char *name) { - port->jack = jack_port_register(midi->client, name, JACK_DEFAULT_MIDI_TYPE, - type | JackPortIsPhysical|JackPortIsTerminal, 0); + port->jack = jack_port_register (midi->client, name, JACK_DEFAULT_MIDI_TYPE, + type | JackPortIsPhysical | JackPortIsTerminal, 0); return port->jack == NULL; } static -int midi_port_open(const alsa_rawmidi_t *midi, midi_port_t *port) +int midi_port_open (const alsa_rawmidi_t *midi, midi_port_t *port) { int err; int type; @@ -461,45 +476,49 @@ int midi_port_open(const alsa_rawmidi_t *midi, midi_port_t *port) out = &port->rawmidi; type = JackPortIsInput; } - - if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0) + + if ((err = snd_rawmidi_open (in, out, port->dev, SND_RAWMIDI_NONBLOCK)) < 0) { return err; + } /* Some devices (emu10k1) have subdevs with the same name, * and we need to generate unique port name for jack */ - snprintf(name, sizeof(name), "%s", port->name); - if (midi_port_open_jack(midi, port, type, name)) { + snprintf (name, sizeof(name), "%s", port->name); + if (midi_port_open_jack (midi, port, type, name)) { int num; num = port->id.id[3] ? port->id.id[3] : port->id.id[1]; - snprintf(name, sizeof(name), "%s %d", port->name, num); - if (midi_port_open_jack(midi, port, type, name)) + snprintf (name, sizeof(name), "%s %d", port->name, num); + if (midi_port_open_jack (midi, port, type, name)) { return 2; + } } - if ((port->event_ring = jack_ringbuffer_create(MAX_EVENTS*sizeof(event_head_t)))==NULL) + if ((port->event_ring = jack_ringbuffer_create (MAX_EVENTS * sizeof(event_head_t))) == NULL) { return 3; - if ((port->data_ring = jack_ringbuffer_create(MAX_DATA))==NULL) + } + if ((port->data_ring = jack_ringbuffer_create (MAX_DATA)) == NULL) { return 4; + } return 0; } static -void midi_port_close(const alsa_rawmidi_t *midi, midi_port_t *port) +void midi_port_close (const alsa_rawmidi_t *midi, midi_port_t *port) { if (port->data_ring) { - jack_ringbuffer_free(port->data_ring); + jack_ringbuffer_free (port->data_ring); port->data_ring = NULL; } if (port->event_ring) { - jack_ringbuffer_free(port->event_ring); + jack_ringbuffer_free (port->event_ring); port->event_ring = NULL; } if (port->jack) { - jack_port_unregister(midi->client, port->jack); + jack_port_unregister (midi->client, port->jack); port->jack = NULL; } if (port->rawmidi) { - snd_rawmidi_close(port->rawmidi); + snd_rawmidi_close (port->rawmidi); port->rawmidi = NULL; } } @@ -509,31 +528,33 @@ void midi_port_close(const alsa_rawmidi_t *midi, midi_port_t *port) */ static -int alsa_id_before(const alsa_id_t *p1, const alsa_id_t *p2) +int alsa_id_before (const alsa_id_t *p1, const alsa_id_t *p2) { int i; - for (i=0; i<4; ++i) { - if (p1->id[i] < p2->id[i]) + + for (i = 0; i < 4; ++i) { + if (p1->id[i] < p2->id[i]) { return 1; - else if (p1->id[i] > p2->id[i]) + } else if (p1->id[i] > p2->id[i]) { return 0; + } } return 0; } static -void alsa_get_id(alsa_id_t *id, snd_rawmidi_info_t *info) +void alsa_get_id (alsa_id_t *id, snd_rawmidi_info_t *info) { - id->id[0] = snd_rawmidi_info_get_card(info); - id->id[1] = snd_rawmidi_info_get_device(info); - id->id[2] = snd_rawmidi_info_get_stream(info) == SND_RAWMIDI_STREAM_OUTPUT ? 1 : 0; - id->id[3] = snd_rawmidi_info_get_subdevice(info); + id->id[0] = snd_rawmidi_info_get_card (info); + id->id[1] = snd_rawmidi_info_get_device (info); + id->id[2] = snd_rawmidi_info_get_stream (info) == SND_RAWMIDI_STREAM_OUTPUT ? 1 : 0; + id->id[3] = snd_rawmidi_info_get_subdevice (info); } static inline -void alsa_error(const char *func, int err) +void alsa_error (const char *func, int err) { - error_log("%s() failed", snd_strerror(err)); + error_log ("%s() failed", snd_strerror (err)); } typedef struct { @@ -546,136 +567,145 @@ typedef struct { static midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list); static -void scan_cleanup(alsa_rawmidi_t *midi) +void scan_cleanup (alsa_rawmidi_t *midi) { midi_port_t **list = &midi->scan.ports; + while (*list) - list = scan_port_del(midi, list); + list = scan_port_del (midi, list); } static void scan_card(scan_t *scan); static midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list); -void scan_cycle(alsa_rawmidi_t *midi) +void scan_cycle (alsa_rawmidi_t *midi) { int card = -1, err; scan_t scan; midi_port_t **ports; //debug_log("scan: cleanup"); - scan_cleanup(midi); + scan_cleanup (midi); scan.midi = midi; scan.iterator = &midi->scan.ports; - snd_rawmidi_info_alloca(&scan.info); + snd_rawmidi_info_alloca (&scan.info); //debug_log("scan: rescan"); - while ((err = snd_card_next(&card))>=0 && card>=0) { + while ((err = snd_card_next (&card)) >= 0 && card >= 0) { char name[32]; - snprintf(name, sizeof(name), "hw:%d", card); - if ((err = snd_ctl_open(&scan.ctl, name, SND_CTL_NONBLOCK))>=0) { - scan_card(&scan); - snd_ctl_close(scan.ctl); - } else - alsa_error("scan: snd_ctl_open", err); + snprintf (name, sizeof(name), "hw:%d", card); + if ((err = snd_ctl_open (&scan.ctl, name, SND_CTL_NONBLOCK)) >= 0) { + scan_card (&scan); + snd_ctl_close (scan.ctl); + } else { + alsa_error ("scan: snd_ctl_open", err); + } } // delayed open to workaround alsa<1.0.14 bug (can't open more than 1 subdevice if ctl is opened). ports = &midi->scan.ports; while (*ports) { midi_port_t *port = *ports; - if (port->state == PORT_CREATED) - ports = scan_port_open(midi, ports); - else + if (port->state == PORT_CREATED) { + ports = scan_port_open (midi, ports); + } else { ports = &port->next; + } } } static void scan_device(scan_t *scan); static -void scan_card(scan_t *scan) +void scan_card (scan_t *scan) { int device = -1; int err; - while ((err = snd_ctl_rawmidi_next_device(scan->ctl, &device))>=0 && device >=0) { - snd_rawmidi_info_set_device(scan->info, device); - - snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_INPUT); - snd_rawmidi_info_set_subdevice(scan->info, 0); - if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0) - scan_device(scan); - else if (err != -ENOENT) - alsa_error("scan: snd_ctl_rawmidi_info on device", err); - - snd_rawmidi_info_set_stream(scan->info, SND_RAWMIDI_STREAM_OUTPUT); - snd_rawmidi_info_set_subdevice(scan->info, 0); - if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info))>=0) - scan_device(scan); - else if (err != -ENOENT) - alsa_error("scan: snd_ctl_rawmidi_info on device", err); + while ((err = snd_ctl_rawmidi_next_device (scan->ctl, &device)) >= 0 && device >= 0) { + snd_rawmidi_info_set_device (scan->info, device); + + snd_rawmidi_info_set_stream (scan->info, SND_RAWMIDI_STREAM_INPUT); + snd_rawmidi_info_set_subdevice (scan->info, 0); + if ((err = snd_ctl_rawmidi_info (scan->ctl, scan->info)) >= 0) { + scan_device (scan); + } else if (err != -ENOENT) { + alsa_error ("scan: snd_ctl_rawmidi_info on device", err); + } + + snd_rawmidi_info_set_stream (scan->info, SND_RAWMIDI_STREAM_OUTPUT); + snd_rawmidi_info_set_subdevice (scan->info, 0); + if ((err = snd_ctl_rawmidi_info (scan->ctl, scan->info)) >= 0) { + scan_device (scan); + } else if (err != -ENOENT) { + alsa_error ("scan: snd_ctl_rawmidi_info on device", err); + } } } static void scan_port_update(scan_t *scan); static -void scan_device(scan_t *scan) +void scan_device (scan_t *scan) { int err; int sub, nsubs = 0; - nsubs = snd_rawmidi_info_get_subdevices_count(scan->info); - for (sub=0; sub<nsubs; ++sub) { - snd_rawmidi_info_set_subdevice(scan->info, sub); - if ((err = snd_ctl_rawmidi_info(scan->ctl, scan->info)) < 0) { - alsa_error("scan: snd_ctl_rawmidi_info on subdevice", err); + nsubs = snd_rawmidi_info_get_subdevices_count (scan->info); + + for (sub = 0; sub < nsubs; ++sub) { + snd_rawmidi_info_set_subdevice (scan->info, sub); + if ((err = snd_ctl_rawmidi_info (scan->ctl, scan->info)) < 0) { + alsa_error ("scan: snd_ctl_rawmidi_info on subdevice", err); continue; } - scan_port_update(scan); + scan_port_update (scan); } } static midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list); static -void scan_port_update(scan_t *scan) +void scan_port_update (scan_t *scan) { midi_port_t **list = scan->iterator; alsa_id_t id; - alsa_get_id(&id, scan->info); - while (*list && alsa_id_before(&(*list)->id, &id)) - list = scan_port_del(scan->midi, list); + alsa_get_id (&id, scan->info); - if (!*list || alsa_id_before(&id, &(*list)->id)) - list = scan_port_add(scan, &id, list); - else if (*list) + while (*list && alsa_id_before (&(*list)->id, &id)) + list = scan_port_del (scan->midi, list); + + if (!*list || alsa_id_before (&id, &(*list)->id)) { + list = scan_port_add (scan, &id, list); + } else if (*list) { list = &(*list)->next; + } scan->iterator = list; } static -midi_port_t** scan_port_add(scan_t *scan, const alsa_id_t *id, midi_port_t **list) +midi_port_t** scan_port_add (scan_t *scan, const alsa_id_t *id, midi_port_t **list) { midi_port_t *port; midi_stream_t *str = id->id[2] ? &scan->midi->out : &scan->midi->in; - port = calloc(1, str->port_size); - if (!port) + port = calloc (1, str->port_size); + if (!port) { return list; - midi_port_init(scan->midi, port, scan->info, id); + } + midi_port_init (scan->midi, port, scan->info, id); port->next = *list; *list = port; - error_log("scan: added port %s %s", port->dev, port->name); + error_log ("scan: added port %s %s", port->dev, port->name); return &port->next; } static -midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list) +midi_port_t** scan_port_open (alsa_rawmidi_t *midi, midi_port_t **list) { midi_stream_t *str; midi_port_t *port; @@ -683,43 +713,48 @@ midi_port_t** scan_port_open(alsa_rawmidi_t *midi, midi_port_t **list) port = *list; str = port->id.id[2] ? &midi->out : &midi->in; - if (jack_ringbuffer_write_space(str->jack.new_ports) < sizeof(port)) + if (jack_ringbuffer_write_space (str->jack.new_ports) < sizeof(port)) { goto fail_0; + } - if (midi_port_open(midi, port)) + if (midi_port_open (midi, port)) { goto fail_1; - if ((str->port_init)(midi, port)) + } + if ((str->port_init)(midi, port)) { goto fail_2; + } port->state = PORT_ADDED_TO_JACK; - jack_ringbuffer_write(str->jack.new_ports, (char*) &port, sizeof(port)); + jack_ringbuffer_write (str->jack.new_ports, (char*)&port, sizeof(port)); - error_log("scan: opened port %s %s", port->dev, port->name); + error_log ("scan: opened port %s %s", port->dev, port->name); return &port->next; - fail_2: - (str->port_close)(midi, port); - fail_1: - midi_port_close(midi, port); +fail_2: + (str->port_close)(midi, port); +fail_1: + midi_port_close (midi, port); port->state = PORT_ZOMBIFIED; - fail_0: - error_log("scan: can't open port %s %s", port->dev, port->name); +fail_0: + error_log ("scan: can't open port %s %s", port->dev, port->name); return &port->next; } static -midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list) +midi_port_t** scan_port_del (alsa_rawmidi_t *midi, midi_port_t **list) { midi_port_t *port = *list; + if (port->state == PORT_REMOVED_FROM_JACK) { - error_log("scan: deleted port %s %s", port->dev, port->name); + error_log ("scan: deleted port %s %s", port->dev, port->name); *list = port->next; - if (port->id.id[2] ) + if (port->id.id[2] ) { (midi->out.port_close)(midi, port); - else + } else { (midi->in.port_close)(midi, port); - midi_port_close(midi, port); - free(port); + } + midi_port_close (midi, port); + free (port); return list; } else { //debug_log("can't delete port %s, wrong state: %d", port->name, (int)port->state); @@ -727,111 +762,117 @@ midi_port_t** scan_port_del(alsa_rawmidi_t *midi, midi_port_t **list) } } -void* scan_thread(void *arg) +void* scan_thread (void *arg) { alsa_rawmidi_t *midi = arg; struct pollfd wakeup; wakeup.fd = midi->scan.wake_pipe[0]; - wakeup.events = POLLIN|POLLERR|POLLNVAL; + wakeup.events = POLLIN | POLLERR | POLLNVAL; while (midi->keep_walking) { int res; //error_log("scanning...."); - scan_cycle(midi); - res = poll(&wakeup, 1, 2000); - if (res>0) { + scan_cycle (midi); + res = poll (&wakeup, 1, 2000); + if (res > 0) { char c; - read(wakeup.fd, &c, 1); - } else if (res<0 && errno != EINTR) + read (wakeup.fd, &c, 1); + } else if (res < 0 && errno != EINTR) { break; + } } return NULL; } -/* +/* * ------------------------------- Input/Output ------------------------------ */ static -void jack_add_ports(midi_stream_t *str) +void jack_add_ports (midi_stream_t *str) { midi_port_t *port; - while (can_pass(sizeof(port), str->jack.new_ports, str->midi.new_ports) && str->jack.nports < MAX_PORTS) { - jack_ringbuffer_read(str->jack.new_ports, (char*)&port, sizeof(port)); + + while (can_pass (sizeof(port), str->jack.new_ports, str->midi.new_ports) && str->jack.nports < MAX_PORTS) { + jack_ringbuffer_read (str->jack.new_ports, (char*)&port, sizeof(port)); str->jack.ports[str->jack.nports++] = port; port->state = PORT_ADDED_TO_MIDI; - jack_ringbuffer_write(str->midi.new_ports, (char*)&port, sizeof(port)); + jack_ringbuffer_write (str->midi.new_ports, (char*)&port, sizeof(port)); } } static -void jack_process(midi_stream_t *str, jack_nframes_t nframes) +void jack_process (midi_stream_t *str, jack_nframes_t nframes) { int r, w; process_jack_t proc; jack_nframes_t cur_frames; - if (!str->owner->keep_walking) + if (!str->owner->keep_walking) { return; + } proc.midi = str->owner; proc.nframes = nframes; - proc.frame_time = jack_last_frame_time(proc.midi->client); - cur_frames = jack_frame_time(proc.midi->client); + proc.frame_time = jack_last_frame_time (proc.midi->client); + cur_frames = jack_frame_time (proc.midi->client); if (proc.frame_time + proc.nframes < cur_frames) { int periods_lost = (cur_frames - proc.frame_time) / proc.nframes; proc.frame_time += periods_lost * proc.nframes; - debug_log("xrun detected: %d periods lost", periods_lost); + debug_log ("xrun detected: %d periods lost", periods_lost); } // process existing ports - for (r=0, w=0; r<str->jack.nports; ++r) { + for (r = 0, w = 0; r < str->jack.nports; ++r) { midi_port_t *port = str->jack.ports[r]; proc.port = port; assert (port->state > PORT_ADDED_TO_JACK && port->state < PORT_REMOVED_FROM_JACK); - proc.buffer = jack_port_get_buffer(port->jack, nframes); - if (str->mode == POLLIN) - jack_midi_clear_buffer(proc.buffer); + proc.buffer = jack_port_get_buffer (port->jack, nframes); + if (str->mode == POLLIN) { + jack_midi_clear_buffer (proc.buffer); + } if (port->state == PORT_REMOVED_FROM_MIDI) { - port->state = PORT_REMOVED_FROM_JACK; // this signals to scan thread - continue; // this effectively removes port from the midi->in.jack.ports[] + port->state = PORT_REMOVED_FROM_JACK; // this signals to scan thread + continue; // this effectively removes port from the midi->in.jack.ports[] } (str->process_jack)(&proc); - if (r != w) + if (r != w) { str->jack.ports[w] = port; + } ++w; } - if (str->jack.nports != w) - debug_log("jack_%s: nports %d -> %d", str->name, str->jack.nports, w); + if (str->jack.nports != w) { + debug_log ("jack_%s: nports %d -> %d", str->name, str->jack.nports, w); + } str->jack.nports = w; - jack_add_ports(str); // it makes no sense to add them earlier since they have no data yet + jack_add_ports (str); // it makes no sense to add them earlier since they have no data yet // wake midi thread - write(str->wake_pipe[1], &r, 1); + write (str->wake_pipe[1], &r, 1); } static -void *midi_thread(void *arg) +void *midi_thread (void *arg) { midi_stream_t *str = arg; alsa_rawmidi_t *midi = str->owner; struct pollfd pfds[MAX_PFDS]; int npfds; - jack_time_t wait_nsec = 1000*1000*1000; // 1 sec + jack_time_t wait_nsec = 1000 * 1000 * 1000; // 1 sec process_midi_t proc; proc.midi = midi; proc.mode = str->mode; pfds[0].fd = str->wake_pipe[0]; - pfds[0].events = POLLIN|POLLERR|POLLNVAL; + pfds[0].events = POLLIN | POLLERR | POLLNVAL; npfds = 1; //debug_log("midi_thread(%s): enter", str->name); @@ -839,47 +880,50 @@ void *midi_thread(void *arg) while (midi->keep_walking) { int poll_timeout; int wait_nanosleep; - int r=1, w=1; // read,write pos in pfds - int rp=0, wp=0; // read, write pos in ports + int r = 1, w = 1; // read,write pos in pfds + int rp = 0, wp = 0; // read, write pos in ports // sleep //if (wait_nsec != 1000*1000*1000) { // debug_log("midi_thread(%s): ", str->name); // assert (wait_nsec == 1000*1000*1000); //} - poll_timeout = wait_nsec / (1000*1000); - wait_nanosleep = wait_nsec % (1000*1000); + poll_timeout = wait_nsec / (1000 * 1000); + wait_nanosleep = wait_nsec % (1000 * 1000); if (wait_nanosleep > NANOSLEEP_RESOLUTION) { struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = wait_nanosleep; - clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL); + clock_nanosleep (CLOCK_MONOTONIC, 0, &ts, NULL); } - int res = poll((struct pollfd*)&pfds, npfds, poll_timeout); + int res = poll ((struct pollfd*)&pfds, npfds, poll_timeout); //debug_log("midi_thread(%s): poll exit: %d", str->name, res); - if (!midi->keep_walking) + if (!midi->keep_walking) { break; + } if (res < 0) { - if (errno == EINTR) + if (errno == EINTR) { continue; - error_log("midi_thread(%s) poll failed: %s", str->name, strerror(errno)); + } + error_log ("midi_thread(%s) poll failed: %s", str->name, strerror (errno)); break; } // check wakeup pipe - if (pfds[0].revents & ~POLLIN) + if (pfds[0].revents & ~POLLIN) { break; + } if (pfds[0].revents & POLLIN) { char c; - read(pfds[0].fd, &c, 1); + read (pfds[0].fd, &c, 1); } // add new ports - while (jack_ringbuffer_read_space(str->midi.new_ports) >= sizeof(midi_port_t*) && str->midi.nports < MAX_PORTS) { + while (jack_ringbuffer_read_space (str->midi.new_ports) >= sizeof(midi_port_t*) && str->midi.nports < MAX_PORTS) { midi_port_t *port; - jack_ringbuffer_read(str->midi.new_ports, (char*)&port, sizeof(port)); + jack_ringbuffer_read (str->midi.new_ports, (char*)&port, sizeof(port)); str->midi.ports[str->midi.nports++] = port; - debug_log("midi_thread(%s): added port %s", str->name, port->name); + debug_log ("midi_thread(%s): added port %s", str->name, port->name); } // if (res == 0) @@ -891,26 +935,29 @@ void *midi_thread(void *arg) for (rp = 0; rp < str->midi.nports; ++rp) { midi_port_t *port = str->midi.ports[rp]; - proc.cur_time = jack_frame_time(midi->client); + proc.cur_time = jack_frame_time (midi->client); proc.port = port; proc.rpfds = &pfds[r]; proc.wpfds = &pfds[w]; proc.max_pfds = MAX_PFDS - w; r += port->npfds; if (!(str->process_midi)(&proc)) { - port->state = PORT_REMOVED_FROM_MIDI; // this signals to jack thread - continue; // this effectively removes port from array + port->state = PORT_REMOVED_FROM_MIDI; // this signals to jack thread + continue; // this effectively removes port from array } w += port->npfds; - if (rp != wp) + if (rp != wp) { str->midi.ports[wp] = port; + } ++wp; } - if (str->midi.nports != wp) - debug_log("midi_%s: nports %d -> %d", str->name, str->midi.nports, wp); + if (str->midi.nports != wp) { + debug_log ("midi_%s: nports %d -> %d", str->name, str->midi.nports, wp); + } str->midi.nports = wp; - if (npfds != w) - debug_log("midi_%s: npfds %d -> %d", str->name, npfds, w); + if (npfds != w) { + debug_log ("midi_%s: npfds %d -> %d", str->name, npfds, w); + } npfds = w; /* @@ -919,75 +966,79 @@ void *midi_thread(void *arg) * So, zero timeout will not cause busy-looping. */ if (proc.next_time < proc.cur_time) { - debug_log("%s: late: next_time = %d, cur_time = %d", str->name, (int)proc.next_time, (int)proc.cur_time); + debug_log ("%s: late: next_time = %d, cur_time = %d", str->name, (int)proc.next_time, (int)proc.cur_time); wait_nsec = 0; // we are late } else if (proc.next_time != NFRAMES_INF) { jack_time_t wait_frames = proc.next_time - proc.cur_time; - jack_nframes_t rate = jack_get_sample_rate(midi->client); - wait_nsec = (wait_frames * (1000*1000*1000)) / rate; - debug_log("midi_%s: timeout = %d", str->name, (int)wait_frames); - } else - wait_nsec = 1000*1000*1000; + jack_nframes_t rate = jack_get_sample_rate (midi->client); + wait_nsec = (wait_frames * (1000 * 1000 * 1000)) / rate; + debug_log ("midi_%s: timeout = %d", str->name, (int)wait_frames); + } else { + wait_nsec = 1000 * 1000 * 1000; + } //debug_log("midi_thread(%s): wait_nsec = %lld", str->name, wait_nsec); } return NULL; } static -int midi_is_ready(process_midi_t *proc) +int midi_is_ready (process_midi_t *proc) { midi_port_t *port = proc->port; + if (port->npfds) { unsigned short revents = 0; - int res = snd_rawmidi_poll_descriptors_revents(port->rawmidi, proc->rpfds, port->npfds, &revents); + int res = snd_rawmidi_poll_descriptors_revents (port->rawmidi, proc->rpfds, port->npfds, &revents); if (res) { - error_log("snd_rawmidi_poll_descriptors_revents failed on port %s with: %s", port->name, snd_strerror(res)); + error_log ("snd_rawmidi_poll_descriptors_revents failed on port %s with: %s", port->name, snd_strerror (res)); return 0; } if (revents & ~proc->mode) { - debug_log("midi: port %s failed", port->name); + debug_log ("midi: port %s failed", port->name); return 0; } if (revents & proc->mode) { port->is_ready = 1; - debug_log("midi: is_ready %s", port->name); + debug_log ("midi: is_ready %s", port->name); } } return 1; } static -int midi_update_pfds(process_midi_t *proc) +int midi_update_pfds (process_midi_t *proc) { midi_port_t *port = proc->port; + if (port->npfds == 0) { - port->npfds = snd_rawmidi_poll_descriptors_count(port->rawmidi); + port->npfds = snd_rawmidi_poll_descriptors_count (port->rawmidi); if (port->npfds > proc->max_pfds) { - debug_log("midi: not enough pfds for port %s", port->name); + debug_log ("midi: not enough pfds for port %s", port->name); return 0; } - snd_rawmidi_poll_descriptors(port->rawmidi, proc->wpfds, port->npfds); + snd_rawmidi_poll_descriptors (port->rawmidi, proc->wpfds, port->npfds); } else if (proc->rpfds != proc->wpfds) { - memmove(proc->wpfds, proc->rpfds, sizeof(struct pollfd) * port->npfds); + memmove (proc->wpfds, proc->rpfds, sizeof(struct pollfd) * port->npfds); } return 1; } -/* +/* * ------------------------------------ Input ------------------------------ */ static -int input_port_init(alsa_rawmidi_t *midi, midi_port_t *port) +int input_port_init (alsa_rawmidi_t *midi, midi_port_t *port) { input_port_t *in = (input_port_t*)port; - midi_unpack_init(&in->unpack); + + midi_unpack_init (&in->unpack); return 0; } static -void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port) +void input_port_close (alsa_rawmidi_t *midi, midi_port_t *port) { } @@ -996,41 +1047,44 @@ void input_port_close(alsa_rawmidi_t *midi, midi_port_t *port) */ static -void do_jack_input(process_jack_t *p) +void do_jack_input (process_jack_t *p) { - input_port_t *port = (input_port_t*) p->port; + input_port_t *port = (input_port_t*)p->port; event_head_t event; - while (jack_ringbuffer_read_space(port->base.event_ring) >= sizeof(event)) { + + while (jack_ringbuffer_read_space (port->base.event_ring) >= sizeof(event)) { jack_ringbuffer_data_t vec[2]; jack_nframes_t time; int i, todo; - jack_ringbuffer_read(port->base.event_ring, (char*)&event, sizeof(event)); + jack_ringbuffer_read (port->base.event_ring, (char*)&event, sizeof(event)); // TODO: take into account possible warping - if ((event.time + p->nframes) < p->frame_time) + if ((event.time + p->nframes) < p->frame_time) { time = 0; - else if (event.time >= p->frame_time) - time = p->nframes -1; - else + } else if (event.time >= p->frame_time) { + time = p->nframes - 1; + } else { time = event.time + p->nframes - p->frame_time; + } - jack_ringbuffer_get_read_vector(port->base.data_ring, vec); + jack_ringbuffer_get_read_vector (port->base.data_ring, vec); assert ((vec[0].len + vec[1].len) >= event.size); - if (event.overruns) - midi_unpack_reset(&port->unpack); + if (event.overruns) { + midi_unpack_reset (&port->unpack); + } todo = event.size; - for (i=0; i<2 && todo>0; ++i) { + for (i = 0; i < 2 && todo > 0; ++i) { int avail = todo < vec[i].len ? todo : vec[i].len; - int done = midi_unpack_buf(&port->unpack, (unsigned char*)vec[i].buf, avail, p->buffer, time); + int done = midi_unpack_buf (&port->unpack, (unsigned char*)vec[i].buf, avail, p->buffer, time); if (done != avail) { - debug_log("jack_in: buffer overflow in port %s", port->base.name); + debug_log ("jack_in: buffer overflow in port %s", port->base.name); break; } todo -= done; } - jack_ringbuffer_read_advance(port->base.data_ring, event.size); + jack_ringbuffer_read_advance (port->base.data_ring, event.size); } } @@ -1038,28 +1092,31 @@ void do_jack_input(process_jack_t *p) * Low level input. */ static -int do_midi_input(process_midi_t *proc) +int do_midi_input (process_midi_t *proc) { - input_port_t *port = (input_port_t*) proc->port; - if (!midi_is_ready(proc)) + input_port_t *port = (input_port_t*)proc->port; + + if (!midi_is_ready (proc)) { return 0; + } if (port->base.is_ready) { jack_ringbuffer_data_t vec[2]; int res; - jack_ringbuffer_get_write_vector(port->base.data_ring, vec); - if (jack_ringbuffer_write_space(port->base.event_ring) < sizeof(event_head_t) || vec[0].len < 1) { + jack_ringbuffer_get_write_vector (port->base.data_ring, vec); + if (jack_ringbuffer_write_space (port->base.event_ring) < sizeof(event_head_t) || vec[0].len < 1) { port->overruns++; - if (port->base.npfds) - debug_log("midi_in: internal overflow on %s", port->base.name); + if (port->base.npfds) { + debug_log ("midi_in: internal overflow on %s", port->base.name); + } // remove from poll to prevent busy-looping port->base.npfds = 0; return 1; } - res = snd_rawmidi_read(port->base.rawmidi, vec[0].buf, vec[0].len); + res = snd_rawmidi_read (port->base.rawmidi, vec[0].buf, vec[0].len); if (res < 0 && res != -EWOULDBLOCK) { - error_log("midi_in: reading from port %s failed: %s", port->base.name, snd_strerror(res)); + error_log ("midi_in: reading from port %s failed: %s", port->base.name, snd_strerror (res)); return 0; } else if (res > 0) { event_head_t event; @@ -1067,94 +1124,101 @@ int do_midi_input(process_midi_t *proc) event.size = res; event.overruns = port->overruns; port->overruns = 0; - debug_log("midi_in: read %d bytes at %d", (int)event.size, (int)event.time); - jack_ringbuffer_write_advance(port->base.data_ring, event.size); - jack_ringbuffer_write(port->base.event_ring, (char*)&event, sizeof(event)); + debug_log ("midi_in: read %d bytes at %d", (int)event.size, (int)event.time); + jack_ringbuffer_write_advance (port->base.data_ring, event.size); + jack_ringbuffer_write (port->base.event_ring, (char*)&event, sizeof(event)); } port->base.is_ready = 0; } - if (!midi_update_pfds(proc)) + if (!midi_update_pfds (proc)) { return 0; + } return 1; } -/* +/* * ------------------------------------ Output ------------------------------ */ -static int output_port_init(alsa_rawmidi_t *midi, midi_port_t *port) +static int output_port_init (alsa_rawmidi_t *midi, midi_port_t *port) { output_port_t *out = (output_port_t*)port; - midi_pack_reset(&out->packer); + + midi_pack_reset (&out->packer); out->next_event.time = 0; out->next_event.size = 0; out->todo = 0; return 0; } -static void output_port_close(alsa_rawmidi_t *midi, midi_port_t *port) +static void output_port_close (alsa_rawmidi_t *midi, midi_port_t *port) { } static -void do_jack_output(process_jack_t *proc) +void do_jack_output (process_jack_t *proc) { - output_port_t *port = (output_port_t*) proc->port; - int nevents = jack_midi_get_event_count(proc->buffer); + output_port_t *port = (output_port_t*)proc->port; + int nevents = jack_midi_get_event_count (proc->buffer); int i; - if (nevents) - debug_log("jack_out: %d events in %s", nevents, port->base.name); - for (i=0; i<nevents; ++i) { + + if (nevents) { + debug_log ("jack_out: %d events in %s", nevents, port->base.name); + } + for (i = 0; i < nevents; ++i) { jack_midi_event_t event; event_head_t hdr; - jack_midi_event_get(&event, proc->buffer, i); + jack_midi_event_get (&event, proc->buffer, i); - if (jack_ringbuffer_write_space(port->base.data_ring) < event.size || jack_ringbuffer_write_space(port->base.event_ring) < sizeof(hdr)) { - debug_log("jack_out: output buffer overflow on %s", port->base.name); + if (jack_ringbuffer_write_space (port->base.data_ring) < event.size || jack_ringbuffer_write_space (port->base.event_ring) < sizeof(hdr)) { + debug_log ("jack_out: output buffer overflow on %s", port->base.name); break; } - midi_pack_event(&port->packer, &event); + midi_pack_event (&port->packer, &event); - jack_ringbuffer_write(port->base.data_ring, (char*)event.buffer, event.size); + jack_ringbuffer_write (port->base.data_ring, (char*)event.buffer, event.size); hdr.time = proc->frame_time + event.time + proc->nframes; hdr.size = event.size; - jack_ringbuffer_write(port->base.event_ring, (char*)&hdr, sizeof(hdr)); - debug_log("jack_out: sent %d-byte event at %ld", (int)event.size, (long)event.time); + jack_ringbuffer_write (port->base.event_ring, (char*)&hdr, sizeof(hdr)); + debug_log ("jack_out: sent %d-byte event at %ld", (int)event.size, (long)event.time); } } static -int do_midi_output(process_midi_t *proc) +int do_midi_output (process_midi_t *proc) { int worked = 0; - output_port_t *port = (output_port_t*) proc->port; + output_port_t *port = (output_port_t*)proc->port; - if (!midi_is_ready(proc)) + if (!midi_is_ready (proc)) { return 0; + } // eat events while (port->next_event.time <= proc->cur_time) { port->todo += port->next_event.size; - if (jack_ringbuffer_read(port->base.event_ring, (char*)&port->next_event, sizeof(port->next_event))!=sizeof(port->next_event)) { + if (jack_ringbuffer_read (port->base.event_ring, (char*)&port->next_event, sizeof(port->next_event)) != sizeof(port->next_event)) { port->next_event.time = 0; port->next_event.size = 0; break; - } else - 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); + } else { + 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); + } + } + + if (port->todo) { + debug_log ("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time); } - - if (port->todo) - debug_log("midi_out: todo = %d at %ld", (int)port->todo, (long)proc->cur_time); // calc next wakeup time if (!port->todo && port->next_event.time && port->next_event.time < proc->next_time) { proc->next_time = port->next_event.time; - debug_log("midi_out: next_time = %ld", (long)proc->next_time); + debug_log ("midi_out: next_time = %ld", (long)proc->next_time); } if (port->todo && port->base.is_ready) { @@ -1163,41 +1227,43 @@ int do_midi_output(process_midi_t *proc) int res; jack_ringbuffer_data_t vec[2]; - jack_ringbuffer_get_read_vector(port->base.data_ring, vec); + jack_ringbuffer_get_read_vector (port->base.data_ring, vec); if (size > vec[0].len) { size = vec[0].len; assert (size > 0); } - res = snd_rawmidi_write(port->base.rawmidi, vec[0].buf, size); + res = snd_rawmidi_write (port->base.rawmidi, vec[0].buf, size); if (res > 0) { - jack_ringbuffer_read_advance(port->base.data_ring, res); - debug_log("midi_out: written %d bytes to %s", res, port->base.name); + jack_ringbuffer_read_advance (port->base.data_ring, res); + debug_log ("midi_out: written %d bytes to %s", res, port->base.name); port->todo -= res; worked = 1; } else if (res == -EWOULDBLOCK) { port->base.is_ready = 0; - debug_log("midi_out: -EWOULDBLOCK on %s", port->base.name); + debug_log ("midi_out: -EWOULDBLOCK on %s", port->base.name); return 1; } else { - error_log("midi_out: writing to port %s failed: %s", port->base.name, snd_strerror(res)); + error_log ("midi_out: writing to port %s failed: %s", port->base.name, snd_strerror (res)); return 0; } - snd_rawmidi_drain(port->base.rawmidi); + snd_rawmidi_drain (port->base.rawmidi); } // update pfds for this port - if (!midi_update_pfds(proc)) + if (!midi_update_pfds (proc)) { return 0; + } if (!port->todo) { int i; - if (worked) - debug_log("midi_out: relaxing on %s", port->base.name); - for (i=0; i<port->base.npfds; ++i) + if (worked) { + debug_log ("midi_out: relaxing on %s", port->base.name); + } + for (i = 0; i < port->base.npfds; ++i) proc->wpfds[i].events &= ~POLLOUT; } else { int i; - for (i=0; i<port->base.npfds; ++i) + for (i = 0; i < port->base.npfds; ++i) proc->wpfds[i].events |= POLLOUT; } return 1; diff --git a/drivers/am/alsa_seqmidi.c b/drivers/am/alsa_seqmidi.c index 3351b36..58db4b2 100644 --- a/drivers/am/alsa_seqmidi.c +++ b/drivers/am/alsa_seqmidi.c @@ -21,21 +21,21 @@ /* * alsa_seqmidi_read: * add new ports - * reads queued snd_seq_event's - * if PORT_EXIT: mark port as dead - * if PORT_ADD, PORT_CHANGE: send addr to port_thread (it also may mark port as dead) - * else process input event - * remove dead ports and send them to port_thread + * reads queued snd_seq_event's + * if PORT_EXIT: mark port as dead + * if PORT_ADD, PORT_CHANGE: send addr to port_thread (it also may mark port as dead) + * else process input event + * remove dead ports and send them to port_thread * * alsa_seqmidi_write: - * remove dead ports and send them to port_thread - * add new ports - * queue output events + * remove dead ports and send them to port_thread + * add new ports + * queue output events * * port_thread: - * wait for port_sem - * free deleted ports - * create new ports or mark existing as dead + * wait for port_sem + * free deleted ports + * create new ports or mark existing as dead */ #include <alsa/asoundlib.h> #include <jack/jack.h> @@ -52,29 +52,29 @@ #include "alsa_midi.h" #ifndef SND_SEQ_PORT_TYPE_PORT -#define SND_SEQ_PORT_TYPE_PORT (1<<19) /* Appears in version 1.0.12rc1 */ +#define SND_SEQ_PORT_TYPE_PORT (1 << 19) /* Appears in version 1.0.12rc1 */ #endif #ifndef SND_SEQ_PORT_TYPE_HARDWARE -#define SND_SEQ_PORT_TYPE_HARDWARE (1<<16) /* Appears in version 1.0.12rc1 */ +#define SND_SEQ_PORT_TYPE_HARDWARE (1 << 16) /* Appears in version 1.0.12rc1 */ #endif #ifdef STANDALONE -#define MESSAGE(...) fprintf(stderr, __VA_ARGS__) +#define MESSAGE(...) fprintf (stderr, __VA_ARGS__) #else #include "messagebuffer.h" #endif -#define info_log(...) MESSAGE(__VA_ARGS__) -#define error_log(...) MESSAGE(__VA_ARGS__) +#define info_log(...) MESSAGE (__VA_ARGS__) +#define error_log(...) MESSAGE (__VA_ARGS__) #ifdef JACK_MIDI_DEBUG -#define debug_log(...) MESSAGE(__VA_ARGS__) +#define debug_log(...) MESSAGE (__VA_ARGS__) #else #define debug_log(...) #endif -#define NSEC_PER_SEC ((int64_t)1000*1000*1000) +#define NSEC_PER_SEC ((int64_t)1000 * 1000 * 1000) enum { MAX_PORTS = 64, @@ -124,8 +124,8 @@ typedef struct alsa_seqmidi { pthread_t port_thread; sem_t port_sem; - jack_ringbuffer_t *port_add; // snd_seq_addr_t - jack_ringbuffer_t *port_del; // port_t* + jack_ringbuffer_t *port_add; // snd_seq_addr_t + jack_ringbuffer_t *port_del; // port_t* stream_t stream[2]; @@ -150,7 +150,7 @@ struct process_info { enum PortType { PORT_INPUT = 0, PORT_OUTPUT = 1 }; -typedef void (*port_jack_func)(alsa_seqmidi_t *self, port_t *port,struct process_info* info); +typedef void (*port_jack_func)(alsa_seqmidi_t *self, port_t *port, struct process_info* info); static void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info* info); static void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info); @@ -186,36 +186,36 @@ static void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes); static void alsa_seqmidi_write(alsa_midi_t *m, jack_nframes_t nframes); static -void stream_init(alsa_seqmidi_t *self, int dir) +void stream_init (alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; - str->new_ports = jack_ringbuffer_create(MAX_PORTS*sizeof(port_t*)); - snd_midi_event_new(MAX_EVENT_SIZE, &str->codec); + str->new_ports = jack_ringbuffer_create (MAX_PORTS * sizeof(port_t*)); + snd_midi_event_new (MAX_EVENT_SIZE, &str->codec); } static void port_free(alsa_seqmidi_t *self, port_t *port); static void free_ports(alsa_seqmidi_t *self, jack_ringbuffer_t *ports); static -void stream_attach(alsa_seqmidi_t *self, int dir) +void stream_attach (alsa_seqmidi_t *self, int dir) { } static -void stream_detach(alsa_seqmidi_t *self, int dir) +void stream_detach (alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; int i; - free_ports(self, str->new_ports); + free_ports (self, str->new_ports); // delete all ports from hash - for (i=0; i<PORT_HASH_SIZE; ++i) { + for (i = 0; i < PORT_HASH_SIZE; ++i) { port_t *port = str->ports[i]; while (port) { port_t *next = port->next; - port_free(self, port); + port_free (self, port); port = next; } str->ports[i] = NULL; @@ -223,33 +223,38 @@ void stream_detach(alsa_seqmidi_t *self, int dir) } static -void stream_close(alsa_seqmidi_t *self, int dir) +void stream_close (alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; - if (str->codec) - snd_midi_event_free(str->codec); - if (str->new_ports) - jack_ringbuffer_free(str->new_ports); + if (str->codec) { + snd_midi_event_free (str->codec); + } + if (str->new_ports) { + jack_ringbuffer_free (str->new_ports); + } } -alsa_midi_t* alsa_seqmidi_new(jack_client_t *client, const char* alsa_name) +alsa_midi_t* alsa_seqmidi_new (jack_client_t *client, const char* alsa_name) { - alsa_seqmidi_t *self = calloc(1, sizeof(alsa_seqmidi_t)); - debug_log("midi: new\n"); - if (!self) + alsa_seqmidi_t *self = calloc (1, sizeof(alsa_seqmidi_t)); + + debug_log ("midi: new\n"); + if (!self) { return NULL; + } self->jack = client; - if (!alsa_name) + if (!alsa_name) { alsa_name = "jack_midi"; - snprintf(self->alsa_name, sizeof(self->alsa_name), "%s", alsa_name); + } + snprintf (self->alsa_name, sizeof(self->alsa_name), "%s", alsa_name); - self->port_add = jack_ringbuffer_create(2*MAX_PORTS*sizeof(snd_seq_addr_t)); - self->port_del = jack_ringbuffer_create(2*MAX_PORTS*sizeof(port_t*)); - sem_init(&self->port_sem, 0, 0); + self->port_add = jack_ringbuffer_create (2 * MAX_PORTS * sizeof(snd_seq_addr_t)); + self->port_del = jack_ringbuffer_create (2 * MAX_PORTS * sizeof(port_t*)); + sem_init (&self->port_sem, 0, 0); - stream_init(self, PORT_INPUT); - stream_init(self, PORT_OUTPUT); + stream_init (self, PORT_INPUT); + stream_init (self, PORT_OUTPUT); self->ops.destroy = alsa_seqmidi_delete; self->ops.attach = alsa_seqmidi_attach; @@ -262,77 +267,79 @@ alsa_midi_t* alsa_seqmidi_new(jack_client_t *client, const char* alsa_name) } static -void alsa_seqmidi_delete(alsa_midi_t *m) +void alsa_seqmidi_delete (alsa_midi_t *m) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; - debug_log("midi: delete\n"); - alsa_seqmidi_detach(m); + debug_log ("midi: delete\n"); + alsa_seqmidi_detach (m); - stream_close(self, PORT_OUTPUT); - stream_close(self, PORT_INPUT); + stream_close (self, PORT_OUTPUT); + stream_close (self, PORT_INPUT); - jack_ringbuffer_free(self->port_add); - jack_ringbuffer_free(self->port_del); - sem_close(&self->port_sem); + jack_ringbuffer_free (self->port_add); + jack_ringbuffer_free (self->port_del); + sem_close (&self->port_sem); - free(self); + free (self); } static -int alsa_seqmidi_attach(alsa_midi_t *m) +int alsa_seqmidi_attach (alsa_midi_t *m) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; int err; - debug_log("midi: attach\n"); + debug_log ("midi: attach\n"); - if (self->seq) + if (self->seq) { return -EALREADY; + } - if ((err = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) { - error_log("failed to open alsa seq"); + if ((err = snd_seq_open (&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) { + error_log ("failed to open alsa seq"); return err; } - snd_seq_set_client_name(self->seq, self->alsa_name); - self->port_id = snd_seq_create_simple_port(self->seq, "port", - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE + snd_seq_set_client_name (self->seq, self->alsa_name); + self->port_id = snd_seq_create_simple_port (self->seq, "port", + SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_WRITE #ifndef JACK_MIDI_DEBUG - |SND_SEQ_PORT_CAP_NO_EXPORT + | SND_SEQ_PORT_CAP_NO_EXPORT #endif - ,SND_SEQ_PORT_TYPE_APPLICATION); - self->client_id = snd_seq_client_id(self->seq); + , SND_SEQ_PORT_TYPE_APPLICATION); + self->client_id = snd_seq_client_id (self->seq); - self->queue = snd_seq_alloc_queue(self->seq); - snd_seq_start_queue(self->seq, self->queue, 0); + self->queue = snd_seq_alloc_queue (self->seq); + snd_seq_start_queue (self->seq, self->queue, 0); - stream_attach(self, PORT_INPUT); - stream_attach(self, PORT_OUTPUT); + stream_attach (self, PORT_INPUT); + stream_attach (self, PORT_OUTPUT); - snd_seq_nonblock(self->seq, 1); + snd_seq_nonblock (self->seq, 1); return 0; } static -int alsa_seqmidi_detach(alsa_midi_t *m) +int alsa_seqmidi_detach (alsa_midi_t *m) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; - debug_log("midi: detach\n"); + debug_log ("midi: detach\n"); - if (!self->seq) + if (!self->seq) { return -EALREADY; + } - alsa_seqmidi_stop(m); + alsa_seqmidi_stop (m); - jack_ringbuffer_reset(self->port_add); - free_ports(self, self->port_del); + jack_ringbuffer_reset (self->port_add); + free_ports (self, self->port_del); - stream_detach(self, PORT_INPUT); - stream_detach(self, PORT_OUTPUT); + stream_detach (self, PORT_INPUT); + stream_detach (self, PORT_OUTPUT); - snd_seq_close(self->seq); + snd_seq_close (self->seq); self->seq = NULL; return 0; @@ -345,30 +352,32 @@ static void update_ports(alsa_seqmidi_t *self); static void add_ports(stream_t *str); static -int alsa_seqmidi_start(alsa_midi_t *m) +int alsa_seqmidi_start (alsa_midi_t *m) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; int err; - debug_log("midi: start\n"); + debug_log ("midi: start\n"); - if (!self->seq) + if (!self->seq) { return -EBADF; + } - if (self->keep_walking) + if (self->keep_walking) { return -EALREADY; + } - snd_seq_connect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); - snd_seq_drop_input(self->seq); + snd_seq_connect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); + snd_seq_drop_input (self->seq); - add_existing_ports(self); - update_ports(self); - add_ports(&self->stream[PORT_INPUT]); - add_ports(&self->stream[PORT_OUTPUT]); + add_existing_ports (self); + update_ports (self); + add_ports (&self->stream[PORT_INPUT]); + add_ports (&self->stream[PORT_OUTPUT]); self->keep_walking = 1; - if ((err = pthread_create(&self->port_thread, NULL, port_thread, self))) { + if ((err = pthread_create (&self->port_thread, NULL, port_thread, self))) { self->keep_walking = 0; return -errno; } @@ -377,47 +386,49 @@ int alsa_seqmidi_start(alsa_midi_t *m) } static -int alsa_seqmidi_stop(alsa_midi_t *m) +int alsa_seqmidi_stop (alsa_midi_t *m) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; - debug_log("midi: stop\n"); + debug_log ("midi: stop\n"); - if (!self->keep_walking) + if (!self->keep_walking) { return -EALREADY; + } - snd_seq_disconnect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); + snd_seq_disconnect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE); self->keep_walking = 0; - sem_post(&self->port_sem); - pthread_join(self->port_thread, NULL); + sem_post (&self->port_sem); + pthread_join (self->port_thread, NULL); self->port_thread = 0; return 0; } static -int alsa_connect_from(alsa_seqmidi_t *self, int client, int port) +int alsa_connect_from (alsa_seqmidi_t *self, int client, int port) { snd_seq_port_subscribe_t* sub; snd_seq_addr_t seq_addr; int err; - snd_seq_port_subscribe_alloca(&sub); + snd_seq_port_subscribe_alloca (&sub); seq_addr.client = client; seq_addr.port = port; - snd_seq_port_subscribe_set_sender(sub, &seq_addr); + snd_seq_port_subscribe_set_sender (sub, &seq_addr); seq_addr.client = self->client_id; seq_addr.port = self->port_id; - snd_seq_port_subscribe_set_dest(sub, &seq_addr); + snd_seq_port_subscribe_set_dest (sub, &seq_addr); - snd_seq_port_subscribe_set_time_update(sub, 1); - snd_seq_port_subscribe_set_queue(sub, self->queue); - snd_seq_port_subscribe_set_time_real(sub, 1); + snd_seq_port_subscribe_set_time_update (sub, 1); + snd_seq_port_subscribe_set_queue (sub, self->queue); + snd_seq_port_subscribe_set_time_real (sub, 1); - if ((err=snd_seq_subscribe_port(self->seq, sub))) - error_log("can't subscribe to %d:%d - %s\n", client, port, snd_strerror(err)); + if ((err = snd_seq_subscribe_port (self->seq, sub))) { + error_log ("can't subscribe to %d:%d - %s\n", client, port, snd_strerror (err)); + } return err; } @@ -425,58 +436,65 @@ int alsa_connect_from(alsa_seqmidi_t *self, int client, int port) * ==================== Port routines ============================= */ static inline -int port_hash(snd_seq_addr_t addr) +int port_hash (snd_seq_addr_t addr) { return (addr.client + addr.port) % PORT_HASH_SIZE; } static -port_t* port_get(port_hash_t hash, snd_seq_addr_t addr) +port_t* port_get (port_hash_t hash, snd_seq_addr_t addr) { - port_t **pport = &hash[port_hash(addr)]; + port_t **pport = &hash[port_hash (addr)]; + while (*pport) { port_t *port = *pport; - if (port->remote.client == addr.client && port->remote.port == addr.port) + if (port->remote.client == addr.client && port->remote.port == addr.port) { return port; + } pport = &port->next; } return NULL; } static -void port_insert(port_hash_t hash, port_t *port) +void port_insert (port_hash_t hash, port_t *port) { - port_t **pport = &hash[port_hash(port->remote)]; + port_t **pport = &hash[port_hash (port->remote)]; + port->next = *pport; *pport = port; } static -void port_setdead(port_hash_t hash, snd_seq_addr_t addr) +void port_setdead (port_hash_t hash, snd_seq_addr_t addr) { - port_t *port = port_get(hash, addr); - if (port) + port_t *port = port_get (hash, addr); + + if (port) { port->is_dead = 1; // see jack_process - else - debug_log("port_setdead: not found (%d:%d)\n", addr.client, addr.port); + } else { + debug_log ("port_setdead: not found (%d:%d)\n", addr.client, addr.port); + } } static -void port_free(alsa_seqmidi_t *self, port_t *port) +void port_free (alsa_seqmidi_t *self, port_t *port) { //snd_seq_disconnect_from(self->seq, self->port_id, port->remote.client, port->remote.port); //snd_seq_disconnect_to(self->seq, self->port_id, port->remote.client, port->remote.port); - if (port->early_events) - jack_ringbuffer_free(port->early_events); - if (port->jack_port) - jack_port_unregister(self->jack, port->jack_port); + if (port->early_events) { + jack_ringbuffer_free (port->early_events); + } + if (port->jack_port) { + jack_port_unregister (self->jack, port->jack_port); + } // info_log("port deleted: %s\n", port->name); - free(port); + free (port); } static -port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const snd_seq_port_info_t *info) +port_t* port_create (alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const snd_seq_port_info_t *info) { snd_seq_client_info_t* client_info; port_t *port; @@ -484,62 +502,68 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s int err; int jack_caps; - port = calloc(1, sizeof(port_t)); - if (!port) + port = calloc (1, sizeof(port_t)); + if (!port) { return NULL; + } port->remote = addr; snd_seq_client_info_alloca (&client_info); snd_seq_get_any_client_info (self->seq, addr.client, client_info); - snprintf(port->name, sizeof(port->name), "%s/midi_%s_%d", - snd_seq_client_info_get_name(client_info), port_type[type].name, addr.port+1); + snprintf (port->name, sizeof(port->name), "%s/midi_%s_%d", + snd_seq_client_info_get_name (client_info), port_type[type].name, addr.port + 1); // replace all offending characters by - for (c = port->name; *c; ++c) - if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') + if (!isalnum (*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') { *c = '-'; + } jack_caps = port_type[type].jack_caps; /* mark anything that looks like a hardware port as physical&terminal */ - if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE|SND_SEQ_PORT_TYPE_PORT|SND_SEQ_PORT_TYPE_SPECIFIC)) { - jack_caps |= (JackPortIsPhysical|JackPortIsTerminal); + if (snd_seq_port_info_get_type (info) & (SND_SEQ_PORT_TYPE_HARDWARE | SND_SEQ_PORT_TYPE_PORT | SND_SEQ_PORT_TYPE_SPECIFIC)) { + jack_caps |= (JackPortIsPhysical | JackPortIsTerminal); } - - port->jack_port = jack_port_register(self->jack, - port->name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); - if (!port->jack_port) + + port->jack_port = jack_port_register (self->jack, + port->name, JACK_DEFAULT_MIDI_TYPE, jack_caps, 0); + if (!port->jack_port) { goto failed; + } /* generate an alias */ - snprintf(port->name, sizeof(port->name), "%s:midi/%s_%d", - snd_seq_client_info_get_name (client_info), port_type[type].name, addr.port+1); + snprintf (port->name, sizeof(port->name), "%s:midi/%s_%d", + snd_seq_client_info_get_name (client_info), port_type[type].name, addr.port + 1); // replace all offending characters by - for (c = port->name; *c; ++c) - if (!isalnum(*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') + if (!isalnum (*c) && *c != '/' && *c != '_' && *c != ':' && *c != '(' && *c != ')') { *c = '-'; + } jack_port_set_alias (port->jack_port, port->name); - if (type == PORT_INPUT) - err = alsa_connect_from(self, port->remote.client, port->remote.port); - else - err = snd_seq_connect_to(self->seq, self->port_id, port->remote.client, port->remote.port); - if (err) + if (type == PORT_INPUT) { + err = alsa_connect_from (self, port->remote.client, port->remote.port); + } else { + err = snd_seq_connect_to (self->seq, self->port_id, port->remote.client, port->remote.port); + } + if (err) { goto failed; + } - port->early_events = jack_ringbuffer_create(MAX_EVENT_SIZE*16); + port->early_events = jack_ringbuffer_create (MAX_EVENT_SIZE * 16); // info_log("port created: %s\n", port->name); return port; - failed: - port_free(self, port); +failed: + port_free (self, port); return NULL; } @@ -547,65 +571,69 @@ port_t* port_create(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, const s * ==================== Port add/del handling thread ============================== */ static -void update_port_type(alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, int caps, const snd_seq_port_info_t *info) +void update_port_type (alsa_seqmidi_t *self, int type, snd_seq_addr_t addr, int caps, const snd_seq_port_info_t *info) { stream_t *str = &self->stream[type]; int alsa_mask = port_type[type].alsa_mask; - port_t *port = port_get(str->ports, addr); + port_t *port = port_get (str->ports, addr); - debug_log("update_port_type(%d:%d)\n", addr.client, addr.port); + debug_log ("update_port_type(%d:%d)\n", addr.client, addr.port); - if (port && (caps & alsa_mask)!=alsa_mask) { - debug_log("setdead: %s\n", port->name); + if (port && (caps & alsa_mask) != alsa_mask) { + debug_log ("setdead: %s\n", port->name); port->is_dead = 1; } - if (!port && (caps & alsa_mask)==alsa_mask) { - assert (jack_ringbuffer_write_space(str->new_ports) >= sizeof(port)); - port = port_create(self, type, addr, info); - if (port) - jack_ringbuffer_write(str->new_ports, (char*)&port, sizeof(port)); + if (!port && (caps & alsa_mask) == alsa_mask) { + assert (jack_ringbuffer_write_space (str->new_ports) >= sizeof(port)); + port = port_create (self, type, addr, info); + if (port) { + jack_ringbuffer_write (str->new_ports, (char*)&port, sizeof(port)); + } } } static -void update_port(alsa_seqmidi_t *self, snd_seq_addr_t addr, const snd_seq_port_info_t *info) +void update_port (alsa_seqmidi_t *self, snd_seq_addr_t addr, const snd_seq_port_info_t *info) { - unsigned int port_caps = snd_seq_port_info_get_capability(info); - if (port_caps & SND_SEQ_PORT_CAP_NO_EXPORT) + unsigned int port_caps = snd_seq_port_info_get_capability (info); + + if (port_caps & SND_SEQ_PORT_CAP_NO_EXPORT) { return; - update_port_type(self, PORT_INPUT, addr, port_caps, info); - update_port_type(self, PORT_OUTPUT,addr, port_caps, info); + } + update_port_type (self, PORT_INPUT, addr, port_caps, info); + update_port_type (self, PORT_OUTPUT, addr, port_caps, info); } static -void free_ports(alsa_seqmidi_t *self, jack_ringbuffer_t *ports) +void free_ports (alsa_seqmidi_t *self, jack_ringbuffer_t *ports) { port_t *port; int sz; - while ((sz = jack_ringbuffer_read(ports, (char*)&port, sizeof(port)))) { + + while ((sz = jack_ringbuffer_read (ports, (char*)&port, sizeof(port)))) { assert (sz == sizeof(port)); - port_free(self, port); + port_free (self, port); } } static -void update_ports(alsa_seqmidi_t *self) +void update_ports (alsa_seqmidi_t *self) { snd_seq_addr_t addr; snd_seq_port_info_t *info; int size; - snd_seq_port_info_alloca(&info); + snd_seq_port_info_alloca (&info); + + while ((size = jack_ringbuffer_read (self->port_add, (char*)&addr, sizeof(addr)))) { - while ((size = jack_ringbuffer_read(self->port_add, (char*)&addr, sizeof(addr)))) { - int err; assert (size == sizeof(addr)); assert (addr.client != self->client_id); - if ((err=snd_seq_get_any_port_info(self->seq, addr.client, addr.port, info))>=0) { - update_port(self, addr, info); + if ((err = snd_seq_get_any_port_info (self->seq, addr.client, addr.port, info)) >= 0) { + update_port (self, addr, info); } else { //port_setdead(self->stream[PORT_INPUT].ports, addr); //port_setdead(self->stream[PORT_OUTPUT].ports, addr); @@ -614,40 +642,39 @@ void update_ports(alsa_seqmidi_t *self) } static -void* port_thread(void *arg) +void* port_thread (void *arg) { alsa_seqmidi_t *self = arg; while (self->keep_walking) { - sem_wait(&self->port_sem); - free_ports(self, self->port_del); - update_ports(self); + sem_wait (&self->port_sem); + free_ports (self, self->port_del); + update_ports (self); } - debug_log("port_thread exited\n"); + debug_log ("port_thread exited\n"); return NULL; } static -void add_existing_ports(alsa_seqmidi_t *self) +void add_existing_ports (alsa_seqmidi_t *self) { snd_seq_addr_t addr; snd_seq_client_info_t *client_info; snd_seq_port_info_t *port_info; - snd_seq_client_info_alloca(&client_info); - snd_seq_port_info_alloca(&port_info); - snd_seq_client_info_set_client(client_info, -1); - while (snd_seq_query_next_client(self->seq, client_info) >= 0) - { - addr.client = snd_seq_client_info_get_client(client_info); - if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id) + snd_seq_client_info_alloca (&client_info); + snd_seq_port_info_alloca (&port_info); + snd_seq_client_info_set_client (client_info, -1); + while (snd_seq_query_next_client (self->seq, client_info) >= 0) { + addr.client = snd_seq_client_info_get_client (client_info); + if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id) { continue; - snd_seq_port_info_set_client(port_info, addr.client); - snd_seq_port_info_set_port(port_info, -1); - while (snd_seq_query_next_port(self->seq, port_info) >= 0) - { - addr.port = snd_seq_port_info_get_port(port_info); - update_port(self, addr, port_info); + } + snd_seq_port_info_set_client (port_info, addr.client); + snd_seq_port_info_set_port (port_info, -1); + while (snd_seq_query_next_port (self->seq, port_info) >= 0) { + addr.port = snd_seq_port_info_get_port (port_info); + update_port (self, addr, port_info); } } } @@ -656,67 +683,69 @@ void add_existing_ports(alsa_seqmidi_t *self) * =================== Input/output port handling ========================= */ static -void set_process_info(struct process_info *info, alsa_seqmidi_t *self, int dir, jack_nframes_t nframes) +void set_process_info (struct process_info *info, alsa_seqmidi_t *self, int dir, jack_nframes_t nframes) { const snd_seq_real_time_t* alsa_time; snd_seq_queue_status_t *status; - snd_seq_queue_status_alloca(&status); + snd_seq_queue_status_alloca (&status); info->dir = dir; - info->period_start = jack_last_frame_time(self->jack); + info->period_start = jack_last_frame_time (self->jack); info->nframes = nframes; - info->sample_rate = jack_get_sample_rate(self->jack); + info->sample_rate = jack_get_sample_rate (self->jack); - info->cur_frames = jack_frame_time(self->jack); + info->cur_frames = jack_frame_time (self->jack); // immediately get alsa'a real time (uhh, why everybody has their on 'real' time) - snd_seq_get_queue_status(self->seq, self->queue, status); - alsa_time = snd_seq_queue_status_get_real_time(status); + snd_seq_get_queue_status (self->seq, self->queue, status); + alsa_time = snd_seq_queue_status_get_real_time (status); info->alsa_time = alsa_time->tv_sec * NSEC_PER_SEC + alsa_time->tv_nsec; if (info->period_start + info->nframes < info->cur_frames) { - int periods_lost = (info->cur_frames - info->period_start) / info->nframes; + int periods_lost = (info->cur_frames - info->period_start) / info->nframes; info->period_start += periods_lost * info->nframes; - debug_log("xrun detected: %d periods lost\n", periods_lost); + debug_log ("xrun detected: %d periods lost\n", periods_lost); } } static -void add_ports(stream_t *str) +void add_ports (stream_t *str) { port_t *port; - while (jack_ringbuffer_read(str->new_ports, (char*)&port, sizeof(port))) { - debug_log("jack: inserted port %s\n", port->name); - port_insert(str->ports, port); + + while (jack_ringbuffer_read (str->new_ports, (char*)&port, sizeof(port))) { + debug_log ("jack: inserted port %s\n", port->name); + port_insert (str->ports, port); } } static -void jack_process(alsa_seqmidi_t *self, struct process_info *info) +void jack_process (alsa_seqmidi_t *self, struct process_info *info) { stream_t *str = &self->stream[info->dir]; port_jack_func process = port_type[info->dir].jack_func; - int i, del=0; + int i, del = 0; - add_ports(str); + add_ports (str); // process ports - for (i=0; i<PORT_HASH_SIZE; ++i) { + for (i = 0; i < PORT_HASH_SIZE; ++i) { port_t **pport = &str->ports[i]; while (*pport) { port_t *port = *pport; - port->jack_buf = jack_port_get_buffer(port->jack_port, info->nframes); - if (info->dir == PORT_INPUT) - jack_midi_clear_buffer(port->jack_buf); + port->jack_buf = jack_port_get_buffer (port->jack_port, info->nframes); + if (info->dir == PORT_INPUT) { + jack_midi_clear_buffer (port->jack_buf); + } - if (!port->is_dead) + if (!port->is_dead) { (*process)(self, port, info); - else if (jack_ringbuffer_write_space(self->port_del) >= sizeof(port)) { - debug_log("jack: removed port %s\n", port->name); + } else if (jack_ringbuffer_write_space (self->port_del) >= sizeof(port)) { + debug_log ("jack: removed port %s\n", port->name); *pport = port->next; - jack_ringbuffer_write(self->port_del, (char*)&port, sizeof(port)); + jack_ringbuffer_write (self->port_del, (char*)&port, sizeof(port)); del++; continue; } @@ -725,57 +754,62 @@ void jack_process(alsa_seqmidi_t *self, struct process_info *info) } } - if (del) - sem_post(&self->port_sem); + if (del) { + sem_post (&self->port_sem); + } } /* * ============================ Input ============================== */ static -void do_jack_input(alsa_seqmidi_t *self, port_t *port, struct process_info *info) +void do_jack_input (alsa_seqmidi_t *self, port_t *port, struct process_info *info) { // process port->early_events alsa_midi_event_t ev; - while (jack_ringbuffer_read(port->early_events, (char*)&ev, sizeof(ev))) { + + while (jack_ringbuffer_read (port->early_events, (char*)&ev, sizeof(ev))) { jack_midi_data_t* buf; jack_nframes_t time = ev.time - info->period_start; - if (time < 0) + if (time < 0) { time = 0; - else if (time >= info->nframes) + } else if (time >= info->nframes) { time = info->nframes - 1; - buf = jack_midi_event_reserve(port->jack_buf, time, ev.size); - if (buf) - jack_ringbuffer_read(port->early_events, (char*)buf, ev.size); - else - jack_ringbuffer_read_advance(port->early_events, ev.size); - debug_log("input: it's time for %d bytes at %d\n", ev.size, time); + } + buf = jack_midi_event_reserve (port->jack_buf, time, ev.size); + if (buf) { + jack_ringbuffer_read (port->early_events, (char*)buf, ev.size); + } else { + jack_ringbuffer_read_advance (port->early_events, ev.size); + } + debug_log ("input: it's time for %d bytes at %d\n", ev.size, time); } } static -void port_event(alsa_seqmidi_t *self, snd_seq_event_t *ev) +void port_event (alsa_seqmidi_t *self, snd_seq_event_t *ev) { const snd_seq_addr_t addr = ev->data.addr; - if (addr.client == self->client_id) + if (addr.client == self->client_id) { return; + } if (ev->type == SND_SEQ_EVENT_PORT_START || ev->type == SND_SEQ_EVENT_PORT_CHANGE) { - assert (jack_ringbuffer_write_space(self->port_add) >= sizeof(addr)); + assert (jack_ringbuffer_write_space (self->port_add) >= sizeof(addr)); - debug_log("port_event: add/change %d:%d\n", addr.client, addr.port); - jack_ringbuffer_write(self->port_add, (char*)&addr, sizeof(addr)); - sem_post(&self->port_sem); + debug_log ("port_event: add/change %d:%d\n", addr.client, addr.port); + jack_ringbuffer_write (self->port_add, (char*)&addr, sizeof(addr)); + sem_post (&self->port_sem); } else if (ev->type == SND_SEQ_EVENT_PORT_EXIT) { - debug_log("port_event: del %d:%d\n", addr.client, addr.port); - port_setdead(self->stream[PORT_INPUT].ports, addr); - port_setdead(self->stream[PORT_OUTPUT].ports, addr); + debug_log ("port_event: del %d:%d\n", addr.client, addr.port); + port_setdead (self->stream[PORT_INPUT].ports, addr); + port_setdead (self->stream[PORT_OUTPUT].ports, addr); } } static -void input_event(alsa_seqmidi_t *self, snd_seq_event_t *alsa_event, struct process_info* info) +void input_event (alsa_seqmidi_t *self, snd_seq_event_t *alsa_event, struct process_info* info) { jack_midi_data_t data[MAX_EVENT_SIZE]; stream_t *str = &self->stream[PORT_INPUT]; @@ -784,17 +818,19 @@ void input_event(alsa_seqmidi_t *self, snd_seq_event_t *alsa_event, struct proce int64_t frame_offset, event_frame; port_t *port; - port = port_get(str->ports, alsa_event->source); - if (!port) + port = port_get (str->ports, alsa_event->source); + if (!port) { return; + } /* * RPNs, NRPNs, Bank Change, etc. need special handling * but seems, ALSA does it for us already. */ - snd_midi_event_reset_decode(str->codec); - if ((size = snd_midi_event_decode(str->codec, data, sizeof(data), alsa_event))<0) + snd_midi_event_reset_decode (str->codec); + if ((size = snd_midi_event_decode (str->codec, data, sizeof(data), alsa_event)) < 0) { return; + } // fixup NoteOn with vel 0 if ((data[0] & 0xF0) == 0x90 && data[2] == 0x00) { @@ -807,46 +843,49 @@ void input_event(alsa_seqmidi_t *self, snd_seq_event_t *alsa_event, struct proce frame_offset = (info->sample_rate * time_offset) / NSEC_PER_SEC; event_frame = (int64_t)info->cur_frames - info->period_start - frame_offset + info->nframes; - debug_log("input: %d bytes at event_frame=%d\n", (int)size, (int)event_frame); + debug_log ("input: %d bytes at event_frame=%d\n", (int)size, (int)event_frame); if (event_frame >= info->nframes && - jack_ringbuffer_write_space(port->early_events) >= (sizeof(alsa_midi_event_t) + size)) { + jack_ringbuffer_write_space (port->early_events) >= (sizeof(alsa_midi_event_t) + size)) { alsa_midi_event_t ev; ev.time = event_frame + info->period_start; ev.size = size; - jack_ringbuffer_write(port->early_events, (char*)&ev, sizeof(ev)); - jack_ringbuffer_write(port->early_events, (char*)data, size); - debug_log("postponed to next frame +%d\n", (int) (event_frame - info->nframes)); + jack_ringbuffer_write (port->early_events, (char*)&ev, sizeof(ev)); + jack_ringbuffer_write (port->early_events, (char*)data, size); + debug_log ("postponed to next frame +%d\n", (int)(event_frame - info->nframes)); return; } - if (event_frame < 0) + if (event_frame < 0) { event_frame = 0; - else if (event_frame >= info->nframes) + } else if (event_frame >= info->nframes) { event_frame = info->nframes - 1; + } - jack_midi_event_write(port->jack_buf, event_frame, data, size); + jack_midi_event_write (port->jack_buf, event_frame, data, size); } static -void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes) +void alsa_seqmidi_read (alsa_midi_t *m, jack_nframes_t nframes) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; int res; snd_seq_event_t *event; struct process_info info; - if (!self->keep_walking) + if (!self->keep_walking) { return; + } - set_process_info(&info, self, PORT_INPUT, nframes); - jack_process(self, &info); + set_process_info (&info, self, PORT_INPUT, nframes); + jack_process (self, &info); - while ((res = snd_seq_event_input(self->seq, &event))>0) { - if (event->source.client == SND_SEQ_CLIENT_SYSTEM) - port_event(self, event); - else - input_event(self, event, &info); + while ((res = snd_seq_event_input (self->seq, &event)) > 0) { + if (event->source.client == SND_SEQ_CLIENT_SYSTEM) { + port_event (self, event); + } else { + input_event (self, event, &info); + } } } @@ -855,12 +894,13 @@ void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes) */ static -void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info) +void do_jack_output (alsa_seqmidi_t *self, port_t *port, struct process_info* info) { stream_t *str = &self->stream[info->dir]; - int nevents = jack_midi_get_event_count(port->jack_buf); + int nevents = jack_midi_get_event_count (port->jack_buf); int i; - for (i=0; i<nevents; ++i) { + + for (i = 0; i < nevents; ++i) { jack_midi_event_t jack_event; snd_seq_event_t alsa_event; int64_t frame_offset; @@ -868,21 +908,22 @@ void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* inf snd_seq_real_time_t out_rt; int err; - jack_midi_event_get(&jack_event, port->jack_buf, i); + jack_midi_event_get (&jack_event, port->jack_buf, i); - snd_seq_ev_clear(&alsa_event); - snd_midi_event_reset_encode(str->codec); - if (!snd_midi_event_encode(str->codec, jack_event.buffer, jack_event.size, &alsa_event)) + snd_seq_ev_clear (&alsa_event); + snd_midi_event_reset_encode (str->codec); + if (!snd_midi_event_encode (str->codec, jack_event.buffer, jack_event.size, &alsa_event)) { continue; // invalid event - snd_seq_ev_set_source(&alsa_event, self->port_id); - snd_seq_ev_set_dest(&alsa_event, port->remote.client, port->remote.port); + } + snd_seq_ev_set_source (&alsa_event, self->port_id); + snd_seq_ev_set_dest (&alsa_event, port->remote.client, port->remote.port); /* NOTE: in case of xrun it could become negative, so it is essential to use signed type! */ frame_offset = (int64_t)jack_event.time + info->period_start + info->nframes - info->cur_frames; if (frame_offset < 0) { frame_offset = info->nframes + jack_event.time; - error_log("internal xrun detected: frame_offset = %"PRId64"\n", frame_offset); + error_log ("internal xrun detected: frame_offset = %" PRId64 "\n", frame_offset); } /* Ken Ellinwood reported problems with this assert. * Seems, magic 2 should be replaced with nperiods. */ @@ -894,32 +935,34 @@ void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* inf // we should use absolute time to prevent reordering caused by rounding errors if (out_time < port->last_out_time) { - debug_log("alsa_out: limiting out_time %lld at %lld\n", out_time, port->last_out_time); + debug_log ("alsa_out: limiting out_time %lld at %lld\n", out_time, port->last_out_time); out_time = port->last_out_time; - } else + } else { port->last_out_time = out_time; + } out_rt.tv_nsec = out_time % NSEC_PER_SEC; out_rt.tv_sec = out_time / NSEC_PER_SEC; - snd_seq_ev_schedule_real(&alsa_event, self->queue, 0, &out_rt); + snd_seq_ev_schedule_real (&alsa_event, self->queue, 0, &out_rt); - err = snd_seq_event_output(self->seq, &alsa_event); + err = snd_seq_event_output (self->seq, &alsa_event); - debug_log("alsa_out: written %d bytes to %s at %d (%lld): %d %s\n", - jack_event.size, port->name, (int)frame_offset, out_time - info->alsa_time, err, err < 0 ? snd_strerror(err) : "bytes queued"); + debug_log ("alsa_out: written %d bytes to %s at %d (%lld): %d %s\n", + jack_event.size, port->name, (int)frame_offset, out_time - info->alsa_time, err, err < 0 ? snd_strerror (err) : "bytes queued"); } } static -void alsa_seqmidi_write(alsa_midi_t *m, jack_nframes_t nframes) +void alsa_seqmidi_write (alsa_midi_t *m, jack_nframes_t nframes) { - alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; + alsa_seqmidi_t *self = (alsa_seqmidi_t*)m; struct process_info info; - if (!self->keep_walking) + if (!self->keep_walking) { return; + } - set_process_info(&info, self, PORT_OUTPUT, nframes); - jack_process(self, &info); - snd_seq_drain_output(self->seq); + set_process_info (&info, self, PORT_OUTPUT, nframes); + jack_process (self, &info); + snd_seq_drain_output (self->seq); } diff --git a/drivers/am/midi_pack.h b/drivers/am/midi_pack.h index 6fb704b..d75c18e 100644 --- a/drivers/am/midi_pack.h +++ b/drivers/am/midi_pack.h @@ -27,20 +27,21 @@ typedef struct { } midi_pack_t; static inline -void midi_pack_reset(midi_pack_t *p) +void midi_pack_reset (midi_pack_t *p) { p->running_status = 0; } static -void midi_pack_event(midi_pack_t *p, jack_midi_event_t *e) +void midi_pack_event (midi_pack_t *p, jack_midi_event_t *e) { if (e->buffer[0] >= 0x80 && e->buffer[0] < 0xF0) { // Voice Message if (e->buffer[0] == p->running_status) { e->buffer++; e->size--; - } else + } else { p->running_status = e->buffer[0]; + } } else if (e->buffer[0] < 0xF8) { // not System Realtime p->running_status = 0; } diff --git a/drivers/am/midi_unpack.h b/drivers/am/midi_unpack.h index c917f4d..7573a54 100644 --- a/drivers/am/midi_unpack.h +++ b/drivers/am/midi_unpack.h @@ -32,7 +32,7 @@ typedef struct { } midi_unpack_t; static inline -void midi_unpack_init(midi_unpack_t *u) +void midi_unpack_init (midi_unpack_t *u) { u->pos = 0; u->size = sizeof(u->data); @@ -40,102 +40,93 @@ void midi_unpack_init(midi_unpack_t *u) } static inline -void midi_unpack_reset(midi_unpack_t *u) +void midi_unpack_reset (midi_unpack_t *u) { u->pos = 0; u->need = u->size; } static const unsigned char midi_voice_len[] = { - 3, /*0x80 Note Off*/ - 3, /*0x90 Note On*/ - 3, /*0xA0 Aftertouch*/ - 3, /*0xB0 Control Change*/ - 2, /*0xC0 Program Change*/ - 2, /*0xD0 Channel Pressure*/ - 3, /*0xE0 Pitch Wheel*/ - 1 /*0xF0 System*/ + 3, /*0x80 Note Off*/ + 3, /*0x90 Note On*/ + 3, /*0xA0 Aftertouch*/ + 3, /*0xB0 Control Change*/ + 2, /*0xC0 Program Change*/ + 2, /*0xD0 Channel Pressure*/ + 3, /*0xE0 Pitch Wheel*/ + 1 /*0xF0 System*/ }; static const unsigned char midi_system_len[] = { - 0, /*0xF0 System Exclusive Start*/ - 2, /*0xF1 MTC Quarter Frame*/ - 3, /*0xF2 Song Postion*/ - 2, /*0xF3 Song Select*/ - 0, /*0xF4 undefined*/ - 0, /*0xF5 undefined*/ - 1, /*0xF6 Tune Request*/ - 1 /*0xF7 System Exlusive End*/ + 0, /*0xF0 System Exclusive Start*/ + 2, /*0xF1 MTC Quarter Frame*/ + 3, /*0xF2 Song Postion*/ + 2, /*0xF3 Song Select*/ + 0, /*0xF4 undefined*/ + 0, /*0xF5 undefined*/ + 1, /*0xF6 Tune Request*/ + 1 /*0xF7 System Exlusive End*/ }; static -int midi_unpack_buf(midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) +int midi_unpack_buf (midi_unpack_t *buf, const unsigned char *data, int len, void *jack_port_buf, jack_nframes_t time) { int i; - for (i=0; i<len; ++i) - { + + for (i = 0; i < len; ++i) { const unsigned char byte = data[i]; - if (byte >= 0xF8) // system realtime - { - jack_midi_event_write(jack_port_buf, time, &data[i], 1); + if (byte >= 0xF8) { // system realtime + jack_midi_event_write (jack_port_buf, time, &data[i], 1); //jack_error("midi_unpack: written system relatime event\n"); //midi_input_write(in, &data[i], 1); - } - else if (byte < 0x80) // data - { + } else if (byte < 0x80) { // data assert (buf->pos < buf->size); buf->data[buf->pos++] = byte; - } - else if (byte < 0xF0) // voice - { + } else if (byte < 0xF0) { // voice assert (byte >= 0x80 && byte < 0xF0); //buf->need = ((byte|0x0F) == 0xCF || (byte|0x0F)==0xDF) ? 2 : 3; - buf->need = midi_voice_len[(byte-0x80)>>4]; + buf->need = midi_voice_len[(byte - 0x80) >> 4]; buf->data[0] = byte; buf->pos = 1; - } - else if (byte == 0xF7) // sysex end - { + } else if (byte == 0xF7) { // sysex end assert (buf->pos < buf->size); buf->data[buf->pos++] = byte; buf->need = buf->pos; - } - else - { + } else { assert (byte >= 0xF0 && byte < 0xF8); buf->pos = 1; buf->data[0] = byte; buf->need = midi_system_len[byte - 0xF0]; - if (!buf->need) + if (!buf->need) { buf->need = buf->size; + } } - if (buf->pos == buf->need) - { + if (buf->pos == buf->need) { // TODO: deal with big sysex'es (they are silently dropped for now) - if (buf->data[0] >= 0x80 || (buf->data[0]==0xF0 && buf->data[buf->pos-1] == 0xF7)) { + if (buf->data[0] >= 0x80 || (buf->data[0] == 0xF0 && buf->data[buf->pos - 1] == 0xF7)) { /* convert Note On with velocity 0 to Note Off */ if ((buf->data[0] & 0xF0) == 0x90 && buf->data[2] == 0) { // we use temp array here to keep running status in sync jack_midi_data_t temp[3] = { 0x80, 0, 0x40 }; temp[0] |= buf->data[0] & 0x0F; temp[1] = buf->data[1]; - jack_midi_event_write(jack_port_buf, time, temp, 3); - } else - jack_midi_event_write(jack_port_buf, time, &buf->data[0], buf->pos); + jack_midi_event_write (jack_port_buf, time, temp, 3); + } else { + jack_midi_event_write (jack_port_buf, time, &buf->data[0], buf->pos); + } //jack_error("midi_unpack: written %d-byte event\n", buf->pos); //midi_input_write(in, &buf->data[0], buf->pos); } /* keep running status */ - if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) + if (buf->data[0] >= 0x80 && buf->data[0] < 0xF0) { buf->pos = 1; - else - { + } else { buf->pos = 0; buf->need = buf->size; } } } - assert (i==len); + assert (i == len); return i; } |