aboutsummaryrefslogtreecommitdiffhomepage
path: root/midi.c
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2017-06-05 20:53:02 +0200
committercbdev <cb@cbcdn.com>2017-06-05 20:53:02 +0200
commitddb185aaa2a5ef6a70c130675826c33f90057591 (patch)
tree4a984a603d5e8c712609b10502cce3b4b5baa0bf /midi.c
parent40e123db7713b188162cd94d935f7a395405567a (diff)
downloadmidimonster-ddb185aaa2a5ef6a70c130675826c33f90057591.tar.gz
midimonster-ddb185aaa2a5ef6a70c130675826c33f90057591.tar.bz2
midimonster-ddb185aaa2a5ef6a70c130675826c33f90057591.zip
MIDI backend start procedure
Diffstat (limited to 'midi.c')
-rw-r--r--midi.c111
1 files changed, 98 insertions, 13 deletions
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(){