diff options
Diffstat (limited to 'backends/jack.c')
-rw-r--r-- | backends/jack.c | 109 |
1 files changed, 56 insertions, 53 deletions
diff --git a/backends/jack.c b/backends/jack.c index eb53190..d7f68c4 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "jack" + #include <string.h> #include <signal.h> #include <sys/types.h> @@ -8,7 +10,6 @@ #include <jack/midiport.h> #include <jack/metadata.h> -#define BACKEND_NAME "jack" #define JACKEY_SIGNAL_TYPE "http://jackaudio.org/metadata/signal-type" #ifdef __APPLE__ @@ -41,20 +42,20 @@ MM_PLUGIN_API int init(){ }; if(sizeof(mmjack_channel_ident) != sizeof(uint64_t)){ - fprintf(stderr, "jack channel identification union out of bounds\n"); + LOG("Channel identification union out of bounds"); return 1; } //register backend if(mm_backend_register(mmjack)){ - fprintf(stderr, "Failed to register jack backend\n"); + LOG("Failed to register backend"); return 1; } return 0; } static void mmjack_message_print(const char* msg){ - fprintf(stderr, "JACK message: %s\n", msg); + LOGPF("JACK message: %s", msg); } static void mmjack_message_ignore(const char* msg){ @@ -66,7 +67,7 @@ static int mmjack_midiqueue_append(mmjack_port* port, mmjack_channel_ident ident //extend the queue port->queue = realloc(port->queue, (port->queue_len + JACK_MIDIQUEUE_CHUNK) * sizeof(mmjack_midiqueue)); if(!port->queue){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } port->queue_alloc += JACK_MIDIQUEUE_CHUNK; @@ -75,7 +76,7 @@ static int mmjack_midiqueue_append(mmjack_port* port, mmjack_channel_ident ident port->queue[port->queue_len].ident.label = ident.label; port->queue[port->queue_len].raw = value; port->queue_len++; - DBGPF("Appended event to queue for %s, now at %" PRIsize_t " entries\n", port->name, port->queue_len); + DBGPF("Appended event to queue for %s, now at %" PRIsize_t " entries", port->name, port->queue_len); return 0; } @@ -90,7 +91,7 @@ static int mmjack_process_midi(instance* inst, mmjack_port* port, size_t nframes if(port->input){ if(event_count){ - DBGPF("Reading %u MIDI events from jack port %s\n", event_count, port->name); + DBGPF("Reading %u MIDI events from port %s", event_count, port->name); for(u = 0; u < event_count; u++){ ident.label = 0; //read midi data from stream @@ -128,7 +129,7 @@ static int mmjack_process_midi(instance* inst, mmjack_port* port, size_t nframes ident.label = port->queue[u].ident.label; event_data = jack_midi_event_reserve(buffer, u, (ident.fields.sub_type == midi_aftertouch) ? 2 : 3); if(!event_data){ - fprintf(stderr, "Failed to reserve MIDI stream data\n"); + LOG("Failed to reserve MIDI stream data"); return 1; } event_data[0] = ident.fields.sub_channel | ident.fields.sub_type; @@ -146,7 +147,7 @@ static int mmjack_process_midi(instance* inst, mmjack_port* port, size_t nframes } if(port->queue_len){ - DBGPF("Wrote %" PRIsize_t " MIDI events to jack port %s\n", port->queue_len, port->name); + DBGPF("Wrote %" PRIsize_t " MIDI events to port %s", port->queue_len, port->name); } port->queue_len = 0; } @@ -180,21 +181,21 @@ static int mmjack_process(jack_nframes_t nframes, void* instp){ size_t p, mark = 0; int rv = 0; - //DBGPF("jack callback for %d frames on %s\n", nframes, inst->name); + //DBGPF("jack callback for %d frames on %s", nframes, inst->name); for(p = 0; p < data->ports; p++){ pthread_mutex_lock(&data->port[p].lock); switch(data->port[p].type){ case port_midi: - //DBGPF("Handling MIDI port %s.%s\n", inst->name, data->port[p].name); + //DBGPF("Handling MIDI port %s.%s", inst->name, data->port[p].name); rv |= mmjack_process_midi(inst, data->port + p, nframes, &mark); break; case port_cv: - //DBGPF("Handling CV port %s.%s\n", inst->name, data->port[p].name); + //DBGPF("Handling CV port %s.%s", inst->name, data->port[p].name); rv |= mmjack_process_cv(inst, data->port + p, nframes, &mark); break; default: - fprintf(stderr, "Unhandled jack port type in processing callback\n"); + LOG("Unhandled port type in processing callback"); pthread_mutex_unlock(&data->port[p].lock); return 1; } @@ -203,14 +204,14 @@ static int mmjack_process(jack_nframes_t nframes, void* instp){ //notify the main thread if(mark){ - DBGPF("Notifying handler thread for jack instance %s\n", inst->name); + DBGPF("Notifying handler thread for instance %s", inst->name); send(data->fd, "c", 1, 0); } return rv; } static void mmjack_server_shutdown(void* inst){ - fprintf(stderr, "jack server shutdown notification\n"); + LOG("Server shut down"); config.jack_shutdown = 1; } @@ -232,7 +233,7 @@ static int mmjack_configure(char* option, char* value){ return 0; } - fprintf(stderr, "Unknown jack backend option %s\n", option); + LOGPF("Unknown backend option %s", option); return 1; } @@ -258,7 +259,7 @@ static int mmjack_parse_portconfig(mmjack_port* port, char* spec){ else if(!strcmp(token, "max")){ token = strtok(NULL, " "); if(!token){ - fprintf(stderr, "jack port %s configuration missing argument\n", port->name); + LOGPF("Port %s configuration missing argument", port->name); return 1; } port->max = strtod(token, NULL); @@ -266,19 +267,19 @@ static int mmjack_parse_portconfig(mmjack_port* port, char* spec){ else if(!strcmp(token, "min")){ token = strtok(NULL, " "); if(!token){ - fprintf(stderr, "jack port %s configuration missing argument\n", port->name); + LOGPF("Port %s configuration missing argument", port->name); return 1; } port->min = strtod(token, NULL); } else{ - fprintf(stderr, "Unknown jack channel configuration token %s on port %s\n", token, port->name); + LOGPF("Unknown channel configuration token %s on port %s", token, port->name); return 1; } } if(port->type == port_none){ - fprintf(stderr, "jack channel %s assigned no port type\n", port->name); + LOGPF("Channel %s assigned no port type", port->name); return 1; } return 0; @@ -306,24 +307,24 @@ static int mmjack_configure_instance(instance* inst, char* option, char* value){ //register new port, first check for unique name for(p = 0; p < data->ports; p++){ if(!strcmp(data->port[p].name, option)){ - fprintf(stderr, "jack instance %s has duplicate port %s\n", inst->name, option); + LOGPF("Instance %s has duplicate port %s", inst->name, option); return 1; } } if(strchr(option, '.')){ - fprintf(stderr, "Invalid jack channel spec %s.%s\n", inst->name, option); + LOGPF("Invalid channel spec %s.%s", inst->name, option); } //add port to registry //TODO for OSC ports we need to configure subchannels for each message data->port = realloc(data->port, (data->ports + 1) * sizeof(mmjack_port)); if(!data->port){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } data->port[data->ports].name = strdup(option); if(!data->port[data->ports].name){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } if(mmjack_parse_portconfig(data->port + p, value)){ @@ -341,7 +342,7 @@ static instance* mmjack_instance(){ inst->impl = calloc(1, sizeof(mmjack_instance_data)); if(!inst->impl){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -359,18 +360,18 @@ static int mmjack_parse_midispec(mmjack_channel_ident* ident, char* spec){ } if(!next_token){ - fprintf(stderr, "Invalid jack MIDI spec %s\n", spec); + LOGPF("Invalid MIDI spec %s", spec); return 1; } ident->fields.sub_channel = strtoul(next_token, &next_token, 10); if(ident->fields.sub_channel > 15){ - fprintf(stderr, "Invalid jack MIDI spec %s, channel out of range\n", spec); + LOGPF("Invalid MIDI spec %s, channel out of range", spec); return 1; } if(*next_token != '.'){ - fprintf(stderr, "Invalid jack MIDI spec %s\n", spec); + LOGPF("Invalid MIDI spec %s", spec); return 1; } @@ -395,7 +396,7 @@ static int mmjack_parse_midispec(mmjack_channel_ident* ident, char* spec){ ident->fields.sub_type = midi_aftertouch; } else{ - fprintf(stderr, "Unknown jack MIDI control type in spec %s\n", spec); + LOGPF("Unknown MIDI control type in spec %s", spec); return 1; } @@ -403,7 +404,7 @@ static int mmjack_parse_midispec(mmjack_channel_ident* ident, char* spec){ if(ident->fields.sub_type == midi_none || ident->fields.sub_control > 127){ - fprintf(stderr, "Invalid jack MIDI spec %s\n", spec); + LOGPF("Invalid MIDI spec %s", spec); return 1; } return 0; @@ -425,7 +426,7 @@ static channel* mmjack_channel(instance* inst, char* spec, uint8_t flags){ } if(u == data->ports){ - fprintf(stderr, "jack port %s.%s not found\n", inst->name, spec); + LOGPF("Tried to map unknown port %s.%s", inst->name, spec); return NULL; } @@ -456,7 +457,7 @@ static int mmjack_set(instance* inst, size_t num, channel** c, channel_value* v) ident.label = c[u]->ident; if(data->port[ident.fields.port].input){ - fprintf(stderr, "jack port %s.%s is an input port, no output is possible\n", inst->name, data->port[ident.fields.port].name); + LOGPF("Port %s.%s is an input port, no output is possible", inst->name, data->port[ident.fields.port].name); continue; } range = data->port[ident.fields.port].max - data->port[ident.fields.port].min; @@ -466,7 +467,7 @@ static int mmjack_set(instance* inst, size_t num, channel** c, channel_value* v) case port_cv: //scale value to given range data->port[ident.fields.port].last = (range * v[u].normalised) + data->port[ident.fields.port].min; - DBGPF("CV port %s updated to %f\n", data->port[ident.fields.port].name, data->port[ident.fields.port].last); + DBGPF("CV port %s updated to %f", data->port[ident.fields.port].name, data->port[ident.fields.port].last); break; case port_midi: value = v[u].normalised * 127.0; @@ -479,7 +480,7 @@ static int mmjack_set(instance* inst, size_t num, channel** c, channel_value* v) } break; default: - fprintf(stderr, "No handler implemented for jack port type %s.%s\n", inst->name, data->port[ident.fields.port].name); + LOGPF("No handler implemented for port type %s.%s", inst->name, data->port[ident.fields.port].name); break; } pthread_mutex_unlock(&data->port[ident.fields.port].lock); @@ -503,7 +504,7 @@ static void mmjack_handle_midi(instance* inst, size_t index, mmjack_port* port){ else{ val.normalised = ((double)port->queue[u].raw) / 127.0; } - DBGPF("Pushing MIDI channel %d type %02X control %d value %f raw %d label %" PRIu64 "\n", + DBGPF("Pushing MIDI channel %d type %02X control %d value %f raw %d label %" PRIu64, port->queue[u].ident.fields.sub_channel, port->queue[u].ident.fields.sub_type, port->queue[u].ident.fields.sub_control, @@ -511,13 +512,13 @@ static void mmjack_handle_midi(instance* inst, size_t index, mmjack_port* port){ port->queue[u].raw, port->queue[u].ident.label); if(mm_channel_event(chan, val)){ - fprintf(stderr, "Failed to push MIDI event to core on jack port %s.%s\n", inst->name, port->name); + LOGPF("Failed to push MIDI event to core on port %s.%s", inst->name, port->name); } } } if(port->queue_len){ - DBGPF("Pushed %" PRIsize_t " MIDI events to core for jack port %s.%s\n", port->queue_len, inst->name, port->name); + DBGPF("Pushed %" PRIsize_t " MIDI events to core for port %s.%s", port->queue_len, inst->name, port->name); } port->queue_len = 0; } @@ -532,7 +533,7 @@ static void mmjack_handle_cv(instance* inst, size_t index, mmjack_port* port){ channel* chan = mm_channel(inst, ident.label, 0); if(!chan){ //this might happen if a channel is registered but not mapped - DBGPF("Failed to match jack CV channel %s.%s to core channel\n", inst->name, port->name); + DBGPF("Failed to match CV channel %s.%s to core channel", inst->name, port->name); return; } @@ -541,9 +542,9 @@ static void mmjack_handle_cv(instance* inst, size_t index, mmjack_port* port){ val.normalised = port->last - port->min; val.normalised /= range; val.normalised = clamp(val.normalised, 1.0, 0.0); - DBGPF("Pushing CV channel %s value %f raw %f min %f max %f\n", port->name, val.normalised, port->last, port->min, port->max); + DBGPF("Pushing CV channel %s value %f raw %f min %f max %f", port->name, val.normalised, port->last, port->min, port->max); if(mm_channel_event(chan, val)){ - fprintf(stderr, "Failed to push CV event to core for %s.%s\n", inst->name, port->name); + LOGPF("Failed to push CV event to core for %s.%s", inst->name, port->name); } } @@ -560,7 +561,7 @@ static int mmjack_handle(size_t num, managed_fd* fds){ data = (mmjack_instance_data*) inst->impl; bytes = recv(fds[u].fd, recv_buf, sizeof(recv_buf), 0); if(bytes < 0){ - fprintf(stderr, "Failed to receive on feedback socket for instance %s\n", inst->name); + LOGPF("Failed to receive on feedback socket for instance %s", inst->name); return 1; } @@ -575,7 +576,7 @@ static int mmjack_handle(size_t num, managed_fd* fds){ mmjack_handle_midi(inst, p, data->port + p); break; default: - fprintf(stderr, "Output handler not implemented for unknown jack channel type on %s.%s\n", inst->name, data->port[p].name); + LOGPF("Output handler not implemented for unknown channel type on %s.%s", inst->name, data->port[p].name); break; } @@ -587,7 +588,7 @@ static int mmjack_handle(size_t num, managed_fd* fds){ } if(config.jack_shutdown){ - fprintf(stderr, "JACK server disconnected\n"); + LOG("Server disconnected"); return 1; } return 0; @@ -613,7 +614,7 @@ static int mmjack_start(size_t n, instance** inst){ //prepare mutex attributes because the initializer macro for adaptive mutexes is a GNU extension... if(pthread_mutexattr_init(&mutex_attr) || pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ADAPTIVE_NP)){ - fprintf(stderr, "Failed to initialize mutex attributes\n"); + LOG("Failed to initialize mutex attributes"); goto bail; } @@ -628,19 +629,19 @@ static int mmjack_start(size_t n, instance** inst){ if(!data->client){ //TODO pretty-print failures - fprintf(stderr, "jack backend failed to connect to server, return status %u\n", error); + LOGPF("Failed to connect to server, return status %u", error); goto bail; } //set up the feedback fd if(socketpair(AF_LOCAL, SOCK_DGRAM, 0, feedback_fd)){ - fprintf(stderr, "Failed to create feedback socket pair\n"); + LOG("Failed to create feedback socket pair"); goto bail; } data->fd = feedback_fd[0]; if(mm_manage_fd(feedback_fd[1], BACKEND_NAME, 1, inst[u])){ - fprintf(stderr, "jack backend failed to register feedback fd with core\n"); + LOG("Failed to register feedback FD with core"); goto bail; } @@ -648,12 +649,12 @@ static int mmjack_start(size_t n, instance** inst){ jack_set_process_callback(data->client, mmjack_process, inst[u]); jack_on_shutdown(data->client, mmjack_server_shutdown, inst[u]); - fprintf(stderr, "jack instance %s assigned client name %s\n", inst[u]->name, jack_get_client_name(data->client)); + LOGPF("Instance %s assigned client name %s", inst[u]->name, jack_get_client_name(data->client)); //create and initialize jack ports for(p = 0; p < data->ports; p++){ if(pthread_mutex_init(&(data->port[p].lock), &mutex_attr)){ - fprintf(stderr, "Failed to create port mutex\n"); + LOG("Failed to create port mutex"); goto bail; } @@ -666,19 +667,19 @@ static int mmjack_start(size_t n, instance** inst){ jack_set_property(data->client, jack_port_uuid(data->port[p].port), JACKEY_SIGNAL_TYPE, "CV", "text/plain"); if(!data->port[p].port){ - fprintf(stderr, "Failed to create jack port %s.%s\n", inst[u]->name, data->port[p].name); + LOGPF("Failed to create port %s.%s", inst[u]->name, data->port[p].name); goto bail; } } //do the thing if(jack_activate(data->client)){ - fprintf(stderr, "Failed to activate jack client for instance %s\n", inst[u]->name); + LOGPF("Failed to activate client for instance %s", inst[u]->name); goto bail; } } - fprintf(stderr, "jack backend registered %" PRIsize_t " descriptors to core\n", n); + LOGPF("Registered %" PRIsize_t " descriptors to core", n); rv = 0; bail: pthread_mutexattr_destroy(&mutex_attr); @@ -725,8 +726,10 @@ static int mmjack_shutdown(size_t n, instance** inst){ data->client_name = NULL; close(data->fd); data->fd = -1; + + free(inst[u]->impl); } - fprintf(stderr, "jack backend shut down\n"); + LOG("Backend shut down"); return 0; } |