From ddb185aaa2a5ef6a70c130675826c33f90057591 Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 5 Jun 2017 20:53:02 +0200 Subject: MIDI backend start procedure --- midi.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 13 deletions(-) (limited to 'midi.c') diff --git a/midi.c b/midi.c index 00ff0a4..ca1f66b 100644 --- a/midi.c +++ b/midi.c @@ -40,6 +40,10 @@ int midi_init(){ fprintf(stderr, "Failed to register MIDI backend\n"); return 1; } + + snd_seq_nonblock(sequencer, 1); + + fprintf(stderr, "MIDI client ID is %d\n", snd_seq_client_id(sequencer)); return 0; } @@ -57,24 +61,43 @@ static int midi_configure(char* option, char* value){ } static instance* midi_instance(){ - return mm_instance(); + instance* inst = mm_instance(); + if(!inst){ + return NULL; + } + + inst->impl = calloc(1, sizeof(midi_instance_data)); + if(!inst->impl){ + fprintf(stderr, "Failed to allocate memory\n"); + return NULL; + } + + return inst; } static int midi_configure_instance(instance* instance, char* option, char* value){ - if(!strcmp(option, "device")){ - //open i/o device - return 0; - } - else if(!strcmp(option, "port")){ - //create midi port + midi_instance_data* data = (midi_instance_data*) instance->impl; + + //FIXME maybe allow connecting more than one device + if(!strcmp(option, "read")){ + //connect input device + if(data->read){ + fprintf(stderr, "Port already connected to an input device\n"); + return 1; + } + data->read = strdup(value); return 0; } - else if(!strcmp(option, "mode")){ - //configure open mode - //FIXME needed? + else if(!strcmp(option, "write")){ + //connect output device + if(data->write){ + fprintf(stderr, "Port already connected to an output device\n"); + return 1; + } + data->write = strdup(value); return 0; } - + fprintf(stderr, "Unknown MIDI instance option %s\n", option); return 1; } @@ -124,7 +147,7 @@ static channel* midi_channel(instance* instance, char* spec){ ident.fields.control = strtoul(channel, NULL, 10); if(ident.label){ - return mm_channel(instance, ident.label); + return mm_channel(instance, ident.label, 1); } return NULL; @@ -141,7 +164,69 @@ static int midi_handle(size_t num, int* fd, void** data){ } static int midi_start(){ - return 0; + size_t n, p; + int nfds, rv = 1; + struct pollfd* pfds = NULL; + instance** inst = NULL; + midi_instance_data* data = NULL; + snd_seq_addr_t addr; + + if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ + fprintf(stderr, "Failed to fetch instance list\n"); + return 1; + } + + //create all ports + for(p = 0; p < n; p++){ + data = (midi_instance_data*) inst[p]->impl; + data->port = snd_seq_create_simple_port(sequencer, inst[p]->name, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); + + //make connections + if(data->write){ + fprintf(stderr, "Connecting output of instance %s to MIDI device %s\n", inst[p]->name, data->write); + if(snd_seq_parse_address(sequencer, &addr, data->write) == 0){ + snd_seq_connect_to(sequencer, data->port, addr.client, addr.port); + } + else{ + fprintf(stderr, "Failed to get destination device address: %s\n", data->write); + } + free(data->write); + data->write = NULL; + } + + if(data->read){ + fprintf(stderr, "Connecting input from MIDI device %s to instance %s\n", data->read, inst[p]->name); + if(snd_seq_parse_address(sequencer, &addr, data->read) == 0){ + snd_seq_connect_from(sequencer, data->port, addr.client, addr.port); + } + else{ + fprintf(stderr, "Failed to get source device address: %s\n", data->read); + } + free(data->read); + data->read = NULL; + } + } + + //register all fds to core + nfds = snd_seq_poll_descriptors_count(sequencer, POLLIN | POLLOUT); + pfds = calloc(nfds, sizeof(struct pollfd)); + if(!pfds){ + fprintf(stderr, "Failed to allocate memory\n"); + goto bail; + } + nfds = snd_seq_poll_descriptors(sequencer, pfds, nfds, POLLIN | POLLOUT); + + fprintf(stderr, "Registering %d descriptors to core\n", nfds); + for(p = 0; p < nfds; p++){ + mm_manage_fd(pfds[p].fd, BACKEND_NAME, 1, NULL); + } + + rv = 0; + +bail: + free(pfds); + free(inst); + return rv; } static int midi_shutdown(){ -- cgit v1.2.3