From 9c37eddad24eb7e9bbc9aae723b3a992ec5b4c97 Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 5 Dec 2019 19:31:14 +0100 Subject: Unify midi parsing/deparsing code --- backends/jack.c | 8 ++--- backends/winmidi.c | 89 ++++++++++++++++-------------------------------------- backends/winmidi.h | 10 +++--- midimonster.c | 2 +- 4 files changed, 36 insertions(+), 73 deletions(-) diff --git a/backends/jack.c b/backends/jack.c index 192aab2..926f800 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -98,20 +98,20 @@ static int mmjack_process_midi(instance* inst, mmjack_port* port, size_t nframes //ident.fields.port set on output in mmjack_handle_midi ident.fields.sub_channel = event.buffer[0] & 0x0F; ident.fields.sub_type = event.buffer[0] & 0xF0; + ident.fields.sub_control = event.buffer[1]; + value = event.buffer[2]; if(ident.fields.sub_type == 0x80){ ident.fields.sub_type = midi_note; value = 0; } else if(ident.fields.sub_type == midi_pitchbend){ + ident.fields.sub_control = 0; value = event.buffer[1] | (event.buffer[2] << 7); } else if(ident.fields.sub_type == midi_aftertouch){ + ident.fields.sub_control = 0; value = event.buffer[1]; } - else{ - ident.fields.sub_control = event.buffer[1]; - value = event.buffer[2]; - } //append midi data mmjack_midiqueue_append(port, ident, value); } diff --git a/backends/winmidi.c b/backends/winmidi.c index bda5401..b274c06 100644 --- a/backends/winmidi.c +++ b/backends/winmidi.c @@ -203,35 +203,17 @@ static int winmidi_set(instance* inst, size_t num, channel** c, channel_value* v for(u = 0; u < num; u++){ ident.label = c[u]->ident; - switch(ident.fields.type){ - case note: - output.components.status = 0x90 | ident.fields.channel; - output.components.data1 = ident.fields.control; - output.components.data2 = v[u].normalised * 127.0; - break; - case cc: - output.components.status = 0xB0 | ident.fields.channel; - output.components.data1 = ident.fields.control; - output.components.data2 = v[u].normalised * 127.0; - break; - case pressure: - output.components.status = 0xA0 | ident.fields.channel; - output.components.data1 = ident.fields.control; - output.components.data2 = v[u].normalised * 127.0; - break; - case aftertouch: - output.components.status = 0xD0 | ident.fields.channel; - output.components.data1 = v[u].normalised * 127.0; - output.components.data2 = 0; - break; - case pitchbend: - output.components.status = 0xE0 | ident.fields.channel; - output.components.data1 = ((int)(v[u].normalised * 16384.0)) & 0x7F; - output.components.data2 = (((int)(v[u].normalised * 16384.0)) >> 7) & 0x7F; - break; - default: - fprintf(stderr, "Unknown winmidi channel type %d\n", ident.fields.type); - continue; + //build output message + output.components.status = ident.fields.type | ident.fields.channel; + output.components.data1 = ident.fields.control; + output.components.data2 = v[u].normalised * 127.0; + if(ident.fields.type == pitchbend){ + output.components.data1 = ((int)(v[u].normalised * 16384.0)) & 0x7F; + output.components.data2 = (((int)(v[u].normalised * 16384.0)) >> 7) & 0x7F; + } + else if(ident.fields.type == aftertouch){ + output.components.data1 = v[u].normalised * 127.0; + output.components.data2 = 0; } midiOutShortMsg(data->device_out, output.dword); @@ -330,40 +312,21 @@ static void CALLBACK winmidi_input_callback(HMIDIIN device, unsigned message, DW //param1 has the message input.dword = param1; ident.fields.channel = input.components.status & 0x0F; - switch(input.components.status & 0xF0){ - case 0x80: - ident.fields.type = note; - ident.fields.control = input.components.data1; - val.normalised = 0.0; - break; - case 0x90: - ident.fields.type = note; - ident.fields.control = input.components.data1; - val.normalised = (double) input.components.data2 / 127.0; - break; - case 0xA0: - ident.fields.type = pressure; - ident.fields.control = input.components.data1; - val.normalised = (double) input.components.data2 / 127.0; - break; - case 0xB0: - ident.fields.type = cc; - ident.fields.control = input.components.data1; - val.normalised = (double) input.components.data2 / 127.0; - break; - case 0xD0: - ident.fields.type = aftertouch; - ident.fields.control = 0; - val.normalised = (double) input.components.data1 / 127.0; - break; - case 0xE0: - ident.fields.type = pitchbend; - ident.fields.control = 0; - val.normalised = (double)((input.components.data2 << 7) | input.components.data1) / 16384.0; - break; - default: - fprintf(stderr, "winmidi unhandled status byte %02X\n", input.components.status); - return; + ident.fields.type = input.components.status & 0xF0; + ident.fields.control = input.components.data1; + val.normalised = (double) input.components.data2 / 127.0; + + if(ident.fields.type == 0x80){ + ident.fields.type = note; + val.normalised = 0; + } + else if(ident.fields.type == pitchbend){ + ident.fields.control = 0; + val.normalised = (double)((input.components.data2 << 7) | input.components.data1) / 16384.0; + } + else if(ident.fields.type == aftertouch){ + ident.fields.control = 0; + val.normalised = (double) input.components.data1 / 127.0; } break; case MIM_LONGDATA: diff --git a/backends/winmidi.h b/backends/winmidi.h index ffa6a26..8c2d76b 100644 --- a/backends/winmidi.h +++ b/backends/winmidi.h @@ -19,11 +19,11 @@ typedef struct /*_winmidi_instance_data*/ { enum /*_winmidi_channel_type*/ { none = 0, - note, - cc, - pressure, - aftertouch, - pitchbend + note = 0x90, + cc = 0xB0, + pressure = 0xA0, + aftertouch = 0xD0, + pitchbend = 0xE0 }; typedef union { diff --git a/midimonster.c b/midimonster.c index eb64974..e6c0842 100644 --- a/midimonster.c +++ b/midimonster.c @@ -224,7 +224,7 @@ static void event_free(){ } static int usage(char* fn){ - fprintf(stderr, "MIDIMonster v0.2\n"); + fprintf(stderr, "MIDIMonster v0.3\n"); fprintf(stderr, "Usage:\n"); fprintf(stderr, "\t%s \n", fn); return EXIT_FAILURE; -- cgit v1.2.3 From d8d636901b43a4b94bc54052b3fb26517d48e055 Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 5 Dec 2019 19:48:40 +0100 Subject: Create basic manpage (Fixes #38) --- midimonster.1 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 midimonster.1 diff --git a/midimonster.1 b/midimonster.1 new file mode 100644 index 0000000..8e97109 --- /dev/null +++ b/midimonster.1 @@ -0,0 +1,18 @@ +.TH MIDIMONSTER 8 "December 2019" +.SH NAME +midimonster \- Multi-protocol translation tool +.SH SYNOPSIS +.B midimonster +.I config-file +.SH DESCRIPTION +.B MIDIMonster +allows the user to translate any channel on one supported protocol into channel(s) +on any other (or the same) supported protocol. +.SH OPTIONS +.TP +.I config-file +The configuration file to read. If not specified, a default configuration file is read. +.SH "SEE ALSO" +Online documentation and repository at https://github.com/cbdevnet/midimonster +.SH AUTHOR +Fabian "cbdev" Stumpf -- cgit v1.2.3 From 3eada28582b144519e95a44ee3adc3f46d39036e Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 5 Dec 2019 21:05:14 +0100 Subject: Add flags parameter to channel parser plugin API (Fixes #31) --- backends/artnet.c | 2 +- backends/artnet.h | 2 +- backends/evdev.c | 2 +- backends/evdev.h | 2 +- backends/jack.c | 2 +- backends/jack.h | 2 +- backends/loopback.c | 2 +- backends/loopback.h | 2 +- backends/lua.c | 2 +- backends/lua.h | 2 +- backends/maweb.c | 2 +- backends/maweb.h | 2 +- backends/midi.c | 2 +- backends/midi.h | 2 +- backends/ola.cpp | 2 +- backends/ola.h | 2 +- backends/osc.c | 2 +- backends/osc.h | 2 +- backends/sacn.c | 2 +- backends/sacn.h | 2 +- backends/winmidi.c | 2 +- backends/winmidi.h | 2 +- config.c | 8 ++++---- midimonster.h | 15 ++++++++++++--- 24 files changed, 38 insertions(+), 29 deletions(-) diff --git a/backends/artnet.c b/backends/artnet.c index 8a62a43..57eb7b1 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -156,7 +156,7 @@ static int artnet_configure_instance(instance* inst, char* option, char* value){ return 1; } -static channel* artnet_channel(instance* inst, char* spec){ +static channel* artnet_channel(instance* inst, char* spec, uint8_t flags){ artnet_instance_data* data = (artnet_instance_data*) inst->impl; char* spec_next = spec; unsigned chan_a = strtoul(spec, &spec_next, 10); diff --git a/backends/artnet.h b/backends/artnet.h index cce11d1..f6a6709 100644 --- a/backends/artnet.h +++ b/backends/artnet.h @@ -7,7 +7,7 @@ MM_PLUGIN_API int init(); static int artnet_configure(char* option, char* value); static int artnet_configure_instance(instance* instance, char* option, char* value); static instance* artnet_instance(); -static channel* artnet_channel(instance* instance, char* spec); +static channel* artnet_channel(instance* instance, char* spec, uint8_t flags); static int artnet_set(instance* inst, size_t num, channel** c, channel_value* v); static int artnet_handle(size_t num, managed_fd* fds); static int artnet_start(); diff --git a/backends/evdev.c b/backends/evdev.c index dd2231b..0da5ae6 100644 --- a/backends/evdev.c +++ b/backends/evdev.c @@ -249,7 +249,7 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { return 1; } -static channel* evdev_channel(instance* inst, char* spec){ +static channel* evdev_channel(instance* inst, char* spec, uint8_t flags){ #ifndef EVDEV_NO_UINPUT evdev_instance_data* data = (evdev_instance_data*) inst->impl; #endif diff --git a/backends/evdev.h b/backends/evdev.h index 30ce892..6504416 100644 --- a/backends/evdev.h +++ b/backends/evdev.h @@ -12,7 +12,7 @@ MM_PLUGIN_API int init(); static int evdev_configure(char* option, char* value); static int evdev_configure_instance(instance* instance, char* option, char* value); static instance* evdev_instance(); -static channel* evdev_channel(instance* instance, char* spec); +static channel* evdev_channel(instance* instance, char* spec, uint8_t flags); static int evdev_set(instance* inst, size_t num, channel** c, channel_value* v); static int evdev_handle(size_t num, managed_fd* fds); static int evdev_start(); diff --git a/backends/jack.c b/backends/jack.c index 926f800..e7bed04 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -409,7 +409,7 @@ static int mmjack_parse_midispec(mmjack_channel_ident* ident, char* spec){ return 0; } -static channel* mmjack_channel(instance* inst, char* spec){ +static channel* mmjack_channel(instance* inst, char* spec, uint8_t flags){ mmjack_instance_data* data = (mmjack_instance_data*) inst->impl; mmjack_channel_ident ident = { .label = 0 diff --git a/backends/jack.h b/backends/jack.h index 5598042..a7f3e8b 100644 --- a/backends/jack.h +++ b/backends/jack.h @@ -6,7 +6,7 @@ MM_PLUGIN_API int init(); static int mmjack_configure(char* option, char* value); static int mmjack_configure_instance(instance* inst, char* option, char* value); static instance* mmjack_instance(); -static channel* mmjack_channel(instance* inst, char* spec); +static channel* mmjack_channel(instance* inst, char* spec, uint8_t flags); static int mmjack_set(instance* inst, size_t num, channel** c, channel_value* v); static int mmjack_handle(size_t num, managed_fd* fds); static int mmjack_start(); diff --git a/backends/loopback.c b/backends/loopback.c index 0a45bde..41e6f85 100644 --- a/backends/loopback.c +++ b/backends/loopback.c @@ -49,7 +49,7 @@ static instance* loopback_instance(){ return i; } -static channel* loopback_channel(instance* inst, char* spec){ +static channel* loopback_channel(instance* inst, char* spec, uint8_t flags){ size_t u; loopback_instance_data* data = (loopback_instance_data*) inst->impl; diff --git a/backends/loopback.h b/backends/loopback.h index a08417b..ee51c66 100644 --- a/backends/loopback.h +++ b/backends/loopback.h @@ -4,7 +4,7 @@ MM_PLUGIN_API int init(); static int loopback_configure(char* option, char* value); static int loopback_configure_instance(instance* inst, char* option, char* value); static instance* loopback_instance(); -static channel* loopback_channel(instance* inst, char* spec); +static channel* loopback_channel(instance* inst, char* spec, uint8_t flags); static int loopback_set(instance* inst, size_t num, channel** c, channel_value* v); static int loopback_handle(size_t num, managed_fd* fds); static int loopback_start(); diff --git a/backends/lua.c b/backends/lua.c index 0b47b2c..40e6613 100644 --- a/backends/lua.c +++ b/backends/lua.c @@ -330,7 +330,7 @@ static instance* lua_instance(){ return inst; } -static channel* lua_channel(instance* inst, char* spec){ +static channel* lua_channel(instance* inst, char* spec, uint8_t flags){ size_t u; lua_instance_data* data = (lua_instance_data*) inst->impl; diff --git a/backends/lua.h b/backends/lua.h index e187a8e..4ea5b0a 100644 --- a/backends/lua.h +++ b/backends/lua.h @@ -13,7 +13,7 @@ MM_PLUGIN_API int init(); static int lua_configure(char* option, char* value); static int lua_configure_instance(instance* inst, char* option, char* value); static instance* lua_instance(); -static channel* lua_channel(instance* inst, char* spec); +static channel* lua_channel(instance* inst, char* spec, uint8_t flags); static int lua_set(instance* inst, size_t num, channel** c, channel_value* v); static int lua_handle(size_t num, managed_fd* fds); static int lua_start(); diff --git a/backends/maweb.c b/backends/maweb.c index 08156f2..d008cc0 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -229,7 +229,7 @@ static instance* maweb_instance(){ return inst; } -static channel* maweb_channel(instance* inst, char* spec){ +static channel* maweb_channel(instance* inst, char* spec, uint8_t flags){ maweb_instance_data* data = (maweb_instance_data*) inst->impl; maweb_channel_data chan = { 0 diff --git a/backends/maweb.h b/backends/maweb.h index 9091cda..05095f8 100644 --- a/backends/maweb.h +++ b/backends/maweb.h @@ -4,7 +4,7 @@ MM_PLUGIN_API int init(); static int maweb_configure(char* option, char* value); static int maweb_configure_instance(instance* inst, char* option, char* value); static instance* maweb_instance(); -static channel* maweb_channel(instance* inst, char* spec); +static channel* maweb_channel(instance* inst, char* spec, uint8_t flags); static int maweb_set(instance* inst, size_t num, channel** c, channel_value* v); static int maweb_handle(size_t num, managed_fd* fds); static int maweb_start(); diff --git a/backends/midi.c b/backends/midi.c index f380f59..92776ca 100644 --- a/backends/midi.c +++ b/backends/midi.c @@ -110,7 +110,7 @@ static int midi_configure_instance(instance* inst, char* option, char* value){ return 1; } -static channel* midi_channel(instance* inst, char* spec){ +static channel* midi_channel(instance* inst, char* spec, uint8_t flags){ midi_channel_ident ident = { .label = 0 }; diff --git a/backends/midi.h b/backends/midi.h index b9934f1..4e16f90 100644 --- a/backends/midi.h +++ b/backends/midi.h @@ -4,7 +4,7 @@ MM_PLUGIN_API int init(); static int midi_configure(char* option, char* value); static int midi_configure_instance(instance* instance, char* option, char* value); static instance* midi_instance(); -static channel* midi_channel(instance* instance, char* spec); +static channel* midi_channel(instance* instance, char* spec, uint8_t flags); static int midi_set(instance* inst, size_t num, channel** c, channel_value* v); static int midi_handle(size_t num, managed_fd* fds); static int midi_start(); diff --git a/backends/ola.cpp b/backends/ola.cpp index d069a8c..c13e8f9 100644 --- a/backends/ola.cpp +++ b/backends/ola.cpp @@ -68,7 +68,7 @@ static int ola_configure_instance(instance* inst, char* option, char* value){ return 1; } -static channel* ola_channel(instance* inst, char* spec){ +static channel* ola_channel(instance* inst, char* spec, uint8_t flags){ ola_instance_data* data = (ola_instance_data*) inst->impl; char* spec_next = spec; unsigned chan_a = strtoul(spec, &spec_next, 10); diff --git a/backends/ola.h b/backends/ola.h index 1637495..0c42bac 100644 --- a/backends/ola.h +++ b/backends/ola.h @@ -8,7 +8,7 @@ extern "C" { static int ola_configure(char* option, char* value); static int ola_configure_instance(instance* instance, char* option, char* value); static instance* ola_instance(); - static channel* ola_channel(instance* instance, char* spec); + static channel* ola_channel(instance* instance, char* spec, uint8_t flags); static int ola_set(instance* inst, size_t num, channel** c, channel_value* v); static int ola_handle(size_t num, managed_fd* fds); static int ola_start(); diff --git a/backends/osc.c b/backends/osc.c index d9f9139..757ad89 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -577,7 +577,7 @@ static instance* osc_instance(){ return inst; } -static channel* osc_map_channel(instance* inst, char* spec){ +static channel* osc_map_channel(instance* inst, char* spec, uint8_t flags){ size_t u, p; osc_instance_data* data = (osc_instance_data*) inst->impl; osc_channel_ident ident = { diff --git a/backends/osc.h b/backends/osc.h index 86be285..6f3b923 100644 --- a/backends/osc.h +++ b/backends/osc.h @@ -11,7 +11,7 @@ MM_PLUGIN_API int init(); static int osc_configure(char* option, char* value); static int osc_configure_instance(instance* inst, char* option, char* value); static instance* osc_instance(); -static channel* osc_map_channel(instance* inst, char* spec); +static channel* osc_map_channel(instance* inst, char* spec, uint8_t flags); static int osc_set(instance* inst, size_t num, channel** c, channel_value* v); static int osc_handle(size_t num, managed_fd* fds); static int osc_start(); diff --git a/backends/sacn.c b/backends/sacn.c index d8b3eb3..2229b8a 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -198,7 +198,7 @@ static instance* sacn_instance(){ return inst; } -static channel* sacn_channel(instance* inst, char* spec){ +static channel* sacn_channel(instance* inst, char* spec, uint8_t flags){ sacn_instance_data* data = (sacn_instance_data*) inst->impl; char* spec_next = spec; diff --git a/backends/sacn.h b/backends/sacn.h index 631d3a4..1d3268c 100644 --- a/backends/sacn.h +++ b/backends/sacn.h @@ -4,7 +4,7 @@ MM_PLUGIN_API int init(); static int sacn_configure(char* option, char* value); static int sacn_configure_instance(instance* instance, char* option, char* value); static instance* sacn_instance(); -static channel* sacn_channel(instance* instance, char* spec); +static channel* sacn_channel(instance* instance, char* spec, uint8_t flags); static int sacn_set(instance* inst, size_t num, channel** c, channel_value* v); static int sacn_handle(size_t num, managed_fd* fds); static int sacn_start(); diff --git a/backends/winmidi.c b/backends/winmidi.c index b274c06..790257b 100644 --- a/backends/winmidi.c +++ b/backends/winmidi.c @@ -110,7 +110,7 @@ static instance* winmidi_instance(){ return i; } -static channel* winmidi_channel(instance* inst, char* spec){ +static channel* winmidi_channel(instance* inst, char* spec, uint8_t flags){ char* next_token = NULL; winmidi_channel_ident ident = { .label = 0 diff --git a/backends/winmidi.h b/backends/winmidi.h index 8c2d76b..985c46a 100644 --- a/backends/winmidi.h +++ b/backends/winmidi.h @@ -4,7 +4,7 @@ MM_PLUGIN_API int init(); static int winmidi_configure(char* option, char* value); static int winmidi_configure_instance(instance* inst, char* option, char* value); static instance* winmidi_instance(); -static channel* winmidi_channel(instance* inst, char* spec); +static channel* winmidi_channel(instance* inst, char* spec, uint8_t flags); static int winmidi_set(instance* inst, size_t num, channel** c, channel_value* v); static int winmidi_handle(size_t num, managed_fd* fds); static int winmidi_start(); diff --git a/config.c b/config.c index 8e7e581..0b9173e 100644 --- a/config.c +++ b/config.c @@ -175,7 +175,7 @@ static int config_glob_scan(instance* inst, channel_spec* spec){ return 0; } -static channel* config_glob_resolve(instance* inst, channel_spec* spec, uint64_t n){ +static channel* config_glob_resolve(instance* inst, channel_spec* spec, uint64_t n, uint8_t map_direction){ size_t glob = 0, glob_length; ssize_t bytes = 0; uint64_t current_value = 0; @@ -216,7 +216,7 @@ static channel* config_glob_resolve(instance* inst, channel_spec* spec, uint64_t } } - result = inst->backend->channel(inst, resolved_spec); + result = inst->backend->channel(inst, resolved_spec, map_direction); if(spec->globs && !result){ fprintf(stderr, "Failed to match multichannel evaluation %s to a channel\n", resolved_spec); } @@ -294,8 +294,8 @@ static int config_map(char* to_raw, char* from_raw){ //iterate, resolve globs and map rv = 0; for(n = 0; !rv && n < max(spec_from.channels, spec_to.channels); n++){ - channel_from = config_glob_resolve(instance_from, &spec_from, min(n, spec_from.channels)); - channel_to = config_glob_resolve(instance_to, &spec_to, min(n, spec_to.channels)); + channel_from = config_glob_resolve(instance_from, &spec_from, min(n, spec_from.channels), mmchannel_input); + channel_to = config_glob_resolve(instance_to, &spec_to, min(n, spec_to.channels), mmchannel_output); if(!channel_from || !channel_to){ rv = 1; diff --git a/midimonster.h b/midimonster.h index 1192d6a..5ce0c73 100644 --- a/midimonster.h +++ b/midimonster.h @@ -87,8 +87,11 @@ struct _managed_fd; * Parse instance configuration from the user-supplied configuration * file. Returning a non-zero value fails config parsing. * * mmbackend_channel - * Parse a channel-spec to be mapped to/from. Returning NULL signals an - * out-of-memory condition and terminates the program. + * Parse a channel-spec to be mapped to/from. The `falgs` parameter supplies + * additional information to the parser, such as whether the channel is being + * queried for use as input (to the MIDIMonster core) and/or output + * (from the MIDIMonster core) channel (on a per-query basis). + * Returning NULL signals an out-of-memory condition and terminates the program. * * mmbackend_start * Called after all instances have been created and all mappings * have been set up. Only backends for which instances have been configured @@ -121,7 +124,7 @@ struct _managed_fd; */ typedef int (*mmbackend_handle_event)(struct _backend_instance* inst, size_t channels, struct _backend_channel** c, struct _channel_value* v); typedef struct _backend_instance* (*mmbackend_create_instance)(); -typedef struct _backend_channel* (*mmbackend_parse_channel)(struct _backend_instance* instance, char* spec); +typedef struct _backend_channel* (*mmbackend_parse_channel)(struct _backend_instance* instance, char* spec, uint8_t flags); typedef void (*mmbackend_free_channel)(struct _backend_channel* c); typedef int (*mmbackend_configure)(char* option, char* value); typedef int (*mmbackend_configure_instance)(struct _backend_instance* instance, char* option, char* value); @@ -130,6 +133,12 @@ typedef int (*mmbackend_start)(); typedef uint32_t (*mmbackend_interval)(); typedef int (*mmbackend_shutdown)(); +/* Bit masks for the `flags` parameter to mmbackend_parse_channel */ +typedef enum { + mmchannel_input = 0x1, + mmchannel_output = 0x2 +} mmbe_channel_flags; + /* Channel event value, .normalised is used by backends to determine channel values */ typedef struct _channel_value { union { -- cgit v1.2.3 From d92cf08ac473b2a904ba8873a7c7358e5440cb39 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 6 Dec 2019 18:11:45 +0100 Subject: Fix manpage section --- midimonster.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/midimonster.1 b/midimonster.1 index 8e97109..131ed44 100644 --- a/midimonster.1 +++ b/midimonster.1 @@ -1,4 +1,4 @@ -.TH MIDIMONSTER 8 "December 2019" +.TH MIDIMONSTER 1 "December 2019" .SH NAME midimonster \- Multi-protocol translation tool .SH SYNOPSIS -- cgit v1.2.3 From 96fe966928cd83f22aed388a11013b67c1a374a1 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 6 Dec 2019 18:58:59 +0100 Subject: Make install path for examples configurable --- Makefile | 5 +++-- README.md | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 8b2d7ec..8dab638 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ OBJS = config.o backend.o plugin.o PREFIX ?= /usr PLUGIN_INSTALL = $(PREFIX)/lib/midimonster +EXAMPLES ?= $(PREFIX)/share/midimonster SYSTEM := $(shell uname -s) CFLAGS ?= -g -Wall -Wpedantic @@ -68,8 +69,8 @@ install: install -m 0755 midimonster "$(DESTDIR)$(PREFIX)/bin" install -d "$(DESTDIR)$(PLUGIN_INSTALL)" install -m 0755 backends/*.so "$(DESTDIR)$(PLUGIN_INSTALL)" - install -d "$(DESTDIR)$(PREFIX)/share/midimonster" - install -m 0644 configs/* "$(DESTDIR)$(PREFIX)/share/midimonster" + install -d "$(DESTDIR)$(EXAMPLES)" + install -m 0644 configs/* "$(DESTDIR)$(EXAMPLES)" ifdef DEFAULT_CFG install -Dm 0644 monster.cfg "$(DESTDIR)$(DEFAULT_CFG)" endif diff --git a/README.md b/README.md index bcae9dd..9bcd913 100644 --- a/README.md +++ b/README.md @@ -159,12 +159,13 @@ For Linux and OSX, just running `make` in the source directory should do the tri The build process accepts the following parameters, either from the environment or as arguments to the `make` invocation: -| Target | Parameter | Default value | Description | -|---------------|-----------------------|-------------------------------|-------------------------------| -| build targets | `DEFAULT_CFG` | `monster.cfg` | Default configuration file | -| build targets | `PLUGINS` | Linux/OSX: `./backends/`, Windows: `backends\` | Backend plugin library path | -| `install` | `DESTDIR` | empty | Destination directory for packaging builds | -| `install` | `PREFIX` | `/usr` | Install prefix for binaries | +| Target | Parameter | Default value | Description | +|-------------------------------|-----------------------|-------------------------------|-------------------------------| +| build targets, `install` | `DEFAULT_CFG` | `monster.cfg` | Default configuration file | +| build targets, `install` | `PLUGINS` | Linux/OSX: `./backends/`, Windows: `backends\` | Backend plugin library path | +| `install` | `DESTDIR` | empty | Destination directory for packaging builds | +| `install` | `PREFIX` | `/usr` | Install prefix for binaries | +| `install` | `EXAMPLES` | `$(PREFIX)/share/midimonster` | Install path for example configurations | Some backends have been marked as optional as they require rather large additional software to be installed, for example the `ola` backend. To create a build including these, run `make full`. -- cgit v1.2.3 From 0468b5c5fafe0b6d72d8cd05613da3e705fa25c3 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 6 Dec 2019 19:05:41 +0100 Subject: Update the build parameters section with some explanations --- README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9bcd913..c7fd3c1 100644 --- a/README.md +++ b/README.md @@ -159,13 +159,19 @@ For Linux and OSX, just running `make` in the source directory should do the tri The build process accepts the following parameters, either from the environment or as arguments to the `make` invocation: -| Target | Parameter | Default value | Description | -|-------------------------------|-----------------------|-------------------------------|-------------------------------| -| build targets, `install` | `DEFAULT_CFG` | `monster.cfg` | Default configuration file | -| build targets, `install` | `PLUGINS` | Linux/OSX: `./backends/`, Windows: `backends\` | Backend plugin library path | -| `install` | `DESTDIR` | empty | Destination directory for packaging builds | -| `install` | `PREFIX` | `/usr` | Install prefix for binaries | -| `install` | `EXAMPLES` | `$(PREFIX)/share/midimonster` | Install path for example configurations | +| Target | Parameter | Default value | Description | +|---------------|-----------------------|-------------------------------|-------------------------------| +| build targets | `DEFAULT_CFG` | `monster.cfg` | Default configuration file | +| build targets | `PLUGINS` | Linux/OSX: `./backends/`, Windows: `backends\` | Backend plugin library path | +| `install` | `PREFIX` | `/usr` | Install prefix for binaries | +| `install` | `DESTDIR` | empty | Destination directory for packaging builds | +| `install` | `DEFAULT_CFG` | empty | Install path for default configuration file | +| `install` | `PLUGINS` | `$(PREFIX)/lib/midimonster` | Destination directory for packaging builds | +| `install` | `EXAMPLES` | `$(PREFIX)/share/midimonster` | Install path for example configurations | + +Note that the same variables may have different default values depending on the target. This implies that +builds that are destined to be installed require those variables to be set to the same value for the +build and `install` targets. Some backends have been marked as optional as they require rather large additional software to be installed, for example the `ola` backend. To create a build including these, run `make full`. -- cgit v1.2.3 From 01c8635205e25ba2e6c128010ad512cf03868bc2 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 6 Dec 2019 19:07:25 +0100 Subject: Fix variable description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7fd3c1..785d741 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ as arguments to the `make` invocation: | `install` | `PREFIX` | `/usr` | Install prefix for binaries | | `install` | `DESTDIR` | empty | Destination directory for packaging builds | | `install` | `DEFAULT_CFG` | empty | Install path for default configuration file | -| `install` | `PLUGINS` | `$(PREFIX)/lib/midimonster` | Destination directory for packaging builds | +| `install` | `PLUGINS` | `$(PREFIX)/lib/midimonster` | Install path for backend shared objects | | `install` | `EXAMPLES` | `$(PREFIX)/share/midimonster` | Install path for example configurations | Note that the same variables may have different default values depending on the target. This implies that -- cgit v1.2.3 From 2cb91753b2cab927fca9107128519872ac70665d Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 19:58:16 +0100 Subject: Initial installer release --- installer.sh | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 installer.sh diff --git a/installer.sh b/installer.sh new file mode 100644 index 0000000..fa898fb --- /dev/null +++ b/installer.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +################################################ SETUP ################################################ +deps=(libasound2-dev libevdev-dev liblua5.3-dev libola-dev libjack-jackd2-dev pkg-config libssl-dev gcc make wget git) +user=$(whoami) # for bypassing user check replace "$(whoami)" with "root". + +script_path="`cd $0; pwd`" # Script dir +tmp_path=$(mktemp -d) # Repo download path + +Iversion="v0.2" # (fallback version if ) +makeargs=full # Build args + +VAR_DESTDIR="" # Unused +VAR_PREFIX="/usr" +VAR_PLUGINS="$VAR_PREFIX/lib/midimonster" +VAR_DEFAULT_CFG="/etc/midimonster/midimonster.cfg" +VAR_EXAMPLE_CFGS="$VAR_PREFIX/share/midimonster" + +################################################ SETUP ################################################ + +############################################## FUNCTIONS ############################################## + +INSTALL-DEPS () { ##Install deps from array "$deps" +for t in ${deps[@]}; do + if [ $(dpkg-query -W -f='${Status}' $t 2>/dev/null | grep -c "ok installed") -eq 0 ]; + then + echo "Installing "$t""; + apt-get install $t -Y; + echo "Done."; + else + echo ""$t" already installed!" + + fi +done +echo "" +} + +INSTALL-PREP () { + echo "Starting Git!" + git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster + Iversion=(git describe --abbrev=0) # Get last tag(stable version) + echo "Starting Git checkout to "$Iversion"" + git checkout $Iversion $tmp_path + + echo "" + + read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX + VAR_PREFIX="${input:-$VAR_PREFIX}" + + read -e -i "$VAR_PLUGINS" -p "PLUGINS (Plugin directory): " input # Reads VAR_PLUGINS + VAR_PLUGINS="${input:-$VAR_PLUGINS}" + + read -e -i "$VAR_DEFAULT_CFG" -p "Default config path: " input # Reads VAR_DEFAULT_CFG + VAR_DEFAULT_CFG="${input:-$VAR_DEFAULT_CFG}" + + read -e -i "$VAR_EXAMPLE_CFGS" -p "Example config directory: " input # Reads VAR_EXAMPLE_CFGS + VAR_EXAMPLE_CFGS="${input:-$VAR_EXAMPLE_CFGS}" + + + export PREFIX=$VAR_PREFIX + export PLUGINS=$VAR_PLUGINS + export DEFAULT_CFG=$VAR_DEFAULT_CFG + export DESTDIR=$VAR_DESTDIR + export EXAMPLES=$VAR_EXAMPLE_CFGS +} + +INSTALL-RUN () { # Build + cd "$tmp_path" + make clean + make $makeargs + make install +} + +ERROR () { + echo "Aborting..." + CLEAN + exit 1 +} + +DONE () { + echo Done. + CLEAN + exit 0 +} + +CLEAN () { + echo "Cleaning..." + rm -rf $tmp_path +} + +############################################## FUNCTIONS ############################################## + + +################################################ Main ################################################# + +trap ERROR SIGINT SIGTERM SIGKILL +clear + +if [ $user != "root" ]; then # Check if $user = root! + echo "Installer must be run as root" + ERROR +fi + +if [ $(wget -q --spider http://github.com) $? -eq 0 ]; then "INSTALL-DEPS"; else echo You need connection to the internet; ERROR ; fi + +INSTALL-PREP +echo "" +INSTALL-RUN +DONE \ No newline at end of file -- cgit v1.2.3 From 0e7645ddbd3dfa20ccc246c4aa50a3299fdb708e Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 20:04:56 +0100 Subject: Change $makeargs to "all" --- installer.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer.sh b/installer.sh index fa898fb..bf2775c 100644 --- a/installer.sh +++ b/installer.sh @@ -8,7 +8,7 @@ script_path="`cd $0; pwd`" # Script dir tmp_path=$(mktemp -d) # Repo download path Iversion="v0.2" # (fallback version if ) -makeargs=full # Build args +makeargs=all # Build args VAR_DESTDIR="" # Unused VAR_PREFIX="/usr" @@ -25,7 +25,7 @@ for t in ${deps[@]}; do if [ $(dpkg-query -W -f='${Status}' $t 2>/dev/null | grep -c "ok installed") -eq 0 ]; then echo "Installing "$t""; - apt-get install $t -Y; + apt-get install $t -y; echo "Done."; else echo ""$t" already installed!" -- cgit v1.2.3 From 980e3d84c3da1be28d6e46d8f78ae1816961eb9d Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 20:09:08 +0100 Subject: Remove ola from deps --- installer.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer.sh b/installer.sh index bf2775c..6d438a7 100644 --- a/installer.sh +++ b/installer.sh @@ -1,7 +1,7 @@ #!/bin/bash ################################################ SETUP ################################################ -deps=(libasound2-dev libevdev-dev liblua5.3-dev libola-dev libjack-jackd2-dev pkg-config libssl-dev gcc make wget git) +deps=(libasound2-dev libevdev-dev liblua5.3-dev libjack-jackd2-dev pkg-config libssl-dev gcc make wget git) user=$(whoami) # for bypassing user check replace "$(whoami)" with "root". script_path="`cd $0; pwd`" # Script dir @@ -25,7 +25,7 @@ for t in ${deps[@]}; do if [ $(dpkg-query -W -f='${Status}' $t 2>/dev/null | grep -c "ok installed") -eq 0 ]; then echo "Installing "$t""; - apt-get install $t -y; + apt-get install $t; echo "Done."; else echo ""$t" already installed!" -- cgit v1.2.3 From df07cea946efc5bffb43b25855607f2762a70643 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 20:22:16 +0100 Subject: todo --- installer_todo | 1 + 1 file changed, 1 insertion(+) create mode 100644 installer_todo diff --git a/installer_todo b/installer_todo new file mode 100644 index 0000000..c9935ae --- /dev/null +++ b/installer_todo @@ -0,0 +1 @@ +-Updater (Remote Repo letzten tag lesen und mit lokaler installation abgleichen) \ No newline at end of file -- cgit v1.2.3 From f8d34ee6a8de3fe64339a2d1cbce767cbee2e520 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 22:06:18 +0100 Subject: Fix git checkout error with git init --- installer.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/installer.sh b/installer.sh index 6d438a7..eab9f50 100644 --- a/installer.sh +++ b/installer.sh @@ -40,6 +40,7 @@ INSTALL-PREP () { git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster Iversion=(git describe --abbrev=0) # Get last tag(stable version) echo "Starting Git checkout to "$Iversion"" + git init $tmp_path git checkout $Iversion $tmp_path echo "" -- cgit v1.2.3 From a04b0d13d9248f89b9fe71f9d433ad44aac99116 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 22:21:44 +0100 Subject: Added update to README --- installer.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 installer.sh diff --git a/installer.sh b/installer.sh old mode 100644 new mode 100755 -- cgit v1.2.3 From 7e59d4832f819abe0bc981ebdac20f6e12a031e7 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 22:28:04 +0100 Subject: Added update to README --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 785d741..1f22657 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,14 @@ for example ``` make jack.so ``` +#### Buiding with Installer + +For easy installation, the following steps are required: + +``` +wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh ./ +./installer.sh +``` #### Building for packaging or installation -- cgit v1.2.3 From 553633e0ab0191756bb5b8810a461168dfc66a3d Mon Sep 17 00:00:00 2001 From: Spacelord Date: Fri, 6 Dec 2019 22:37:40 +0100 Subject: added chmod +x to Installer README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1f22657..e925541 100644 --- a/README.md +++ b/README.md @@ -188,6 +188,7 @@ For easy installation, the following steps are required: ``` wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh ./ +chmod +x ./installer.sh ./installer.sh ``` -- cgit v1.2.3 From 34b8dd5c71615724408022db37dcf94576a12280 Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 6 Dec 2019 22:51:56 +0100 Subject: Add link to installer section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f22657..9052034 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ make jack.so ``` #### Buiding with Installer -For easy installation, the following steps are required: +For easy installation on Linux, the [installer script](installer.sh) can be used: ``` wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh ./ -- cgit v1.2.3 From 2fb3801be65cd98a6069f503897da93033b5049e Mon Sep 17 00:00:00 2001 From: Spacelord Date: Sat, 7 Dec 2019 15:22:58 +0100 Subject: Convert user check to 1line --- installer.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/installer.sh b/installer.sh index eab9f50..1a6301c 100755 --- a/installer.sh +++ b/installer.sh @@ -97,10 +97,7 @@ CLEAN () { trap ERROR SIGINT SIGTERM SIGKILL clear -if [ $user != "root" ]; then # Check if $user = root! - echo "Installer must be run as root" - ERROR -fi +if [ $user != "root" ]; then echo "Installer must be run as root"; ERROR; fi # Check if $user = root! if [ $(wget -q --spider http://github.com) $? -eq 0 ]; then "INSTALL-DEPS"; else echo You need connection to the internet; ERROR ; fi -- cgit v1.2.3 From 95eac9cccb2cba39446f83e8803565f018fa411b Mon Sep 17 00:00:00 2001 From: Spacelord Date: Sat, 7 Dec 2019 16:36:09 +0100 Subject: Git checkout fix (again) --- installer.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/installer.sh b/installer.sh index 1a6301c..ae6518e 100755 --- a/installer.sh +++ b/installer.sh @@ -41,8 +41,10 @@ INSTALL-PREP () { Iversion=(git describe --abbrev=0) # Get last tag(stable version) echo "Starting Git checkout to "$Iversion"" git init $tmp_path - git checkout $Iversion $tmp_path - + ( + cd $tmp_path + git checkout $Iversion $tmp_path + ) echo "" read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX -- cgit v1.2.3 From 2e1c2f63ef728027ebb8183599a4ebba734c8a04 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Sat, 7 Dec 2019 16:41:44 +0100 Subject: checkout fix again (bugfix) --- installer.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/installer.sh b/installer.sh index ae6518e..dab1afc 100755 --- a/installer.sh +++ b/installer.sh @@ -41,10 +41,7 @@ INSTALL-PREP () { Iversion=(git describe --abbrev=0) # Get last tag(stable version) echo "Starting Git checkout to "$Iversion"" git init $tmp_path - ( - cd $tmp_path - git checkout $Iversion $tmp_path - ) + (cd $tmp_path; git checkout $Iversion) echo "" read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX -- cgit v1.2.3 From c038fee6bd4888749691299456f8e95611677e43 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Sat, 7 Dec 2019 17:40:35 +0100 Subject: git checkout bug fix.. --- installer.sh | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/installer.sh b/installer.sh index dab1afc..fc544f6 100755 --- a/installer.sh +++ b/installer.sh @@ -7,7 +7,7 @@ user=$(whoami) # for bypassing user check replace "$(whoami)" w script_path="`cd $0; pwd`" # Script dir tmp_path=$(mktemp -d) # Repo download path -Iversion="v0.2" # (fallback version if ) +Iversion="TEST!" # (fallback version if ) makeargs=all # Build args VAR_DESTDIR="" # Unused @@ -38,10 +38,35 @@ echo "" INSTALL-PREP () { echo "Starting Git!" git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster - Iversion=(git describe --abbrev=0) # Get last tag(stable version) - echo "Starting Git checkout to "$Iversion"" + +( + echo "" + echo "" + cd $tmp_path + echo "IVer.: $Iversion" + + echo "Start GIT INIT" git init $tmp_path - (cd $tmp_path; git checkout $Iversion) + + echo "IVer.: $Iversion VOR GIT DESCRIBE!" + echo "" + + + echo "Starting git describe.." + Iversion=$(git describe --abbrev=0) # Get last tag(stable version) + echo "IVer.: $Iversion NACH GIT DESCRIBE!" + + echo "" + + + echo "Starting Git checkout to "$Iversion"" + git checkout $Iversion + ) + echo "" + echo "Done. (Iver.: $Iversion)" + + + echo "" read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX -- cgit v1.2.3 From 565c75ff0c0b828b370179e0b877d629503794e5 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Sat, 7 Dec 2019 18:17:05 +0100 Subject: Finally git checkout bug with subshell fixed. --- installer.sh | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/installer.sh b/installer.sh index fc544f6..fd4dd91 100755 --- a/installer.sh +++ b/installer.sh @@ -7,7 +7,6 @@ user=$(whoami) # for bypassing user check replace "$(whoami)" w script_path="`cd $0; pwd`" # Script dir tmp_path=$(mktemp -d) # Repo download path -Iversion="TEST!" # (fallback version if ) makeargs=all # Build args VAR_DESTDIR="" # Unused @@ -36,37 +35,24 @@ echo "" } INSTALL-PREP () { - echo "Starting Git!" - git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster - -( +(#### Subshell make things like cd $tmp_path easier to revert + echo "Starting download..." + git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster echo "" echo "" + echo "Initializing repository..." cd $tmp_path - echo "IVer.: $Iversion" - - echo "Start GIT INIT" git init $tmp_path - - echo "IVer.: $Iversion VOR GIT DESCRIBE!" echo "" - - - echo "Starting git describe.." + echo "Finding latest stable version..." Iversion=$(git describe --abbrev=0) # Get last tag(stable version) - echo "IVer.: $Iversion NACH GIT DESCRIBE!" - - echo "" + echo "Starting Git checkout to "$Iversion"..." + git checkout -f -q $Iversion + echo "Done." + ) - - echo "Starting Git checkout to "$Iversion"" - git checkout $Iversion - ) echo "" - echo "Done. (Iver.: $Iversion)" - - - + echo "" echo "" read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX @@ -117,7 +103,6 @@ CLEAN () { ################################################ Main ################################################# - trap ERROR SIGINT SIGTERM SIGKILL clear -- cgit v1.2.3 From 1bb3b9a3eaf94af045c39a1ff1ee8bf9b8e5b8ec Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 7 Dec 2019 20:22:03 +0100 Subject: Mention debianization in README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 454284f..8d38565 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ for example ``` make jack.so ``` -#### Buiding with Installer +#### Using the installer For easy installation on Linux, the [installer script](installer.sh) can be used: @@ -208,6 +208,9 @@ make install Depending on your configuration of `DESTDIR`, the `make install` step may require root privileges to install the binaries to the appropriate destinations. +To create Debian packages, use the debianization and `git-buildpackage` configuration on the `debian/master` +branch. Simply running `gbp buildpackage` should build a package for the last tagged release. + #### Building for Windows To build for Windows, you still need to compile on a Linux machine (virtual machines work well for this). -- cgit v1.2.3 From 4ca0acff460c1c02a11cb9f246fb755cd4f4f792 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sun, 8 Dec 2019 02:27:57 +0100 Subject: Minor logic cleanup --- backends/artnet.c | 12 ++---------- backends/sacn.c | 10 ++-------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/backends/artnet.c b/backends/artnet.c index 57eb7b1..e01f038 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -77,16 +77,12 @@ static int artnet_configure(char* option, char* value){ else if(!strcmp(option, "bind")){ mmbackend_parse_hostspec(value, &host, &port); - if(!port){ - port = ARTNET_PORT; - } - if(!host){ fprintf(stderr, "Not valid ArtNet bind address given\n"); return 1; } - if(artnet_listener(host, port)){ + if(artnet_listener(host, (port ? port : ARTNET_PORT))){ fprintf(stderr, "Failed to bind ArtNet descriptor: %s\n", value); return 1; } @@ -140,16 +136,12 @@ static int artnet_configure_instance(instance* inst, char* option, char* value){ else if(!strcmp(option, "dest") || !strcmp(option, "destination")){ mmbackend_parse_hostspec(value, &host, &port); - if(!port){ - port = ARTNET_PORT; - } - if(!host){ fprintf(stderr, "Not a valid ArtNet destination for instance %s\n", inst->name); return 1; } - return mmbackend_parse_sockaddr(host, port, &data->dest_addr, &data->dest_len); + return mmbackend_parse_sockaddr(host, port ? port : ARTNET_PORT, &data->dest_addr, &data->dest_len); } fprintf(stderr, "Unknown ArtNet option %s for instance %s\n", option, inst->name); diff --git a/backends/sacn.c b/backends/sacn.c index 2229b8a..edb648d 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -111,16 +111,13 @@ static int sacn_configure(char* option, char* value){ } else if(!strcmp(option, "bind")){ mmbackend_parse_hostspec(value, &host, &port); - if(!port){ - port = SACN_PORT; - } if(!host){ fprintf(stderr, "No valid sACN bind address provided\n"); return 1; } - if(sacn_listener(host, port, flags)){ + if(sacn_listener(host, port ? port : SACN_PORT, flags)){ fprintf(stderr, "Failed to bind sACN descriptor: %s\n", value); return 1; } @@ -155,16 +152,13 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ } else if(!strcmp(option, "destination")){ mmbackend_parse_hostspec(value, &host, &port); - if(!port){ - port = SACN_PORT; - } if(!host){ fprintf(stderr, "No valid sACN destination for instance %s\n", inst->name); return 1; } - return mmbackend_parse_sockaddr(host, port, &data->dest_addr, &data->dest_len); + return mmbackend_parse_sockaddr(host, port ? port : SACN_PORT, &data->dest_addr, &data->dest_len); } else if(!strcmp(option, "from")){ next = value; -- cgit v1.2.3 From 31cc72f660513b033cc0621782586562bafab08e Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 10 Dec 2019 22:35:59 +0100 Subject: Fix bug in sACN config parsing --- TODO | 12 +++--------- backends/osc.c | 1 + backends/sacn.c | 1 + installer_todo | 1 - 4 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 installer_todo diff --git a/TODO b/TODO index cba1c15..f6fc728 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,9 @@ -winmidi -rename -release - -MIDI NRPN keepalive channels per backend? mm_backend_start might get some arguments so they don't have to fetch them all the time -mm_channel_resolver might get additional info about the mapping direction Note source in channel value struct Optimize core channel search (store backend offset) -mm_managed_fd.impl is not freed currently +mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway) -> documentation + +installer: implement an upgrade mode (check for newer versions in the repo) -rtpmidi mode=peer - mode=initiator diff --git a/backends/osc.c b/backends/osc.c index 757ad89..b12ae40 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -522,6 +522,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ return 1; } + //this requests a socket with SO_BROADCAST set, whether this is useful functionality for OSC is up for debate data->fd = mmbackend_socket(host, port, SOCK_DGRAM, 1, 1); if(data->fd < 0){ fprintf(stderr, "Failed to bind for instance %s\n", inst->name); diff --git a/backends/sacn.c b/backends/sacn.c index edb648d..75c327e 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -171,6 +171,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ } else if(!strcmp(option, "unicast")){ data->unicast_input = strtoul(value, NULL, 10); + return 0; } fprintf(stderr, "Unknown configuration option %s for sACN backend\n", option); diff --git a/installer_todo b/installer_todo deleted file mode 100644 index c9935ae..0000000 --- a/installer_todo +++ /dev/null @@ -1 +0,0 @@ --Updater (Remote Repo letzten tag lesen und mit lokaler installation abgleichen) \ No newline at end of file -- cgit v1.2.3 From e517dbe783e65fdd1c80f5c917f8f924e2adfe8d Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 10 Dec 2019 23:28:02 +0100 Subject: Implement rudimentary argument parsing --- Makefile | 8 +++++++- midimonster.c | 27 ++++++++++++++++++++++++--- midimonster.h | 5 +++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 8dab638..5183fa5 100644 --- a/Makefile +++ b/Makefile @@ -5,13 +5,19 @@ PREFIX ?= /usr PLUGIN_INSTALL = $(PREFIX)/lib/midimonster EXAMPLES ?= $(PREFIX)/share/midimonster SYSTEM := $(shell uname -s) +GITVERSION = $(shell git describe) +# Default compilation CFLAGS CFLAGS ?= -g -Wall -Wpedantic +#CFLAGS += -DDEBUG # Hide all non-API symbols for export CFLAGS += -fvisibility=hidden -#CFLAGS += -DDEBUG midimonster: LDLIBS = -ldl +# Replace version string with current git-describe if possible +ifneq "$(GITVERSION)" "" +midimonster: CFLAGS += "-DMIDIMONSTER_VERSION=\"$(GITVERSION)\"" +endif # Work around strange linker passing convention differences in Linux and OSX ifeq ($(SYSTEM),Linux) diff --git a/midimonster.c b/midimonster.c index e6c0842..67614d4 100644 --- a/midimonster.c +++ b/midimonster.c @@ -223,8 +223,12 @@ static void event_free(){ } } +static void version(){ + fprintf(stderr, "MIDIMonster %s\n", MIDIMONSTER_VERSION); +} + static int usage(char* fn){ - fprintf(stderr, "MIDIMonster v0.3\n"); + version(); fprintf(stderr, "Usage:\n"); fprintf(stderr, "\t%s \n", fn); return EXIT_FAILURE; @@ -263,6 +267,21 @@ static int platform_initialize(){ return 0; } +static int args_parse(int argc, char** argv, char** cfg_file){ + size_t u; + for(u = 1; u < argc; u++){ + if(!strcmp(argv[u], "-v") || !strcmp(argv[u], "--version")){ + version(); + return 1; + } + + //if nothing else matches, it's probably the configuration file + *cfg_file = argv[u]; + } + + return 0; +} + int main(int argc, char** argv){ fd_set all_fds, read_fds; event_collection* secondary = NULL; @@ -271,8 +290,10 @@ int main(int argc, char** argv){ managed_fd* signaled_fds = NULL; int rv = EXIT_FAILURE, error, maxfd = -1; char* cfg_file = DEFAULT_CFG; - if(argc > 1){ - cfg_file = argv[1]; + + //parse commandline arguments + if(args_parse(argc, argv, &cfg_file)){ + return EXIT_FAILURE; } if(platform_initialize()){ diff --git a/midimonster.h b/midimonster.h index 5ce0c73..677eeee 100644 --- a/midimonster.h +++ b/midimonster.h @@ -5,6 +5,11 @@ #include #include +/* Core version unless set by the build process */ +#ifndef MIDIMONSTER_VERSION + #define MIDIMONSTER_VERSION "v0.3-dist" +#endif + /* API call attributes and visibilities */ #ifndef MM_API #ifdef _WIN32 -- cgit v1.2.3 From ec01135171e4a57450e0250cf08cd4d60a8ad9ee Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 11 Dec 2019 22:38:46 +0100 Subject: Fix makefile indentation --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 5183fa5..1f6f212 100644 --- a/Makefile +++ b/Makefile @@ -71,14 +71,14 @@ run: valgrind --leak-check=full --show-leak-kinds=all ./midimonster install: - install -d "$(DESTDIR)$(PREFIX)/bin" - install -m 0755 midimonster "$(DESTDIR)$(PREFIX)/bin" - install -d "$(DESTDIR)$(PLUGIN_INSTALL)" - install -m 0755 backends/*.so "$(DESTDIR)$(PLUGIN_INSTALL)" - install -d "$(DESTDIR)$(EXAMPLES)" - install -m 0644 configs/* "$(DESTDIR)$(EXAMPLES)" + install -d "$(DESTDIR)$(PREFIX)/bin" + install -m 0755 midimonster "$(DESTDIR)$(PREFIX)/bin" + install -d "$(DESTDIR)$(PLUGIN_INSTALL)" + install -m 0755 backends/*.so "$(DESTDIR)$(PLUGIN_INSTALL)" + install -d "$(DESTDIR)$(EXAMPLES)" + install -m 0644 configs/* "$(DESTDIR)$(EXAMPLES)" ifdef DEFAULT_CFG - install -Dm 0644 monster.cfg "$(DESTDIR)$(DEFAULT_CFG)" + install -Dm 0644 monster.cfg "$(DESTDIR)$(DEFAULT_CFG)" endif sanitize: export CC = clang -- cgit v1.2.3 From e60eff52920cf063e7625344764521a791c8be3e Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 11 Dec 2019 22:41:43 +0100 Subject: Remove unnecessary quotes --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1f6f212..75c9d0d 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ CFLAGS += -fvisibility=hidden midimonster: LDLIBS = -ldl # Replace version string with current git-describe if possible ifneq "$(GITVERSION)" "" -midimonster: CFLAGS += "-DMIDIMONSTER_VERSION=\"$(GITVERSION)\"" +midimonster: CFLAGS += -DMIDIMONSTER_VERSION=\"$(GITVERSION)\" endif # Work around strange linker passing convention differences in Linux and OSX -- cgit v1.2.3 From f65fb8baaba285f5ff4b02af111420ba4479f5d9 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 11 Dec 2019 23:02:22 +0100 Subject: Simplify plugin_start API --- TODO | 1 - backend.c | 20 +++++++++++++++++--- backends/artnet.c | 18 ++---------------- backends/artnet.h | 2 +- backends/evdev.c | 18 ++---------------- backends/evdev.h | 2 +- backends/jack.c | 12 ++---------- backends/jack.h | 2 +- backends/loopback.c | 2 +- backends/loopback.h | 2 +- backends/lua.c | 13 ++----------- backends/lua.h | 2 +- backends/maweb.c | 16 ++-------------- backends/midi.c | 17 ++--------------- backends/midi.h | 2 +- backends/ola.cpp | 13 ++----------- backends/ola.h | 2 +- backends/osc.c | 19 ++----------------- backends/osc.h | 2 +- backends/sacn.c | 17 ++--------------- backends/sacn.h | 2 +- backends/winmidi.c | 18 ++---------------- backends/winmidi.h | 2 +- midimonster.h | 2 +- 24 files changed, 49 insertions(+), 157 deletions(-) diff --git a/TODO b/TODO index f6fc728..1f1269d 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ keepalive channels per backend? -mm_backend_start might get some arguments so they don't have to fetch them all the time Note source in channel value struct Optimize core channel search (store backend offset) diff --git a/backend.c b/backend.c index 3a18f41..f5efca7 100644 --- a/backend.c +++ b/backend.c @@ -256,20 +256,34 @@ MM_API int mm_backend_register(backend b){ int backends_start(){ int rv = 0, current; - size_t u, p; + size_t n, u, p; + instance** inst = NULL; + for(u = 0; u < nbackends; u++){ //only start backends that have instances for(p = 0; p < ninstances && instances[p]->backend != backends + u; p++){ } + + //backend has no instances, skip the start call if(p == ninstances){ - fprintf(stderr, "Skipping start of backend %s\n", backends[u].name); continue; } + + //fetch list of instances + if(mm_backend_instances(backends[u].name, &n, &inst)){ + fprintf(stderr, "Failed to fetch instance list for initialization of backend %s\n", backends[u].name); + return 1; + } - current = backends[u].start(); + //start the backend + current = backends[u].start(n, inst); if(current){ fprintf(stderr, "Failed to start backend %s\n", backends[u].name); } + + //clean up + free(inst); + inst = NULL; rv |= current; } return rv; diff --git a/backends/artnet.c b/backends/artnet.c index e01f038..e4147ec 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -381,28 +381,15 @@ static int artnet_handle(size_t num, managed_fd* fds){ return 0; } -static int artnet_start(){ - size_t n, u, p; +static int artnet_start(size_t n, instance** inst){ + size_t u, p; int rv = 1; - instance** inst = NULL; artnet_instance_data* data = NULL; artnet_instance_id id = { .label = 0 }; - //fetch all defined instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - - if(!n){ - free(inst); - return 0; - } - if(!artnet_fds){ - free(inst); fprintf(stderr, "Failed to start ArtNet backend: no descriptors bound\n"); return 1; } @@ -448,7 +435,6 @@ static int artnet_start(){ rv = 0; bail: - free(inst); return rv; } diff --git a/backends/artnet.h b/backends/artnet.h index f6a6709..738b55c 100644 --- a/backends/artnet.h +++ b/backends/artnet.h @@ -10,7 +10,7 @@ static instance* artnet_instance(); static channel* artnet_channel(instance* instance, char* spec, uint8_t flags); static int artnet_set(instance* inst, size_t num, channel** c, channel_value* v); static int artnet_handle(size_t num, managed_fd* fds); -static int artnet_start(); +static int artnet_start(size_t n, instance** inst); static int artnet_shutdown(); #define ARTNET_PORT "6454" diff --git a/backends/evdev.c b/backends/evdev.c index 0da5ae6..9998a03 100644 --- a/backends/evdev.c +++ b/backends/evdev.c @@ -393,21 +393,10 @@ static int evdev_handle(size_t num, managed_fd* fds){ return 0; } -static int evdev_start(){ - size_t n, u, fds = 0; - instance** inst = NULL; +static int evdev_start(size_t n, instance** inst){ + size_t u, fds = 0; evdev_instance_data* data = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - - if(!n){ - free(inst); - return 0; - } - for(u = 0; u < n; u++){ data = (evdev_instance_data*) inst[u]->impl; @@ -415,7 +404,6 @@ static int evdev_start(){ if(data->output_enabled){ if(libevdev_uinput_create_from_device(data->output_proto, LIBEVDEV_UINPUT_OPEN_MANAGED, &data->output_ev)){ fprintf(stderr, "Failed to create evdev output device: %s\n", strerror(errno)); - free(inst); return 1; } fprintf(stderr, "Created device node %s for instance %s\n", libevdev_uinput_get_devnode(data->output_ev), inst[u]->name); @@ -426,7 +414,6 @@ static int evdev_start(){ if(data->input_fd >= 0){ if(mm_manage_fd(data->input_fd, BACKEND_NAME, 1, inst[u])){ fprintf(stderr, "Failed to register event input descriptor for instance %s\n", inst[u]->name); - free(inst); return 1; } fds++; @@ -439,7 +426,6 @@ static int evdev_start(){ } fprintf(stderr, "evdev backend registered %zu descriptors to core\n", fds); - free(inst); return 0; } diff --git a/backends/evdev.h b/backends/evdev.h index 6504416..1f03941 100644 --- a/backends/evdev.h +++ b/backends/evdev.h @@ -15,7 +15,7 @@ static instance* evdev_instance(); static channel* evdev_channel(instance* instance, char* spec, uint8_t flags); static int evdev_set(instance* inst, size_t num, channel** c, channel_value* v); static int evdev_handle(size_t num, managed_fd* fds); -static int evdev_start(); +static int evdev_start(size_t n, instance** inst); static int evdev_shutdown(); #define INPUT_NODES "/dev/input" diff --git a/backends/jack.c b/backends/jack.c index e7bed04..047dce8 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -593,10 +593,9 @@ static int mmjack_handle(size_t num, managed_fd* fds){ return 0; } -static int mmjack_start(){ +static int mmjack_start(size_t n, instance** inst){ int rv = 1, feedback_fd[2]; - size_t n, u, p; - instance** inst = NULL; + size_t u, p; pthread_mutexattr_t mutex_attr; mmjack_instance_data* data = NULL; jack_status_t error; @@ -618,12 +617,6 @@ static int mmjack_start(){ goto bail; } - //fetch all instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - goto bail; - } - for(u = 0; u < n; u++){ data = (mmjack_instance_data*) inst[u]->impl; @@ -689,7 +682,6 @@ static int mmjack_start(){ rv = 0; bail: pthread_mutexattr_destroy(&mutex_attr); - free(inst); return rv; } diff --git a/backends/jack.h b/backends/jack.h index a7f3e8b..c9f8c4c 100644 --- a/backends/jack.h +++ b/backends/jack.h @@ -9,7 +9,7 @@ static instance* mmjack_instance(); static channel* mmjack_channel(instance* inst, char* spec, uint8_t flags); static int mmjack_set(instance* inst, size_t num, channel** c, channel_value* v); static int mmjack_handle(size_t num, managed_fd* fds); -static int mmjack_start(); +static int mmjack_start(size_t n, instance** inst); static int mmjack_shutdown(); #define JACK_DEFAULT_CLIENT_NAME "MIDIMonster" diff --git a/backends/loopback.c b/backends/loopback.c index 41e6f85..616eccf 100644 --- a/backends/loopback.c +++ b/backends/loopback.c @@ -92,7 +92,7 @@ static int loopback_handle(size_t num, managed_fd* fds){ return 0; } -static int loopback_start(){ +static int loopback_start(size_t n, instance** inst){ return 0; } diff --git a/backends/loopback.h b/backends/loopback.h index ee51c66..dee3e9d 100644 --- a/backends/loopback.h +++ b/backends/loopback.h @@ -7,7 +7,7 @@ static instance* loopback_instance(); static channel* loopback_channel(instance* inst, char* spec, uint8_t flags); static int loopback_set(instance* inst, size_t num, channel** c, channel_value* v); static int loopback_handle(size_t num, managed_fd* fds); -static int loopback_start(); +static int loopback_start(size_t n, instance** inst); static int loopback_shutdown(); typedef struct /*_loopback_instance_data*/ { diff --git a/backends/lua.c b/backends/lua.c index 40e6613..b165dd8 100644 --- a/backends/lua.c +++ b/backends/lua.c @@ -428,17 +428,10 @@ static int lua_handle(size_t num, managed_fd* fds){ return 0; } -static int lua_start(){ - size_t n, u, p; - instance** inst = NULL; +static int lua_start(size_t n, instance** inst){ + size_t u, p; lua_instance_data* data = NULL; - //fetch all defined instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - //resolve channels to their handler functions for(u = 0; u < n; u++){ data = (lua_instance_data*) inst[u]->impl; @@ -457,8 +450,6 @@ static int lua_start(){ } } - free(inst); - #ifdef MMBACKEND_LUA_TIMERFD //register the timer with the core fprintf(stderr, "Lua backend registering 1 descriptor to core\n"); diff --git a/backends/lua.h b/backends/lua.h index 4ea5b0a..9e19506 100644 --- a/backends/lua.h +++ b/backends/lua.h @@ -16,7 +16,7 @@ static instance* lua_instance(); static channel* lua_channel(instance* inst, char* spec, uint8_t flags); static int lua_set(instance* inst, size_t num, channel** c, channel_value* v); static int lua_handle(size_t num, managed_fd* fds); -static int lua_start(); +static int lua_start(size_t n, instance** inst); static int lua_shutdown(); #ifndef MMBACKEND_LUA_TIMERFD static uint32_t lua_interval(); diff --git a/backends/maweb.c b/backends/maweb.c index d008cc0..28cad0c 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -989,17 +989,10 @@ static int maweb_handle(size_t num, managed_fd* fds){ return rv; } -static int maweb_start(){ - size_t n, u, p; - instance** inst = NULL; +static int maweb_start(size_t n, instance** inst){ + size_t u, p; maweb_instance_data* data = NULL; - //fetch all defined instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ //sort channels data = (maweb_instance_data*) inst[u]->impl; @@ -1017,11 +1010,6 @@ static int maweb_start(){ } } - free(inst); - if(!n){ - return 0; - } - fprintf(stderr, "maweb backend registering %" PRIsize_t " descriptors to core\n", n); //initialize timeouts diff --git a/backends/midi.c b/backends/midi.c index 92776ca..a7945ec 100644 --- a/backends/midi.c +++ b/backends/midi.c @@ -338,25 +338,13 @@ static int midi_handle(size_t num, managed_fd* fds){ return 0; } -static int midi_start(){ - size_t n = 0, p; +static int midi_start(size_t n, instance** inst){ + size_t 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; - } - - //if there are no ports, do nothing - if(!n){ - free(inst); - return 0; - } - //connect to the sequencer if(snd_seq_open(&sequencer, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0){ fprintf(stderr, "Failed to open ALSA sequencer\n"); @@ -424,7 +412,6 @@ static int midi_start(){ bail: free(pfds); - free(inst); return rv; } diff --git a/backends/midi.h b/backends/midi.h index 4e16f90..579c9cb 100644 --- a/backends/midi.h +++ b/backends/midi.h @@ -7,7 +7,7 @@ static instance* midi_instance(); static channel* midi_channel(instance* instance, char* spec, uint8_t flags); static int midi_set(instance* inst, size_t num, channel** c, channel_value* v); static int midi_handle(size_t num, managed_fd* fds); -static int midi_start(); +static int midi_start(size_t n, instance** inst); static int midi_shutdown(); typedef struct /*_midi_instance_data*/ { diff --git a/backends/ola.cpp b/backends/ola.cpp index c13e8f9..088c20c 100644 --- a/backends/ola.cpp +++ b/backends/ola.cpp @@ -220,9 +220,8 @@ static void ola_register_callback(const std::string &error) { } } -static int ola_start(){ - size_t n, u, p; - instance** inst = NULL; +static int ola_start(size_t n, instance** inst){ + size_t u, p; ola_instance_data* data = NULL; ola_select = new ola::io::SelectServer(); @@ -255,12 +254,6 @@ static int ola_start(){ goto bail; } - //this should not happen anymore (backends without instances are not started anymore) - if(!n){ - free(inst); - return 0; - } - for(u = 0; u < n; u++){ data = (ola_instance_data*) inst[u]->impl; inst[u]->ident = data->universe_id; @@ -277,10 +270,8 @@ static int ola_start(){ //run the ola select implementation to run all commands ola_select->RunOnce(); - free(inst); return 0; bail: - free(inst); delete ola_client; ola_client = NULL; delete ola_select; diff --git a/backends/ola.h b/backends/ola.h index 0c42bac..2a55b77 100644 --- a/backends/ola.h +++ b/backends/ola.h @@ -11,7 +11,7 @@ extern "C" { static channel* ola_channel(instance* instance, char* spec, uint8_t flags); static int ola_set(instance* inst, size_t num, channel** c, channel_value* v); static int ola_handle(size_t num, managed_fd* fds); - static int ola_start(); + static int ola_start(size_t n, instance** inst); static int ola_shutdown(); } diff --git a/backends/osc.c b/backends/osc.c index b12ae40..61ae872 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -892,22 +892,10 @@ static int osc_handle(size_t num, managed_fd* fds){ return 0; } -static int osc_start(){ - size_t n, u, fds = 0; - instance** inst = NULL; +static int osc_start(size_t n, instance** inst){ + size_t u, fds = 0; osc_instance_data* data = NULL; - //fetch all instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - - if(!n){ - free(inst); - return 0; - } - //update instance identifiers for(u = 0; u < n; u++){ data = (osc_instance_data*) inst[u]->impl; @@ -916,7 +904,6 @@ static int osc_start(){ inst[u]->ident = data->fd; if(mm_manage_fd(data->fd, BACKEND_NAME, 1, inst[u])){ fprintf(stderr, "Failed to register OSC descriptor for instance %s\n", inst[u]->name); - free(inst); return 1; } fds++; @@ -927,8 +914,6 @@ static int osc_start(){ } fprintf(stderr, "OSC backend registered %" PRIsize_t " descriptors to core\n", fds); - - free(inst); return 0; } diff --git a/backends/osc.h b/backends/osc.h index 6f3b923..24cc7e5 100644 --- a/backends/osc.h +++ b/backends/osc.h @@ -14,7 +14,7 @@ static instance* osc_instance(); static channel* osc_map_channel(instance* inst, char* spec, uint8_t flags); static int osc_set(instance* inst, size_t num, channel** c, channel_value* v); static int osc_handle(size_t num, managed_fd* fds); -static int osc_start(); +static int osc_start(size_t n, instance** inst); static int osc_shutdown(); typedef enum { diff --git a/backends/sacn.c b/backends/sacn.c index 75c327e..877cbb0 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -531,10 +531,9 @@ static int sacn_handle(size_t num, managed_fd* fds){ return 0; } -static int sacn_start(){ - size_t n, u, p; +static int sacn_start(size_t n, instance** inst){ + size_t u, p; int rv = 1; - instance** inst = NULL; sacn_instance_data* data = NULL; sacn_instance_id id = { .label = 0 @@ -544,17 +543,6 @@ static int sacn_start(){ }; struct sockaddr_in* dest_v4 = NULL; - //fetch all instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - - if(!n){ - free(inst); - return 0; - } - if(!global_cfg.fds){ fprintf(stderr, "Failed to start sACN backend: no descriptors bound\n"); free(inst); @@ -625,7 +613,6 @@ static int sacn_start(){ rv = 0; bail: - free(inst); return rv; } diff --git a/backends/sacn.h b/backends/sacn.h index 1d3268c..0d234d4 100644 --- a/backends/sacn.h +++ b/backends/sacn.h @@ -7,7 +7,7 @@ static instance* sacn_instance(); static channel* sacn_channel(instance* instance, char* spec, uint8_t flags); static int sacn_set(instance* inst, size_t num, channel** c, channel_value* v); static int sacn_handle(size_t num, managed_fd* fds); -static int sacn_start(); +static int sacn_start(size_t n, instance** inst); static int sacn_shutdown(); #define SACN_PORT "5568" diff --git a/backends/winmidi.c b/backends/winmidi.c index 790257b..0fc1aca 100644 --- a/backends/winmidi.c +++ b/backends/winmidi.c @@ -440,10 +440,9 @@ static int winmidi_match_output(char* prefix){ return -1; } -static int winmidi_start(){ - size_t n = 0, p; +static int winmidi_start(size_t n, instance** inst){ + size_t p; int device, rv = -1; - instance** inst = NULL; winmidi_instance_data* data = NULL; struct sockaddr_storage sockadd = { 0 @@ -453,18 +452,6 @@ static int winmidi_start(){ char* error = NULL; DBGPF("winmidi main thread ID is %ld\n", GetCurrentThreadId()); - //fetch all instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - - //no instances, we're done - if(!n){ - free(inst); - return 0; - } - //output device list if requested if(backend_config.list_devices){ winmidi_match_input(NULL); @@ -552,7 +539,6 @@ static int winmidi_start(){ rv = 0; bail: - free(inst); return rv; } diff --git a/backends/winmidi.h b/backends/winmidi.h index 985c46a..7907a42 100644 --- a/backends/winmidi.h +++ b/backends/winmidi.h @@ -7,7 +7,7 @@ static instance* winmidi_instance(); static channel* winmidi_channel(instance* inst, char* spec, uint8_t flags); static int winmidi_set(instance* inst, size_t num, channel** c, channel_value* v); static int winmidi_handle(size_t num, managed_fd* fds); -static int winmidi_start(); +static int winmidi_start(size_t n, instance** inst); static int winmidi_shutdown(); typedef struct /*_winmidi_instance_data*/ { diff --git a/midimonster.h b/midimonster.h index 677eeee..bf30e8c 100644 --- a/midimonster.h +++ b/midimonster.h @@ -134,7 +134,7 @@ typedef void (*mmbackend_free_channel)(struct _backend_channel* c); typedef int (*mmbackend_configure)(char* option, char* value); typedef int (*mmbackend_configure_instance)(struct _backend_instance* instance, char* option, char* value); typedef int (*mmbackend_process_fd)(size_t nfds, struct _managed_fd* fds); -typedef int (*mmbackend_start)(); +typedef int (*mmbackend_start)(size_t ninstances, struct _backend_instance** inst); typedef uint32_t (*mmbackend_interval)(); typedef int (*mmbackend_shutdown)(); -- cgit v1.2.3 From f6d6eefe9bb9934f4fa3e665734d746f02471cdb Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 11 Dec 2019 23:20:34 +0100 Subject: Simplify plugin_stop API --- backend.c | 22 ++++++++++++++++++++-- backends/artnet.c | 10 ++-------- backends/artnet.h | 2 +- backends/evdev.c | 13 +++---------- backends/evdev.h | 2 +- backends/jack.c | 12 ++---------- backends/jack.h | 2 +- backends/loopback.c | 12 ++---------- backends/loopback.h | 2 +- backends/lua.c | 12 ++---------- backends/lua.h | 2 +- backends/maweb.c | 13 ++----------- backends/maweb.h | 4 ++-- backends/midi.c | 10 ++-------- backends/midi.h | 2 +- backends/ola.cpp | 16 ++-------------- backends/ola.h | 2 +- backends/osc.c | 11 ++--------- backends/osc.h | 2 +- backends/sacn.c | 11 ++--------- backends/sacn.h | 2 +- backends/winmidi.c | 11 ++--------- backends/winmidi.h | 2 +- config.c | 3 ++- midimonster.h | 2 +- 25 files changed, 58 insertions(+), 124 deletions(-) diff --git a/backend.c b/backend.c index f5efca7..2af2f37 100644 --- a/backend.c +++ b/backend.c @@ -150,6 +150,12 @@ MM_API int mm_backend_instances(char* name, size_t* ninst, instance*** inst){ } *ninst = n; + + if(!n){ + *inst = NULL; + return 0; + } + *inst = calloc(n, sizeof(instance*)); if(!*inst){ fprintf(stderr, "Failed to allocate memory\n"); @@ -290,10 +296,22 @@ int backends_start(){ } int backends_stop(){ - size_t u; + size_t u, n; + instance** inst = NULL; + for(u = 0; u < nbackends; u++){ - backends[u].shutdown(); + //fetch list of instances + if(mm_backend_instances(backends[u].name, &n, &inst)){ + fprintf(stderr, "Failed to fetch instance list for shutdown of backend %s\n", backends[u].name); + n = 0; + inst = NULL; + } + + backends[u].shutdown(n, inst); + free(inst); + inst = NULL; } + free(backends); nbackends = 0; return 0; diff --git a/backends/artnet.c b/backends/artnet.c index e4147ec..b181296 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -438,18 +438,12 @@ bail: return rv; } -static int artnet_shutdown(){ - size_t n, p; - instance** inst = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } +static int artnet_shutdown(size_t n, instance** inst){ + size_t p; for(p = 0; p < n; p++){ free(inst[p]->impl); } - free(inst); for(p = 0; p < artnet_fds; p++){ close(artnet_fd[p].fd); diff --git a/backends/artnet.h b/backends/artnet.h index 738b55c..59bd53f 100644 --- a/backends/artnet.h +++ b/backends/artnet.h @@ -11,7 +11,7 @@ static channel* artnet_channel(instance* instance, char* spec, uint8_t flags); static int artnet_set(instance* inst, size_t num, channel** c, channel_value* v); static int artnet_handle(size_t num, managed_fd* fds); static int artnet_start(size_t n, instance** inst); -static int artnet_shutdown(); +static int artnet_shutdown(size_t n, instance** inst); #define ARTNET_PORT "6454" #define ARTNET_VERSION 14 diff --git a/backends/evdev.c b/backends/evdev.c index 9998a03..d2eeba8 100644 --- a/backends/evdev.c +++ b/backends/evdev.c @@ -498,18 +498,12 @@ static int evdev_set(instance* inst, size_t num, channel** c, channel_value* v) #endif } -static int evdev_shutdown(){ +static int evdev_shutdown(size_t n, instance** inst){ evdev_instance_data* data = NULL; - instance** instances = NULL; - size_t n, u; - - if(mm_backend_instances(BACKEND_NAME, &n, &instances)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } + size_t u; for(u = 0; u < n; u++){ - data = (evdev_instance_data*) instances[u]->impl; + data = (evdev_instance_data*) inst[u]->impl; if(data->input_fd >= 0){ libevdev_free(data->input_ev); @@ -528,7 +522,6 @@ static int evdev_shutdown(){ free(data); } - free(instances); fprintf(stderr, "evdev backend shut down\n"); return 0; } diff --git a/backends/evdev.h b/backends/evdev.h index 1f03941..0c877fc 100644 --- a/backends/evdev.h +++ b/backends/evdev.h @@ -16,7 +16,7 @@ static channel* evdev_channel(instance* instance, char* spec, uint8_t flags); static int evdev_set(instance* inst, size_t num, channel** c, channel_value* v); static int evdev_handle(size_t num, managed_fd* fds); static int evdev_start(size_t n, instance** inst); -static int evdev_shutdown(); +static int evdev_shutdown(size_t n, instance** inst); #define INPUT_NODES "/dev/input" #define INPUT_PREFIX "event" diff --git a/backends/jack.c b/backends/jack.c index 047dce8..eb53190 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -685,16 +685,10 @@ bail: return rv; } -static int mmjack_shutdown(){ - size_t n, u, p; - instance** inst = NULL; +static int mmjack_shutdown(size_t n, instance** inst){ + size_t u, p; mmjack_instance_data* data = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ data = (mmjack_instance_data*) inst[u]->impl; @@ -733,8 +727,6 @@ static int mmjack_shutdown(){ data->fd = -1; } - free(inst); - fprintf(stderr, "jack backend shut down\n"); return 0; } diff --git a/backends/jack.h b/backends/jack.h index c9f8c4c..66c66db 100644 --- a/backends/jack.h +++ b/backends/jack.h @@ -10,7 +10,7 @@ static channel* mmjack_channel(instance* inst, char* spec, uint8_t flags); static int mmjack_set(instance* inst, size_t num, channel** c, channel_value* v); static int mmjack_handle(size_t num, managed_fd* fds); static int mmjack_start(size_t n, instance** inst); -static int mmjack_shutdown(); +static int mmjack_shutdown(size_t n, instance** inst); #define JACK_DEFAULT_CLIENT_NAME "MIDIMonster" #define JACK_DEFAULT_SERVER_NAME "default" diff --git a/backends/loopback.c b/backends/loopback.c index 616eccf..c2c3430 100644 --- a/backends/loopback.c +++ b/backends/loopback.c @@ -96,16 +96,10 @@ static int loopback_start(size_t n, instance** inst){ return 0; } -static int loopback_shutdown(){ - size_t n, u, p; - instance** inst = NULL; +static int loopback_shutdown(size_t n, instance** inst){ + size_t u, p; loopback_instance_data* data = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ data = (loopback_instance_data*) inst[u]->impl; for(p = 0; p < data->n; p++){ @@ -115,8 +109,6 @@ static int loopback_shutdown(){ free(inst[u]->impl); } - free(inst); - fprintf(stderr, "Loopback backend shut down\n"); return 0; } diff --git a/backends/loopback.h b/backends/loopback.h index dee3e9d..c508d72 100644 --- a/backends/loopback.h +++ b/backends/loopback.h @@ -8,7 +8,7 @@ static channel* loopback_channel(instance* inst, char* spec, uint8_t flags); static int loopback_set(instance* inst, size_t num, channel** c, channel_value* v); static int loopback_handle(size_t num, managed_fd* fds); static int loopback_start(size_t n, instance** inst); -static int loopback_shutdown(); +static int loopback_shutdown(size_t n, instance** inst); typedef struct /*_loopback_instance_data*/ { size_t n; diff --git a/backends/lua.c b/backends/lua.c index b165dd8..2ce40f5 100644 --- a/backends/lua.c +++ b/backends/lua.c @@ -460,17 +460,10 @@ static int lua_start(size_t n, instance** inst){ return 0; } -static int lua_shutdown(){ - size_t n, u, p; - instance** inst = NULL; +static int lua_shutdown(size_t n, instance** inst){ + size_t u, p; lua_instance_data* data = NULL; - //fetch all instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ data = (lua_instance_data*) inst[u]->impl; //stop the interpreter @@ -486,7 +479,6 @@ static int lua_shutdown(){ free(inst[u]->impl); } - free(inst); //free module-global data free(timer); timer = NULL; diff --git a/backends/lua.h b/backends/lua.h index 9e19506..75f03c4 100644 --- a/backends/lua.h +++ b/backends/lua.h @@ -17,7 +17,7 @@ static channel* lua_channel(instance* inst, char* spec, uint8_t flags); static int lua_set(instance* inst, size_t num, channel** c, channel_value* v); static int lua_handle(size_t num, managed_fd* fds); static int lua_start(size_t n, instance** inst); -static int lua_shutdown(); +static int lua_shutdown(size_t n, instance** inst); #ifndef MMBACKEND_LUA_TIMERFD static uint32_t lua_interval(); #endif diff --git a/backends/maweb.c b/backends/maweb.c index 28cad0c..8cf201e 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -1017,17 +1017,10 @@ static int maweb_start(size_t n, instance** inst){ return 0; } -static int maweb_shutdown(){ - size_t n, u; - instance** inst = NULL; +static int maweb_shutdown(size_t n, instance** inst){ + size_t u; maweb_instance_data* data = NULL; - //fetch all instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ data = (maweb_instance_data*) inst[u]->impl; free(data->host); @@ -1053,8 +1046,6 @@ static int maweb_shutdown(){ data->channels = 0; } - free(inst); - fprintf(stderr, "maweb backend shut down\n"); return 0; } diff --git a/backends/maweb.h b/backends/maweb.h index 05095f8..50b777a 100644 --- a/backends/maweb.h +++ b/backends/maweb.h @@ -7,8 +7,8 @@ static instance* maweb_instance(); static channel* maweb_channel(instance* inst, char* spec, uint8_t flags); static int maweb_set(instance* inst, size_t num, channel** c, channel_value* v); static int maweb_handle(size_t num, managed_fd* fds); -static int maweb_start(); -static int maweb_shutdown(); +static int maweb_start(size_t n, instance** inst); +static int maweb_shutdown(size_t n, instance** inst); static uint32_t maweb_interval(); //Default login password: MD5("midimonster") diff --git a/backends/midi.c b/backends/midi.c index a7945ec..2088774 100644 --- a/backends/midi.c +++ b/backends/midi.c @@ -415,14 +415,9 @@ bail: return rv; } -static int midi_shutdown(){ - size_t n, p; - instance** inst = NULL; +static int midi_shutdown(size_t n, instance** inst){ + size_t p; midi_instance_data* data = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } for(p = 0; p < n; p++){ data = (midi_instance_data*) inst[p]->impl; @@ -432,7 +427,6 @@ static int midi_shutdown(){ data->write = NULL; free(inst[p]->impl); } - free(inst); //close midi if(sequencer){ diff --git a/backends/midi.h b/backends/midi.h index 579c9cb..66a02bc 100644 --- a/backends/midi.h +++ b/backends/midi.h @@ -8,7 +8,7 @@ static channel* midi_channel(instance* instance, char* spec, uint8_t flags); static int midi_set(instance* inst, size_t num, channel** c, channel_value* v); static int midi_handle(size_t num, managed_fd* fds); static int midi_start(size_t n, instance** inst); -static int midi_shutdown(); +static int midi_shutdown(size_t n, instance** inst); typedef struct /*_midi_instance_data*/ { int port; diff --git a/backends/ola.cpp b/backends/ola.cpp index 088c20c..fd121a0 100644 --- a/backends/ola.cpp +++ b/backends/ola.cpp @@ -248,12 +248,6 @@ static int ola_start(size_t n, instance** inst){ ola_client->SetDmxCallback(ola::NewCallback(&ola_data_receive)); - //fetch all defined instances - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - goto bail; - } - for(u = 0; u < n; u++){ data = (ola_instance_data*) inst[u]->impl; inst[u]->ident = data->universe_id; @@ -279,18 +273,12 @@ bail: return 1; } -static int ola_shutdown(){ - size_t n, p; - instance** inst = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } +static int ola_shutdown(size_t n, instance** inst){ + size_t p; for(p = 0; p < n; p++){ free(inst[p]->impl); } - free(inst); if(ola_client){ ola_client->Stop(); diff --git a/backends/ola.h b/backends/ola.h index 2a55b77..083e971 100644 --- a/backends/ola.h +++ b/backends/ola.h @@ -12,7 +12,7 @@ extern "C" { static int ola_set(instance* inst, size_t num, channel** c, channel_value* v); static int ola_handle(size_t num, managed_fd* fds); static int ola_start(size_t n, instance** inst); - static int ola_shutdown(); + static int ola_shutdown(size_t n, instance** inst); } #define MAP_COARSE 0x0200 diff --git a/backends/osc.c b/backends/osc.c index 61ae872..2c65ecb 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -917,16 +917,10 @@ static int osc_start(size_t n, instance** inst){ return 0; } -static int osc_shutdown(){ - size_t n, u, c; - instance** inst = NULL; +static int osc_shutdown(size_t n, instance** inst){ + size_t u, c; osc_instance_data* data = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ data = (osc_instance_data*) inst[u]->impl; for(c = 0; c < data->channels; c++){ @@ -953,7 +947,6 @@ static int osc_shutdown(){ free(inst[u]->impl); } - free(inst); fprintf(stderr, "OSC backend shut down\n"); return 0; } diff --git a/backends/osc.h b/backends/osc.h index 24cc7e5..f8ff3ff 100644 --- a/backends/osc.h +++ b/backends/osc.h @@ -15,7 +15,7 @@ static channel* osc_map_channel(instance* inst, char* spec, uint8_t flags); static int osc_set(instance* inst, size_t num, channel** c, channel_value* v); static int osc_handle(size_t num, managed_fd* fds); static int osc_start(size_t n, instance** inst); -static int osc_shutdown(); +static int osc_shutdown(size_t n, instance** inst); typedef enum { not_set = 0, diff --git a/backends/sacn.c b/backends/sacn.c index 877cbb0..ef422e8 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -616,19 +616,12 @@ bail: return rv; } -static int sacn_shutdown(){ - size_t n, p; - instance** inst = NULL; - - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } +static int sacn_shutdown(size_t n, instance** inst){ + size_t p; for(p = 0; p < n; p++){ free(inst[p]->impl); } - free(inst); for(p = 0; p < global_cfg.fds; p++){ close(global_cfg.fd[p].fd); diff --git a/backends/sacn.h b/backends/sacn.h index 0d234d4..726fa68 100644 --- a/backends/sacn.h +++ b/backends/sacn.h @@ -8,7 +8,7 @@ static channel* sacn_channel(instance* instance, char* spec, uint8_t flags); static int sacn_set(instance* inst, size_t num, channel** c, channel_value* v); static int sacn_handle(size_t num, managed_fd* fds); static int sacn_start(size_t n, instance** inst); -static int sacn_shutdown(); +static int sacn_shutdown(size_t n, instance** inst); #define SACN_PORT "5568" #define SACN_RECV_BUF 8192 diff --git a/backends/winmidi.c b/backends/winmidi.c index 0fc1aca..090e438 100644 --- a/backends/winmidi.c +++ b/backends/winmidi.c @@ -542,16 +542,10 @@ bail: return rv; } -static int winmidi_shutdown(){ - size_t n, u; - instance** inst = NULL; +static int winmidi_shutdown(size_t n, instance** inst){ + size_t u; winmidi_instance_data* data = NULL; - if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); - return 1; - } - for(u = 0; u < n; u++){ data = (winmidi_instance_data*) inst[u]->impl; free(data->read); @@ -572,7 +566,6 @@ static int winmidi_shutdown(){ } } - free(inst); closesocket(backend_config.socket_pair[0]); closesocket(backend_config.socket_pair[1]); diff --git a/backends/winmidi.h b/backends/winmidi.h index 7907a42..81e7439 100644 --- a/backends/winmidi.h +++ b/backends/winmidi.h @@ -8,7 +8,7 @@ static channel* winmidi_channel(instance* inst, char* spec, uint8_t flags); static int winmidi_set(instance* inst, size_t num, channel** c, channel_value* v); static int winmidi_handle(size_t num, managed_fd* fds); static int winmidi_start(size_t n, instance** inst); -static int winmidi_shutdown(); +static int winmidi_shutdown(size_t n, instance** inst); typedef struct /*_winmidi_instance_data*/ { char* read; diff --git a/config.c b/config.c index 0b9173e..c7e2f7e 100644 --- a/config.c +++ b/config.c @@ -317,6 +317,7 @@ int config_read(char* cfg_filepath){ size_t line_alloc = 0; ssize_t status; map_type mapping_type = map_rtl; + FILE* source = NULL; char* line_raw = NULL, *line, *separator; //create heap copy of file name because original might be in readonly memory @@ -346,7 +347,7 @@ int config_read(char* cfg_filepath){ source_file = source_dir; } - FILE* source = fopen(source_file, "r"); + source = fopen(source_file, "r"); if(!source){ fprintf(stderr, "Failed to open configuration file for reading\n"); diff --git a/midimonster.h b/midimonster.h index bf30e8c..1f5c936 100644 --- a/midimonster.h +++ b/midimonster.h @@ -136,7 +136,7 @@ typedef int (*mmbackend_configure_instance)(struct _backend_instance* instance, typedef int (*mmbackend_process_fd)(size_t nfds, struct _managed_fd* fds); typedef int (*mmbackend_start)(size_t ninstances, struct _backend_instance** inst); typedef uint32_t (*mmbackend_interval)(); -typedef int (*mmbackend_shutdown)(); +typedef int (*mmbackend_shutdown)(size_t ninstances, struct _backend_instance** inst); /* Bit masks for the `flags` parameter to mmbackend_parse_channel */ typedef enum { -- cgit v1.2.3 From 763f6d6a434b6e5a9d166cb538857d0cac5fa29e Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 11 Dec 2019 23:33:27 +0100 Subject: Release instance implementation data allocation --- backends/evdev.c | 2 +- backends/jack.c | 2 ++ backends/maweb.c | 2 ++ backends/winmidi.c | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/backends/evdev.c b/backends/evdev.c index d2eeba8..659dc77 100644 --- a/backends/evdev.c +++ b/backends/evdev.c @@ -519,7 +519,7 @@ static int evdev_shutdown(size_t n, instance** inst){ #endif data->relative_axes = 0; free(data->relative_axis); - free(data); + free(inst[u]->impl); } fprintf(stderr, "evdev backend shut down\n"); diff --git a/backends/jack.c b/backends/jack.c index eb53190..42ecee3 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -725,6 +725,8 @@ 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"); diff --git a/backends/maweb.c b/backends/maweb.c index 8cf201e..4d41f0e 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -1044,6 +1044,8 @@ static int maweb_shutdown(size_t n, instance** inst){ free(data->channel); data->channel = NULL; data->channels = 0; + + free(inst[u]->impl); } fprintf(stderr, "maweb backend shut down\n"); diff --git a/backends/winmidi.c b/backends/winmidi.c index 090e438..c917ac6 100644 --- a/backends/winmidi.c +++ b/backends/winmidi.c @@ -564,6 +564,8 @@ static int winmidi_shutdown(size_t n, instance** inst){ midiOutClose(data->device_out); data->device_out = NULL; } + + free(inst[u]->impl); } closesocket(backend_config.socket_pair[0]); -- cgit v1.2.3 From bef4dd78ca2a610b4c669ea2c7a477283769997d Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 12 Dec 2019 20:29:03 +0100 Subject: Extend hostspec parsing and implement local mode for sACN (#39) --- backends/artnet.c | 6 +++--- backends/libmmbackend.c | 15 ++++++++++++++- backends/libmmbackend.h | 6 ++++-- backends/maweb.c | 4 ++-- backends/osc.c | 6 +++--- backends/sacn.c | 26 +++++++++++++++++++++----- backends/sacn.h | 1 - backends/sacn.md | 6 +++++- 8 files changed, 52 insertions(+), 18 deletions(-) diff --git a/backends/artnet.c b/backends/artnet.c index b181296..aa7c48e 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -68,14 +68,14 @@ MM_PLUGIN_API int init(){ } static int artnet_configure(char* option, char* value){ - char* host = NULL, *port = NULL; + char* host = NULL, *port = NULL, *fd_opts = NULL; if(!strcmp(option, "net")){ //configure default net default_net = strtoul(value, NULL, 0); return 0; } else if(!strcmp(option, "bind")){ - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, &fd_opts); if(!host){ fprintf(stderr, "Not valid ArtNet bind address given\n"); @@ -134,7 +134,7 @@ static int artnet_configure_instance(instance* inst, char* option, char* value){ return 0; } else if(!strcmp(option, "dest") || !strcmp(option, "destination")){ - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, NULL); if(!host){ fprintf(stderr, "Not a valid ArtNet destination for instance %s\n", inst->name); diff --git a/backends/libmmbackend.c b/backends/libmmbackend.c index ccbeb52..7dbb4ae 100644 --- a/backends/libmmbackend.c +++ b/backends/libmmbackend.c @@ -1,6 +1,6 @@ #include "libmmbackend.h" -void mmbackend_parse_hostspec(char* spec, char** host, char** port){ +void mmbackend_parse_hostspec(char* spec, char** host, char** port, char** options){ size_t u = 0; if(!spec || !host || !port){ @@ -29,6 +29,19 @@ void mmbackend_parse_hostspec(char* spec, char** host, char** port){ spec[u] = 0; *port = spec + u + 1; } + + if(options){ + *options = NULL; + if(*port){ + //scan for space after port + for(u = 0; (*port)[u] && !isspace((*port)[u]); u++){ + } + if(isspace((*port)[u])){ + (*port)[u] = 0; + *options = (*port) + u + 1; + } + } + } } int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* addr, socklen_t* len){ diff --git a/backends/libmmbackend.h b/backends/libmmbackend.h index 5749119..76e588f 100644 --- a/backends/libmmbackend.h +++ b/backends/libmmbackend.h @@ -22,13 +22,15 @@ /* * Parse spec as host specification in the form - * host port + * host port [options] * into its constituent parts. * Returns offsets into the original string and modifies it. * Returns NULL in *port if none given. * Returns NULL in both *port and *host if spec was an empty string. + * Returns a pointer after the port in *options if options is non-NULL + * and the port was not followed by \0 */ -void mmbackend_parse_hostspec(char* spec, char** host, char** port); +void mmbackend_parse_hostspec(char* spec, char** host, char** port, char** options); /* * Parse a given host / port combination into a sockaddr_storage diff --git a/backends/maweb.c b/backends/maweb.c index 4d41f0e..18d0351 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -145,10 +145,10 @@ static int maweb_configure(char* option, char* value){ static int maweb_configure_instance(instance* inst, char* option, char* value){ maweb_instance_data* data = (maweb_instance_data*) inst->impl; - char* host = NULL, *port = NULL; + char* host = NULL, *port = NULL, *fd_opts = NULL; if(!strcmp(option, "host")){ - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, &fd_opts); if(!host){ fprintf(stderr, "Invalid host specified for maweb instance %s\n", inst->name); return 1; diff --git a/backends/osc.c b/backends/osc.c index 2c65ecb..15b5c24 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -496,7 +496,7 @@ static int osc_register_pattern(osc_instance_data* data, char* pattern_path, cha static int osc_configure_instance(instance* inst, char* option, char* value){ osc_instance_data* data = (osc_instance_data*) inst->impl; - char* host = NULL, *port = NULL; + char* host = NULL, *port = NULL, *fd_opts = NULL; if(!strcmp(option, "root")){ if(osc_path_validate(value, 0)){ @@ -516,7 +516,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ return 0; } else if(!strcmp(option, "bind")){ - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, &fd_opts); if(!host || !port){ fprintf(stderr, "Invalid bind address for instance %s\n", inst->name); return 1; @@ -541,7 +541,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ return 0; } - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, NULL); if(!host || !port){ fprintf(stderr, "Invalid destination address for instance %s\n", inst->name); return 1; diff --git a/backends/sacn.c b/backends/sacn.c index ef422e8..2a04245 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -17,6 +17,10 @@ #define MAX_FDS 4096 #define BACKEND_NAME "sacn" +enum /*_sacn_fd_flags*/ { + mcast_loop = 1 +}; + static struct /*_sacn_global_config*/ { uint8_t source_name[64]; uint8_t cid[16]; @@ -58,8 +62,8 @@ MM_PLUGIN_API int init(){ return 0; } -static int sacn_listener(char* host, char* port, uint8_t fd_flags){ - int fd = -1; +static int sacn_listener(char* host, char* port, uint8_t flags){ + int fd = -1, yes = 1; if(global_cfg.fds >= MAX_FDS){ fprintf(stderr, "sACN backend descriptor limit reached\n"); return -1; @@ -80,10 +84,17 @@ static int sacn_listener(char* host, char* port, uint8_t fd_flags){ fprintf(stderr, "sACN backend interface %" PRIsize_t " bound to %s port %s\n", global_cfg.fds, host, port); global_cfg.fd[global_cfg.fds].fd = fd; - global_cfg.fd[global_cfg.fds].flags = fd_flags; global_cfg.fd[global_cfg.fds].universes = 0; global_cfg.fd[global_cfg.fds].universe = NULL; global_cfg.fd[global_cfg.fds].last_frame = NULL; + + if(flags & mcast_loop){ + //set IP_MCAST_LOOP to allow local applications to receive output + if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&yes, sizeof(yes)) < 0){ + fprintf(stderr, "Failed to disable IP_MULTICAST_LOOP on socket: %s\n", strerror(errno)); + } + } + global_cfg.fds++; return 0; } @@ -110,17 +121,22 @@ static int sacn_configure(char* option, char* value){ } } else if(!strcmp(option, "bind")){ - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, &next); if(!host){ fprintf(stderr, "No valid sACN bind address provided\n"); return 1; } + if(next && !strncmp(next, "local", 5)){ + flags = mcast_loop; + } + if(sacn_listener(host, port ? port : SACN_PORT, flags)){ fprintf(stderr, "Failed to bind sACN descriptor: %s\n", value); return 1; } + return 0; } @@ -151,7 +167,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ return 0; } else if(!strcmp(option, "destination")){ - mmbackend_parse_hostspec(value, &host, &port); + mmbackend_parse_hostspec(value, &host, &port, NULL); if(!host){ fprintf(stderr, "No valid sACN destination for instance %s\n", inst->name); diff --git a/backends/sacn.h b/backends/sacn.h index 726fa68..c8d11e9 100644 --- a/backends/sacn.h +++ b/backends/sacn.h @@ -56,7 +56,6 @@ typedef union /*_sacn_instance_id*/ { typedef struct /*_sacn_socket*/ { int fd; - uint8_t flags; size_t universes; uint16_t* universe; uint64_t* last_frame; diff --git a/backends/sacn.md b/backends/sacn.md index 434beeb..46f1197 100644 --- a/backends/sacn.md +++ b/backends/sacn.md @@ -10,7 +10,11 @@ containing all write-enabled universes. |---------------|-----------------------|-----------------------|-----------------------| | `name` | `sACN source` | `MIDIMonster` | sACN source name | | `cid` | `0xAA 0xBB 0xCC` ... | `MIDIMonster` | Source CID (16 bytes) | -| `bind` | `0.0.0.0 5568` | none | Binds a network address to listen for data. This option may be set multiple times, with each descriptor being assigned an index starting from 0 to be used with the `interface` instance configuration option. At least one descriptor is required for transmission. | +| `bind` | `0.0.0.0 5568` | none | Binds a network address to listen for data. This option may be set multiple times, with each descriptor being assigned an index starting from 0 to be used with the `interface` instance configuration option. At least one descriptor is required for operation. | + +The `bind` configuration value can be extended by the keyword `local` to allow software on the +local host to process the sACN output frames from the MIDIMonster (e.g. `bind = 0.0.0.0 5568 local`). +This has the side effect of generating mirroring the output of instances on this descriptors to their input. #### Instance configuration -- cgit v1.2.3 From 3d7291df090350365b78550bfc8152ee2576f6a9 Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 12 Dec 2019 20:34:03 +0100 Subject: Fix description --- backends/sacn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/sacn.md b/backends/sacn.md index 46f1197..f5f1db4 100644 --- a/backends/sacn.md +++ b/backends/sacn.md @@ -14,7 +14,7 @@ containing all write-enabled universes. The `bind` configuration value can be extended by the keyword `local` to allow software on the local host to process the sACN output frames from the MIDIMonster (e.g. `bind = 0.0.0.0 5568 local`). -This has the side effect of generating mirroring the output of instances on this descriptors to their input. +This has the side effect of mirroring the output of instances on those descriptors to their input. #### Instance configuration -- cgit v1.2.3 From 4b063b0017ff262e3d6757062a297082a808a3e2 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 14 Dec 2019 23:49:40 +0100 Subject: Fix minor bug in plugin path setup --- TODO | 6 +++--- midimonster.h | 2 +- plugin.c | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/TODO b/TODO index 1f1269d..6ee649f 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,8 @@ keepalive channels per backend? Note source in channel value struct Optimize core channel search (store backend offset) - +udp backends may ignore MTU mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway) -> documentation - installer: implement an upgrade mode (check for newer versions in the repo) - +evdev.c:321 divides by zero with relaxis +make event collectors threadsafe to stop marshalling data... diff --git a/midimonster.h b/midimonster.h index 1f5c936..eb19409 100644 --- a/midimonster.h +++ b/midimonster.h @@ -92,7 +92,7 @@ struct _managed_fd; * Parse instance configuration from the user-supplied configuration * file. Returning a non-zero value fails config parsing. * * mmbackend_channel - * Parse a channel-spec to be mapped to/from. The `falgs` parameter supplies + * Parse a channel-spec to be mapped to/from. The `flags` parameter supplies * additional information to the parser, such as whether the channel is being * queried for use as input (to the MIDIMonster core) and/or output * (from the MIDIMonster core) channel (on a per-query basis). diff --git a/plugin.c b/plugin.c index c7c9812..56d6651 100644 --- a/plugin.c +++ b/plugin.c @@ -30,6 +30,11 @@ static int plugin_attach(char* path, char* file){ char* path_separator = "/"; #endif + if(!path || !file || !strlen(path)){ + fprintf(stderr, "Invalid plugin loader path\n"); + return 1; + } + lib = calloc(strlen(path) + strlen(file) + 2, sizeof(char)); if(!lib){ fprintf(stderr, "Failed to allocate memory\n"); @@ -37,7 +42,7 @@ static int plugin_attach(char* path, char* file){ } snprintf(lib, strlen(path) + strlen(file) + 2, "%s%s%s", path, - (path[strlen(path)] == path_separator[0]) ? "" : path_separator, + (path[strlen(path) - 1] == path_separator[0]) ? "" : path_separator, file); handle = dlopen(lib, RTLD_NOW); -- cgit v1.2.3 From 94ace66323562b7590bc38f61c27439293aa6fd2 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Wed, 18 Dec 2019 08:56:55 +0100 Subject: Change --version output to stdout --- midimonster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/midimonster.c b/midimonster.c index 67614d4..48c6fe9 100644 --- a/midimonster.c +++ b/midimonster.c @@ -224,7 +224,7 @@ static void event_free(){ } static void version(){ - fprintf(stderr, "MIDIMonster %s\n", MIDIMONSTER_VERSION); + fprintf(stdout, "MIDIMonster %s\n", MIDIMONSTER_VERSION); } static int usage(char* fn){ -- cgit v1.2.3 From 21bf7ec86e9319864c403d479b8267b2eb0efb6f Mon Sep 17 00:00:00 2001 From: Spacelord Date: Wed, 18 Dec 2019 09:03:46 +0100 Subject: Change --version output to stdout --- midimonster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/midimonster.c b/midimonster.c index 67614d4..48c6fe9 100644 --- a/midimonster.c +++ b/midimonster.c @@ -224,7 +224,7 @@ static void event_free(){ } static void version(){ - fprintf(stderr, "MIDIMonster %s\n", MIDIMONSTER_VERSION); + fprintf(stdout, "MIDIMonster %s\n", MIDIMONSTER_VERSION); } static int usage(char* fn){ -- cgit v1.2.3 From 5384f9ee0b4ff4a6aa72300436b7dd47b77dc84d Mon Sep 17 00:00:00 2001 From: Spacelord Date: Wed, 18 Dec 2019 19:53:28 +0100 Subject: Initial updater implementation --- installer.sh | 181 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 142 insertions(+), 39 deletions(-) diff --git a/installer.sh b/installer.sh index fd4dd91..527904c 100755 --- a/installer.sh +++ b/installer.sh @@ -4,8 +4,11 @@ deps=(libasound2-dev libevdev-dev liblua5.3-dev libjack-jackd2-dev pkg-config libssl-dev gcc make wget git) user=$(whoami) # for bypassing user check replace "$(whoami)" with "root". -script_path="`cd $0; pwd`" # Script dir tmp_path=$(mktemp -d) # Repo download path +updater_dir=/etc/midimonster-updater-installer # Updater download + config path +updater_file=$updater_dir/updater.conf # + +latest_version=$(curl --silent "https://api.github.com/repos/cbdevnet/midimonster/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') makeargs=all # Build args @@ -15,6 +18,9 @@ VAR_PLUGINS="$VAR_PREFIX/lib/midimonster" VAR_DEFAULT_CFG="/etc/midimonster/midimonster.cfg" VAR_EXAMPLE_CFGS="$VAR_PREFIX/share/midimonster" +bold=$(tput bold) +normal=$(tput sgr0) + ################################################ SETUP ################################################ ############################################## FUNCTIONS ############################################## @@ -23,58 +29,127 @@ INSTALL-DEPS () { ##Install deps from array "$deps" for t in ${deps[@]}; do if [ $(dpkg-query -W -f='${Status}' $t 2>/dev/null | grep -c "ok installed") -eq 0 ]; then - echo "Installing "$t""; + printf "\nInstalling "$t""; apt-get install $t; - echo "Done."; + printf "\nDone."; else - echo ""$t" already installed!" - + printf "\n"$t" already installed!" fi done -echo "" +printf "\n" } INSTALL-PREP () { (#### Subshell make things like cd $tmp_path easier to revert - echo "Starting download..." + printf "\nStarting download..." git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster - echo "" - echo "" - echo "Initializing repository..." + printf "\n\n\nInitializing repository..." cd $tmp_path git init $tmp_path - echo "" - echo "Finding latest stable version..." - Iversion=$(git describe --abbrev=0) # Get last tag(stable version) - echo "Starting Git checkout to "$Iversion"..." - git checkout -f -q $Iversion - echo "Done." - ) + printf "\n" + + read -p "Do you want to install the nightly version? (y/n)? " magic #Asks for nightly version + case "$magic" in + y|Y ) printf "\nOK! You´re a risky person ;D" + NIGHTLY=1 + ;; + n|N ) printf "\nThat´s ok I´ll install the latest stable version for you ;-)" + NIGHTLY=0 + ;; + * ) printf "\nInvalid input" + ERROR + ;; + esac + + if [ $NIGHTLY != 1 ]; then printf "\nFinding latest stable version..."; Iversion=$(git describe --abbrev=0); printf "\nStarting Git checkout to "$Iversion"..."; git checkout -f -q $Iversion; fi # Git checkout if NIGHTLY !=1 + printf "\nPreparing Done.\n\n\n" +) +printf "${bold}If you don't know what you're doing, just hit enter 4 times.${normal}\n" + +read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX +VAR_PREFIX="${input:-$VAR_PREFIX}" + +read -e -i "$VAR_PLUGINS" -p "PLUGINS (Plugin directory): " input # Reads VAR_PLUGINS +VAR_PLUGINS="${input:-$VAR_PLUGINS}" + +read -e -i "$VAR_DEFAULT_CFG" -p "Default config path: " input # Reads VAR_DEFAULT_CFG +VAR_DEFAULT_CFG="${input:-$VAR_DEFAULT_CFG}" + +read -e -i "$VAR_EXAMPLE_CFGS" -p "Example config directory: " input # Reads VAR_EXAMPLE_CFGS +VAR_EXAMPLE_CFGS="${input:-$VAR_EXAMPLE_CFGS}" + +UPDATER_SAVE + +export PREFIX=$VAR_PREFIX +export PLUGINS=$VAR_PLUGINS +export DEFAULT_CFG=$VAR_DEFAULT_CFG +export DESTDIR=$VAR_DESTDIR +export EXAMPLES=$VAR_EXAMPLE_CFGS +} + +UPDATER-PREP () { +(#### Subshell make things like cd $tmp_path easier to revert - echo "" - echo "" - echo "" - read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX - VAR_PREFIX="${input:-$VAR_PREFIX}" + printf "\nStarting download..." + git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster + printf "\n\n" + printf "\nInitializing repository..." + cd $tmp_path + git init $tmp_path + printf "\n" + + read -p "Do you want to install the nightly version? (y/n)? " magic #Asks for nightly version + case "$magic" in + y|Y ) printf "\nOK! You´re a risky person ;D" + NIGHTLY=1 + ;; + n|N ) printf "\nThat´s ok I´ll install the latest stable version for you ;-)" + NIGHTLY=0 + ;; + * ) printf "\nInvalid input" + ERROR + ;; + esac + + if [ $NIGHTLY != 1 ]; then printf "\nFinding latest stable version..."; Iversion=$(git describe --abbrev=0); printf "\nStarting Git checkout to "$Iversion"..."; git checkout -f -q $Iversion; fi # Git checkout if NIGHTLY !=1 + printf "\nDone.\n\n\n" + ) - read -e -i "$VAR_PLUGINS" -p "PLUGINS (Plugin directory): " input # Reads VAR_PLUGINS - VAR_PLUGINS="${input:-$VAR_PLUGINS}" - read -e -i "$VAR_DEFAULT_CFG" -p "Default config path: " input # Reads VAR_DEFAULT_CFG - VAR_DEFAULT_CFG="${input:-$VAR_DEFAULT_CFG}" +rm -f "$VAR_PREFIX/bin/midimonster" +rm -rf "$VAR_PLUGINS/" - read -e -i "$VAR_EXAMPLE_CFGS" -p "Example config directory: " input # Reads VAR_EXAMPLE_CFGS - VAR_EXAMPLE_CFGS="${input:-$VAR_EXAMPLE_CFGS}" +UPDATER_SAVE +export PREFIX=$VAR_PREFIX +export PLUGINS=$VAR_PLUGINS +export DEFAULT_CFG=$VAR_DEFAULT_CFG +export DESTDIR=$VAR_DESTDIR +export EXAMPLES=$VAR_EXAMPLE_CFGS - export PREFIX=$VAR_PREFIX - export PLUGINS=$VAR_PLUGINS - export DEFAULT_CFG=$VAR_DEFAULT_CFG - export DESTDIR=$VAR_DESTDIR - export EXAMPLES=$VAR_EXAMPLE_CFGS +printf "\nSucessfully imported Updater settings from $updater_file." } +UPDATER () { + installed_version="$(midimonster --version)" + #installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) + if [[ "$installed_version" =~ "$latest_version" ]]; then + printf "\nNewest Version is already installed! ${bold}($installed_version)${normal}\n\n" + ERROR + else + printf "\nThe installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} ( Maybe you are running on nightly? )\n\n" + fi + + UPDATER-PREP + INSTALL-RUN + + printf "\nUpdating updater/installer script in $updater_dir" + wget "https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh" -O $updater_dir + chmod +x $updater_dir/installer.sh + DONE + } + INSTALL-RUN () { # Build cd "$tmp_path" make clean @@ -82,20 +157,33 @@ INSTALL-RUN () { # Build make install } +UPDATER_SAVE () { # Saves file for the auto updater in this script + rm -rf $updater_dir + printf "\nSaving updater to $updater_dir/installer.sh" + mkdir -p "$updater_dir" + wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh -O $updater_dir/installer.sh + printf "\nCreating symlink to updater/installer in /usr/bin/midimonster-updater-installer" + ln -s "$updater_dir/installer.sh" "/usr/bin/midimonster-updater-installer" + chmod +x "$updater_dir/installer.sh" + printf "\nExporting updater config to $updater_file" + printf "VAR_PREFIX=%s\nVAR_PLUGINS=%s\nVAR_DEFAULT_CFG=%s\nVAR_DESTDIR=%s\nVAR_EXAMPLE_CFGS=%s\n" "$VAR_PREFIX" "$VAR_PLUGINS" "$VAR_DEFAULT_CFG" "$VAR_DESTDIR" "$VAR_EXAMPLE_CFGS" > $updater_file +} + ERROR () { - echo "Aborting..." + printf "\nAborting..." CLEAN + printf "Exiting...\n\n\n" exit 1 } DONE () { - echo Done. + printf "\n\nDone." CLEAN exit 0 } CLEAN () { - echo "Cleaning..." + printf "\nCleaning...\n\n" rm -rf $tmp_path } @@ -106,11 +194,26 @@ CLEAN () { trap ERROR SIGINT SIGTERM SIGKILL clear -if [ $user != "root" ]; then echo "Installer must be run as root"; ERROR; fi # Check if $user = root! +if [ "$user" != "root" ]; then printf "\nInstaller must be run as root"; ERROR; fi # Check if $user = root! +if [ $(wget -q --spider http://github.com) $? -eq 1 ]; then printf "\nYou need connection to the internet"; ERROR; fi + +if [ -f $updater_file ] # Checks if updater config file exist and import it(overwrite default values!) +then + + printf "\nStarting updater...\n\n" + . $updater_file + + if [ -x "$VAR_PREFIX/bin/midimonster" ] # Check if binary $updater/bin/midimonster exist. If yes start updater else skip. + then + UPDATER + else + printf "\nMidimonster binary not found, skipping updater.\n" + fi -if [ $(wget -q --spider http://github.com) $? -eq 0 ]; then "INSTALL-DEPS"; else echo You need connection to the internet; ERROR ; fi +fi +INSTALL-DEPS INSTALL-PREP -echo "" +printf "\n" INSTALL-RUN DONE \ No newline at end of file -- cgit v1.2.3 From 704f256475ad52ab96e42f7b10ca407fac13d313 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Wed, 18 Dec 2019 21:43:01 +0100 Subject: Mention updater in README + Updater Improvements --- README.md | 2 ++ installer.sh | 81 ++++++++++++++++++++++++++---------------------------------- 2 files changed, 37 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 8d38565..e955d53 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,8 @@ wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh chmod +x ./installer.sh ./installer.sh ``` +This tool can also update MIDImonster automatically using a configuration file generated by the installer. +To do so, run `midimonster-updater` as root on your system after using the installer. #### Building for packaging or installation diff --git a/installer.sh b/installer.sh index 527904c..8906866 100755 --- a/installer.sh +++ b/installer.sh @@ -5,7 +5,7 @@ deps=(libasound2-dev libevdev-dev liblua5.3-dev libjack-jackd2-dev pkg-config li user=$(whoami) # for bypassing user check replace "$(whoami)" with "root". tmp_path=$(mktemp -d) # Repo download path -updater_dir=/etc/midimonster-updater-installer # Updater download + config path +updater_dir=/etc/midimonster-updater # Updater download + config path updater_file=$updater_dir/updater.conf # latest_version=$(curl --silent "https://api.github.com/repos/cbdevnet/midimonster/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') @@ -39,17 +39,9 @@ done printf "\n" } -INSTALL-PREP () { -(#### Subshell make things like cd $tmp_path easier to revert - printf "\nStarting download..." - git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster - printf "\n\n\nInitializing repository..." - cd $tmp_path - git init $tmp_path - printf "\n" - - read -p "Do you want to install the nightly version? (y/n)? " magic #Asks for nightly version - case "$magic" in +NIGHTLY_CHECK () { +read -p "Do you want to install the latest developement version? (y/n)? " magic #Asks for nightly version +case "$magic" in y|Y ) printf "\nOK! You´re a risky person ;D" NIGHTLY=1 ;; @@ -59,11 +51,29 @@ INSTALL-PREP () { * ) printf "\nInvalid input" ERROR ;; - esac +esac + +if [ $NIGHTLY != 1 ] # Git checkout if NIGHTLY !=1 +then + printf "\nFinding latest stable version..." + Iversion=$(git describe --abbrev=0) + printf "\nStarting Git checkout to "$Iversion"..." + git checkout -f -q $Iversion +fi +} - if [ $NIGHTLY != 1 ]; then printf "\nFinding latest stable version..."; Iversion=$(git describe --abbrev=0); printf "\nStarting Git checkout to "$Iversion"..."; git checkout -f -q $Iversion; fi # Git checkout if NIGHTLY !=1 - printf "\nPreparing Done.\n\n\n" +INSTALL-PREP () { +(#### Subshell make things like cd $tmp_path easier to revert + printf "\nStarting download..." + git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster + printf "\n\n\nInitializing repository...\n" + cd $tmp_path + git init $tmp_path + printf "\n" ) +NIGHTLY_CHECK +printf "\nPreparing Done.\n\n\n" + printf "${bold}If you don't know what you're doing, just hit enter 4 times.${normal}\n" read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX @@ -97,25 +107,10 @@ UPDATER-PREP () { printf "\nInitializing repository..." cd $tmp_path git init $tmp_path - printf "\n" - - read -p "Do you want to install the nightly version? (y/n)? " magic #Asks for nightly version - case "$magic" in - y|Y ) printf "\nOK! You´re a risky person ;D" - NIGHTLY=1 - ;; - n|N ) printf "\nThat´s ok I´ll install the latest stable version for you ;-)" - NIGHTLY=0 - ;; - * ) printf "\nInvalid input" - ERROR - ;; - esac - - if [ $NIGHTLY != 1 ]; then printf "\nFinding latest stable version..."; Iversion=$(git describe --abbrev=0); printf "\nStarting Git checkout to "$Iversion"..."; git checkout -f -q $Iversion; fi # Git checkout if NIGHTLY !=1 - printf "\nDone.\n\n\n" + printf "\nSucessfully imported Updater settings from $updater_file.\n\n\n" ) - +NIGHTLY_CHECK +printf "\nPreparing Done.\n\n\n" rm -f "$VAR_PREFIX/bin/midimonster" rm -rf "$VAR_PLUGINS/" @@ -127,26 +122,20 @@ export PLUGINS=$VAR_PLUGINS export DEFAULT_CFG=$VAR_DEFAULT_CFG export DESTDIR=$VAR_DESTDIR export EXAMPLES=$VAR_EXAMPLE_CFGS - -printf "\nSucessfully imported Updater settings from $updater_file." } UPDATER () { installed_version="$(midimonster --version)" - #installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) + installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) if [[ "$installed_version" =~ "$latest_version" ]]; then printf "\nNewest Version is already installed! ${bold}($installed_version)${normal}\n\n" ERROR else - printf "\nThe installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} ( Maybe you are running on nightly? )\n\n" + printf "\nThe installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} ( Maybe you are running a developement version? )\n\n" fi UPDATER-PREP INSTALL-RUN - - printf "\nUpdating updater/installer script in $updater_dir" - wget "https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh" -O $updater_dir - chmod +x $updater_dir/installer.sh DONE } @@ -159,12 +148,12 @@ INSTALL-RUN () { # Build UPDATER_SAVE () { # Saves file for the auto updater in this script rm -rf $updater_dir - printf "\nSaving updater to $updater_dir/installer.sh" + printf "\nSaving updater to $updater_dir/updater.sh" mkdir -p "$updater_dir" - wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh -O $updater_dir/installer.sh - printf "\nCreating symlink to updater/installer in /usr/bin/midimonster-updater-installer" - ln -s "$updater_dir/installer.sh" "/usr/bin/midimonster-updater-installer" - chmod +x "$updater_dir/installer.sh" + wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh -O $updater_dir/updater.sh + printf "\nCreating symlink to updater in /usr/bin/midimonster-updater" + ln -s "$updater_dir/updater.sh" "/usr/bin/midimonster-updater" + chmod +x "$updater_dir/updater.sh" printf "\nExporting updater config to $updater_file" printf "VAR_PREFIX=%s\nVAR_PLUGINS=%s\nVAR_DEFAULT_CFG=%s\nVAR_DESTDIR=%s\nVAR_EXAMPLE_CFGS=%s\n" "$VAR_PREFIX" "$VAR_PLUGINS" "$VAR_DEFAULT_CFG" "$VAR_DESTDIR" "$VAR_EXAMPLE_CFGS" > $updater_file } -- cgit v1.2.3 From 257d5f09fb704b165f22ece1695a6bd72a222f49 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Wed, 18 Dec 2019 21:46:53 +0100 Subject: fix testing var --- installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer.sh b/installer.sh index 8906866..d131234 100755 --- a/installer.sh +++ b/installer.sh @@ -126,7 +126,7 @@ export EXAMPLES=$VAR_EXAMPLE_CFGS UPDATER () { installed_version="$(midimonster --version)" - installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) + #installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) if [[ "$installed_version" =~ "$latest_version" ]]; then printf "\nNewest Version is already installed! ${bold}($installed_version)${normal}\n\n" ERROR -- cgit v1.2.3 From 886c8e299454176446cce82f151b85a82b26aa06 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 18 Dec 2019 22:23:34 +0100 Subject: Fix evdev division by zero --- TODO | 3 ++- backends/evdev.c | 3 +++ midimonster.c | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 6ee649f..a5b5e7c 100644 --- a/TODO +++ b/TODO @@ -4,5 +4,6 @@ Optimize core channel search (store backend offset) udp backends may ignore MTU mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway) -> documentation installer: implement an upgrade mode (check for newer versions in the repo) -evdev.c:321 divides by zero with relaxis make event collectors threadsafe to stop marshalling data... +collect & check backend API version +introduce backend logging macro diff --git a/backends/evdev.c b/backends/evdev.c index 659dc77..193b28b 100644 --- a/backends/evdev.c +++ b/backends/evdev.c @@ -208,6 +208,9 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { data->relative_axis[data->relative_axes].max *= -1; data->relative_axis[data->relative_axes].inverted = 1; } + else if(data->relative_axis[data->relative_axes].max == 0){ + fprintf(stderr, "Relative axis configuration for %s.%s has invalid range\n", inst->name, option + 8); + } data->relative_axis[data->relative_axes].current = strtoul(next_token, NULL, 0); if(data->relative_axis[data->relative_axes].code < 0){ fprintf(stderr, "Failed to configure relative axis extents for %s.%s\n", inst->name, option + 8); diff --git a/midimonster.c b/midimonster.c index 48c6fe9..2ec165b 100644 --- a/midimonster.c +++ b/midimonster.c @@ -224,7 +224,7 @@ static void event_free(){ } static void version(){ - fprintf(stdout, "MIDIMonster %s\n", MIDIMONSTER_VERSION); + printf("MIDIMonster %s\n", MIDIMONSTER_VERSION); } static int usage(char* fn){ -- cgit v1.2.3 From afe2f2a9cb809e4a28ae519db239fa0e4f136685 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 18 Dec 2019 22:47:57 +0100 Subject: Style fixes in installer --- TODO | 1 - installer.sh | 281 ++++++++++++++++++++++++++++++----------------------------- 2 files changed, 143 insertions(+), 139 deletions(-) diff --git a/TODO b/TODO index a5b5e7c..6dc3d72 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,6 @@ Note source in channel value struct Optimize core channel search (store backend offset) udp backends may ignore MTU mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway) -> documentation -installer: implement an upgrade mode (check for newer versions in the repo) make event collectors threadsafe to stop marshalling data... collect & check backend API version introduce backend logging macro diff --git a/installer.sh b/installer.sh index d131234..c17d847 100755 --- a/installer.sh +++ b/installer.sh @@ -6,7 +6,7 @@ user=$(whoami) # for bypassing user check replace "$(whoami)" w tmp_path=$(mktemp -d) # Repo download path updater_dir=/etc/midimonster-updater # Updater download + config path -updater_file=$updater_dir/updater.conf # +updater_file=$updater_dir/updater.conf latest_version=$(curl --silent "https://api.github.com/repos/cbdevnet/midimonster/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') @@ -26,154 +26,153 @@ normal=$(tput sgr0) ############################################## FUNCTIONS ############################################## INSTALL-DEPS () { ##Install deps from array "$deps" -for t in ${deps[@]}; do - if [ $(dpkg-query -W -f='${Status}' $t 2>/dev/null | grep -c "ok installed") -eq 0 ]; - then - printf "\nInstalling "$t""; - apt-get install $t; - printf "\nDone."; - else - printf "\n"$t" already installed!" - fi -done -printf "\n" + for t in ${deps[@]}; do + if [ $(dpkg-query -W -f='${Status}' $t 2>/dev/null | grep -c "ok installed") -eq 0 ]; then + printf "Installing %s\n" "$t" + apt-get install $t; + printf "Done\n"; + else + printf "%s already installed!\n" "$t" + fi + done + printf "\n" } NIGHTLY_CHECK () { -read -p "Do you want to install the latest developement version? (y/n)? " magic #Asks for nightly version -case "$magic" in - y|Y ) printf "\nOK! You´re a risky person ;D" - NIGHTLY=1 - ;; - n|N ) printf "\nThat´s ok I´ll install the latest stable version for you ;-)" - NIGHTLY=0 - ;; - * ) printf "\nInvalid input" - ERROR - ;; -esac - -if [ $NIGHTLY != 1 ] # Git checkout if NIGHTLY !=1 -then - printf "\nFinding latest stable version..." - Iversion=$(git describe --abbrev=0) - printf "\nStarting Git checkout to "$Iversion"..." - git checkout -f -q $Iversion -fi + #Asks for nightly version + read -p "Do you want to install the latest developement version? (y/n)? " magic + case "$magic" in + y|Y) + printf "OK! You´re a risky person ;D\n" + NIGHTLY=1 + ;; + n|N) + printf "That´s OK - installing the latest stable version for you ;-)\n" + NIGHTLY=0 + ;; + *) + printf "Invalid input\n" + ERROR + ;; + esac + + # Roll back to last tag if we're not on a nightly build + if [ "$NIGHTLY" != 1 ]; then + printf "Finding latest stable version...\n" + Iversion=$(git describe --abbrev=0) + printf "Starting Git checkout to %s...\n" "$Iversion" + git checkout -f -q $Iversion + fi } INSTALL-PREP () { -(#### Subshell make things like cd $tmp_path easier to revert - printf "\nStarting download..." - git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster - printf "\n\n\nInitializing repository...\n" - cd $tmp_path - git init $tmp_path - printf "\n" -) -NIGHTLY_CHECK -printf "\nPreparing Done.\n\n\n" - -printf "${bold}If you don't know what you're doing, just hit enter 4 times.${normal}\n" - -read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX -VAR_PREFIX="${input:-$VAR_PREFIX}" - -read -e -i "$VAR_PLUGINS" -p "PLUGINS (Plugin directory): " input # Reads VAR_PLUGINS -VAR_PLUGINS="${input:-$VAR_PLUGINS}" - -read -e -i "$VAR_DEFAULT_CFG" -p "Default config path: " input # Reads VAR_DEFAULT_CFG -VAR_DEFAULT_CFG="${input:-$VAR_DEFAULT_CFG}" - -read -e -i "$VAR_EXAMPLE_CFGS" -p "Example config directory: " input # Reads VAR_EXAMPLE_CFGS -VAR_EXAMPLE_CFGS="${input:-$VAR_EXAMPLE_CFGS}" - -UPDATER_SAVE - -export PREFIX=$VAR_PREFIX -export PLUGINS=$VAR_PLUGINS -export DEFAULT_CFG=$VAR_DEFAULT_CFG -export DESTDIR=$VAR_DESTDIR -export EXAMPLES=$VAR_EXAMPLE_CFGS + ( + printf "Starting download...\n" + git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster + printf "\nInitializing repository...\n" + cd $tmp_path + git init $tmp_path + printf "\n" + ) + NIGHTLY_CHECK + printf "Preparation successful\n\n" + printf "${bold}If you don't know what you're doing, just hit enter 4 times.${normal}\n" + + read -e -i "$VAR_PREFIX" -p "PREFIX (Install root directory): " input # Reads VAR_PREFIX + VAR_PREFIX="${input:-$VAR_PREFIX}" + + read -e -i "$VAR_PLUGINS" -p "PLUGINS (Plugin directory): " input # Reads VAR_PLUGINS + VAR_PLUGINS="${input:-$VAR_PLUGINS}" + + read -e -i "$VAR_DEFAULT_CFG" -p "Default config path: " input # Reads VAR_DEFAULT_CFG + VAR_DEFAULT_CFG="${input:-$VAR_DEFAULT_CFG}" + + read -e -i "$VAR_EXAMPLE_CFGS" -p "Example config directory: " input # Reads VAR_EXAMPLE_CFGS + VAR_EXAMPLE_CFGS="${input:-$VAR_EXAMPLE_CFGS}" + + UPDATER_SAVE + + export PREFIX=$VAR_PREFIX + export PLUGINS=$VAR_PLUGINS + export DEFAULT_CFG=$VAR_DEFAULT_CFG + export DESTDIR=$VAR_DESTDIR + export EXAMPLES=$VAR_EXAMPLE_CFGS } UPDATER-PREP () { -(#### Subshell make things like cd $tmp_path easier to revert - - - printf "\nStarting download..." - git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster - printf "\n\n" - printf "\nInitializing repository..." - cd $tmp_path - git init $tmp_path - printf "\nSucessfully imported Updater settings from $updater_file.\n\n\n" - ) -NIGHTLY_CHECK -printf "\nPreparing Done.\n\n\n" - -rm -f "$VAR_PREFIX/bin/midimonster" -rm -rf "$VAR_PLUGINS/" - -UPDATER_SAVE - -export PREFIX=$VAR_PREFIX -export PLUGINS=$VAR_PLUGINS -export DEFAULT_CFG=$VAR_DEFAULT_CFG -export DESTDIR=$VAR_DESTDIR -export EXAMPLES=$VAR_EXAMPLE_CFGS + ( + printf "Starting download...\n" + git clone https://github.com/cbdevnet/midimonster.git "$tmp_path" # Gets Midimonster + printf "\nInitializing repository...\n" + cd $tmp_path + git init $tmp_path + printf "Sucessfully imported settings from %s\n" "$updater_file" + ) + NIGHTLY_CHECK + printf "Preparation successful\n\n" + + rm -f "$VAR_PREFIX/bin/midimonster" + rm -rf "$VAR_PLUGINS/" + + UPDATER_SAVE + + export PREFIX=$VAR_PREFIX + export PLUGINS=$VAR_PLUGINS + export DEFAULT_CFG=$VAR_DEFAULT_CFG + export DESTDIR=$VAR_DESTDIR + export EXAMPLES=$VAR_EXAMPLE_CFGS } UPDATER () { - installed_version="$(midimonster --version)" - #installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) - if [[ "$installed_version" =~ "$latest_version" ]]; then - printf "\nNewest Version is already installed! ${bold}($installed_version)${normal}\n\n" - ERROR - else - printf "\nThe installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} ( Maybe you are running a developement version? )\n\n" - fi - - UPDATER-PREP - INSTALL-RUN - DONE - } + installed_version="$(midimonster --version)" + #installed_version="MIDIMonster v0.3-40-gafed325" # FOR TESTING ONLY! (or bypassing updater version check) + if [[ "$installed_version" =~ "$latest_version" ]]; then + printf "Newest Version is already installed! ${bold}($installed_version)${normal}\n\n" + ERROR + else + printf "The installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} ( Maybe you are running a developement version? )\n\n" + fi + + UPDATER-PREP + INSTALL-RUN + DONE +} INSTALL-RUN () { # Build - cd "$tmp_path" - make clean - make $makeargs - make install + cd "$tmp_path" + make clean + make $makeargs + make install } UPDATER_SAVE () { # Saves file for the auto updater in this script - rm -rf $updater_dir - printf "\nSaving updater to $updater_dir/updater.sh" - mkdir -p "$updater_dir" - wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh -O $updater_dir/updater.sh - printf "\nCreating symlink to updater in /usr/bin/midimonster-updater" - ln -s "$updater_dir/updater.sh" "/usr/bin/midimonster-updater" - chmod +x "$updater_dir/updater.sh" - printf "\nExporting updater config to $updater_file" - printf "VAR_PREFIX=%s\nVAR_PLUGINS=%s\nVAR_DEFAULT_CFG=%s\nVAR_DESTDIR=%s\nVAR_EXAMPLE_CFGS=%s\n" "$VAR_PREFIX" "$VAR_PLUGINS" "$VAR_DEFAULT_CFG" "$VAR_DESTDIR" "$VAR_EXAMPLE_CFGS" > $updater_file + rm -rf $updater_dir + printf "Saving updater to %s/updater.sh\n" "$update_dir" + mkdir -p "$updater_dir" + wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh -O $updater_dir/updater.sh + printf "Creating symlink to updater in /usr/bin/midimonster-updater\n" + ln -s "$updater_dir/updater.sh" "/usr/bin/midimonster-updater\n" + chmod +x "$updater_dir/updater.sh" + printf "Exporting updater config to %s\n" "$updater_file" + printf "VAR_PREFIX=%s\nVAR_PLUGINS=%s\nVAR_DEFAULT_CFG=%s\nVAR_DESTDIR=%s\nVAR_EXAMPLE_CFGS=%s\n" "$VAR_PREFIX" "$VAR_PLUGINS" "$VAR_DEFAULT_CFG" "$VAR_DESTDIR" "$VAR_EXAMPLE_CFGS" > $updater_file } ERROR () { - printf "\nAborting..." - CLEAN - printf "Exiting...\n\n\n" - exit 1 + printf "\nAborting...\n" + CLEAN + printf "Exiting...\n" + exit 1 } DONE () { - printf "\n\nDone." - CLEAN - exit 0 + printf "\nDone.\n" + CLEAN + exit 0 } CLEAN () { - printf "\nCleaning...\n\n" - rm -rf $tmp_path + printf "\nCleaning...\n" + rm -rf $tmp_path } ############################################## FUNCTIONS ############################################## @@ -183,26 +182,32 @@ CLEAN () { trap ERROR SIGINT SIGTERM SIGKILL clear -if [ "$user" != "root" ]; then printf "\nInstaller must be run as root"; ERROR; fi # Check if $user = root! -if [ $(wget -q --spider http://github.com) $? -eq 1 ]; then printf "\nYou need connection to the internet"; ERROR; fi - -if [ -f $updater_file ] # Checks if updater config file exist and import it(overwrite default values!) -then - - printf "\nStarting updater...\n\n" - . $updater_file +# Check if $user = root! +if [ "$user" != "root" ]; then + printf "Installer must be run as root\n" + ERROR +fi - if [ -x "$VAR_PREFIX/bin/midimonster" ] # Check if binary $updater/bin/midimonster exist. If yes start updater else skip. - then - UPDATER - else - printf "\nMidimonster binary not found, skipping updater.\n" - fi +if [ $(wget -q --spider http://github.com) $? -eq 1 ]; then + printf "You need connection to the internet\n" + ERROR +fi +# Check if updater config file exist and import it (overwrites default values!) +if [ -f $updater_file ]; then + printf "Starting updater...\n\n" + . $updater_file + + # Check if binary $updater/bin/midimonster exist. If yes start updater else skip. + if [ -x "$VAR_PREFIX/bin/midimonster" ]; then + UPDATER + else + printf "midimonster binary not found, skipping updater.\n" + fi fi INSTALL-DEPS INSTALL-PREP printf "\n" INSTALL-RUN -DONE \ No newline at end of file +DONE -- cgit v1.2.3 From a25e815c4d5b4af5068ed3254be8e18c4c4fe7ab Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 18 Dec 2019 23:26:13 +0100 Subject: Fix spelling --- installer.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer.sh b/installer.sh index c17d847..04207cb 100755 --- a/installer.sh +++ b/installer.sh @@ -40,7 +40,7 @@ INSTALL-DEPS () { ##Install deps from array "$deps" NIGHTLY_CHECK () { #Asks for nightly version - read -p "Do you want to install the latest developement version? (y/n)? " magic + read -p "Do you want to install the latest development version? (y/n)? " magic case "$magic" in y|Y) printf "OK! You´re a risky person ;D\n" @@ -130,7 +130,7 @@ UPDATER () { printf "Newest Version is already installed! ${bold}($installed_version)${normal}\n\n" ERROR else - printf "The installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} ( Maybe you are running a developement version? )\n\n" + printf "The installed Version ${bold}´$installed_version´${normal} equals not the newest stable version ${bold}´$latest_version´${normal} (Maybe you are running a development version?)\n\n" fi UPDATER-PREP -- cgit v1.2.3 From 5edccc6653eabe44079d82a7fbb96fd325b05177 Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 19 Dec 2019 22:18:12 +0100 Subject: Fix installer symlink (Fixes #40) --- installer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer.sh b/installer.sh index 04207cb..c85b70e 100755 --- a/installer.sh +++ b/installer.sh @@ -151,7 +151,7 @@ UPDATER_SAVE () { # Saves file for the auto up mkdir -p "$updater_dir" wget https://raw.githubusercontent.com/cbdevnet/midimonster/master/installer.sh -O $updater_dir/updater.sh printf "Creating symlink to updater in /usr/bin/midimonster-updater\n" - ln -s "$updater_dir/updater.sh" "/usr/bin/midimonster-updater\n" + ln -s "$updater_dir/updater.sh" "/usr/bin/midimonster-updater" chmod +x "$updater_dir/updater.sh" printf "Exporting updater config to %s\n" "$updater_file" printf "VAR_PREFIX=%s\nVAR_PLUGINS=%s\nVAR_DEFAULT_CFG=%s\nVAR_DESTDIR=%s\nVAR_EXAMPLE_CFGS=%s\n" "$VAR_PREFIX" "$VAR_PLUGINS" "$VAR_DEFAULT_CFG" "$VAR_DESTDIR" "$VAR_EXAMPLE_CFGS" > $updater_file -- cgit v1.2.3 From 062c93b1f718730c71bc4d2a1e53e0107dd236ad Mon Sep 17 00:00:00 2001 From: cbdev Date: Fri, 20 Dec 2019 21:29:18 +0100 Subject: Route all backend debug logging through a macro --- TODO | 1 - backends/artnet.c | 61 ++++++++++++++------------- backends/evdev.c | 78 +++++++++++++++++----------------- backends/jack.c | 107 ++++++++++++++++++++++++----------------------- backends/libmmbackend.c | 18 ++++---- backends/loopback.c | 14 +++---- backends/lua.c | 42 +++++++++---------- backends/maweb.c | 95 ++++++++++++++++++++--------------------- backends/midi.c | 53 +++++++++++------------ backends/ola.cpp | 35 ++++++++-------- backends/osc.c | 109 ++++++++++++++++++++++++------------------------ backends/sacn.c | 77 +++++++++++++++++----------------- backends/winmidi.c | 84 ++++++++++++++++++------------------- midimonster.h | 13 ++++-- 14 files changed, 401 insertions(+), 386 deletions(-) diff --git a/TODO b/TODO index 6dc3d72..ee58777 100644 --- a/TODO +++ b/TODO @@ -5,4 +5,3 @@ udp backends may ignore MTU mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway) -> documentation make event collectors threadsafe to stop marshalling data... collect & check backend API version -introduce backend logging macro diff --git a/backends/artnet.c b/backends/artnet.c index aa7c48e..0bd1a32 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "artnet" + #include #include #include @@ -6,7 +8,6 @@ #include "artnet.h" #define MAX_FDS 255 -#define BACKEND_NAME "artnet" static uint8_t default_net = 0; static size_t artnet_fds = 0; @@ -15,7 +16,7 @@ static artnet_descriptor* artnet_fd = NULL; static int artnet_listener(char* host, char* port){ int fd; if(artnet_fds >= MAX_FDS){ - fprintf(stderr, "ArtNet backend descriptor limit reached\n"); + LOG("Backend descriptor limit reached"); return -1; } @@ -28,11 +29,11 @@ static int artnet_listener(char* host, char* port){ artnet_fd = realloc(artnet_fd, (artnet_fds + 1) * sizeof(artnet_descriptor)); if(!artnet_fd){ close(fd); - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return -1; } - fprintf(stderr, "ArtNet backend interface %" PRIsize_t " bound to %s port %s\n", artnet_fds, host, port); + LOGPF("Interface %" PRIsize_t " bound to %s port %s", artnet_fds, host, port); artnet_fd[artnet_fds].fd = fd; artnet_fd[artnet_fds].output_instances = 0; artnet_fd[artnet_fds].output_instance = NULL; @@ -55,13 +56,13 @@ MM_PLUGIN_API int init(){ }; if(sizeof(artnet_instance_id) != sizeof(uint64_t)){ - fprintf(stderr, "ArtNet instance identification union out of bounds\n"); + LOG("Instance identification union out of bounds"); return 1; } //register backend if(mm_backend_register(artnet)){ - fprintf(stderr, "Failed to register ArtNet backend\n"); + LOG("Failed to register backend"); return 1; } return 0; @@ -78,18 +79,18 @@ static int artnet_configure(char* option, char* value){ mmbackend_parse_hostspec(value, &host, &port, &fd_opts); if(!host){ - fprintf(stderr, "Not valid ArtNet bind address given\n"); + LOGPF("%s is not a valid bind address", value); return 1; } if(artnet_listener(host, (port ? port : ARTNET_PORT))){ - fprintf(stderr, "Failed to bind ArtNet descriptor: %s\n", value); + LOGPF("Failed to bind descriptor: %s", value); return 1; } return 0; } - fprintf(stderr, "Unknown ArtNet backend option %s\n", option); + LOGPF("Unknown backend option %s", option); return 1; } @@ -102,7 +103,7 @@ static instance* artnet_instance(){ data = calloc(1, sizeof(artnet_instance_data)); if(!data){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -128,7 +129,7 @@ static int artnet_configure_instance(instance* inst, char* option, char* value){ data->fd_index = strtoul(value, NULL, 0); if(data->fd_index >= artnet_fds){ - fprintf(stderr, "Invalid interface configured for ArtNet instance %s\n", inst->name); + LOGPF("Invalid interface configured for instance %s", inst->name); return 1; } return 0; @@ -137,14 +138,14 @@ static int artnet_configure_instance(instance* inst, char* option, char* value){ mmbackend_parse_hostspec(value, &host, &port, NULL); if(!host){ - fprintf(stderr, "Not a valid ArtNet destination for instance %s\n", inst->name); + LOGPF("Not a valid destination for instance %s: %s", inst->name, value); return 1; } return mmbackend_parse_sockaddr(host, port ? port : ARTNET_PORT, &data->dest_addr, &data->dest_len); } - fprintf(stderr, "Unknown ArtNet option %s for instance %s\n", option, inst->name); + LOGPF("Unknown instance option %s for instance %s", option, inst->name); return 1; } @@ -156,7 +157,7 @@ static channel* artnet_channel(instance* inst, char* spec, uint8_t flags){ //primary channel sanity check if(!chan_a || chan_a > 512){ - fprintf(stderr, "Invalid ArtNet channel specification %s\n", spec); + LOGPF("Invalid channel specification %s", spec); return NULL; } chan_a--; @@ -165,14 +166,14 @@ static channel* artnet_channel(instance* inst, char* spec, uint8_t flags){ if(*spec_next == '+'){ chan_b = strtoul(spec_next + 1, NULL, 10); if(!chan_b || chan_b > 512){ - fprintf(stderr, "Invalid wide-channel spec %s\n", spec); + LOGPF("Invalid wide-channel specification %s", spec); return NULL; } chan_b--; //if mapped mode differs, bail if(IS_ACTIVE(data->data.map[chan_b]) && data->data.map[chan_b] != (MAP_FINE | chan_a)){ - fprintf(stderr, "Fine channel already mapped for ArtNet spec %s\n", spec); + LOGPF("Fine channel already mapped for spec %s", spec); return NULL; } @@ -183,7 +184,7 @@ static channel* artnet_channel(instance* inst, char* spec, uint8_t flags){ if(IS_ACTIVE(data->data.map[chan_a])){ if((*spec_next == '+' && data->data.map[chan_a] != (MAP_COARSE | chan_b)) || (*spec_next != '+' && data->data.map[chan_a] != (MAP_SINGLE | chan_a))){ - fprintf(stderr, "Primary ArtNet channel already mapped at differing mode: %s\n", spec); + LOGPF("Primary channel already mapped at differing mode: %s", spec); return NULL; } } @@ -210,7 +211,7 @@ static int artnet_transmit(instance* inst){ memcpy(frame.data, data->data.out, 512); if(sendto(artnet_fd[data->fd_index].fd, (uint8_t*) &frame, sizeof(frame), 0, (struct sockaddr*) &data->dest_addr, data->dest_len) < 0){ - fprintf(stderr, "Failed to output ArtNet frame for instance %s: %s\n", inst->name, strerror(errno)); + LOGPF("Failed to output frame for instance %s: %s", inst->name, strerror(errno)); } //update last frame timestamp @@ -227,7 +228,7 @@ static int artnet_set(instance* inst, size_t num, channel** c, channel_value* v) artnet_instance_data* data = (artnet_instance_data*) inst->impl; if(!data->dest_len){ - fprintf(stderr, "ArtNet instance %s not enabled for output (%" PRIsize_t " channel events)\n", inst->name, num); + LOGPF("Instance %s not enabled for output (%" PRIsize_t " channel events)", inst->name, num); return 0; } @@ -267,7 +268,7 @@ static inline int artnet_process_frame(instance* inst, artnet_pkt* frame){ artnet_instance_data* data = (artnet_instance_data*) inst->impl; if(be16toh(frame->length) > 512){ - fprintf(stderr, "Invalid ArtNet frame channel count\n"); + LOGPF("Invalid frame channel count: %d", be16toh(frame->length)); return 1; } @@ -292,7 +293,7 @@ static inline int artnet_process_frame(instance* inst, artnet_pkt* frame){ } if(!chan){ - fprintf(stderr, "Active channel %" PRIsize_t " on %s not known to core\n", p, inst->name); + LOGPF("Active channel %" PRIsize_t " on %s not known to core", p, inst->name); return 1; } @@ -311,7 +312,7 @@ static inline int artnet_process_frame(instance* inst, artnet_pkt* frame){ } if(mm_channel_event(chan, val)){ - fprintf(stderr, "Failed to push ArtNet channel event to core\n"); + LOG("Failed to push channel event to core"); return 1; } } @@ -358,7 +359,7 @@ static int artnet_handle(size_t num, managed_fd* fds){ inst_id.fields.uni = frame->universe; inst = mm_instance_find(BACKEND_NAME, inst_id.label); if(inst && artnet_process_frame(inst, frame)){ - fprintf(stderr, "Failed to process ArtNet frame\n"); + LOG("Failed to process frame"); } } } @@ -369,11 +370,11 @@ static int artnet_handle(size_t num, managed_fd* fds){ #else if(bytes_read < 0 && errno != EAGAIN){ #endif - fprintf(stderr, "ArtNet failed to receive data: %s\n", strerror(errno)); + LOGPF("Failed to receive data: %s", strerror(errno)); } if(bytes_read == 0){ - fprintf(stderr, "ArtNet listener closed\n"); + LOG("Listener closed"); return 1; } } @@ -390,7 +391,7 @@ static int artnet_start(size_t n, instance** inst){ }; if(!artnet_fds){ - fprintf(stderr, "Failed to start ArtNet backend: no descriptors bound\n"); + LOG("Failed to start backend: no descriptors bound"); return 1; } @@ -405,7 +406,7 @@ static int artnet_start(size_t n, instance** inst){ //check for duplicates for(p = 0; p < u; p++){ if(inst[u]->ident == inst[p]->ident){ - fprintf(stderr, "Universe specified multiple times, use one instance: %s - %s\n", inst[u]->name, inst[p]->name); + LOGPF("Universe specified multiple times, use one instance: %s - %s", inst[u]->name, inst[p]->name); goto bail; } } @@ -416,7 +417,7 @@ static int artnet_start(size_t n, instance** inst){ artnet_fd[data->fd_index].last_frame = realloc(artnet_fd[data->fd_index].last_frame, (artnet_fd[data->fd_index].output_instances + 1) * sizeof(uint64_t)); if(!artnet_fd[data->fd_index].output_instance || !artnet_fd[data->fd_index].last_frame){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); goto bail; } artnet_fd[data->fd_index].output_instance[artnet_fd[data->fd_index].output_instances] = id; @@ -426,7 +427,7 @@ static int artnet_start(size_t n, instance** inst){ } } - fprintf(stderr, "ArtNet backend registering %" PRIsize_t " descriptors to core\n", artnet_fds); + LOGPF("Registering %" PRIsize_t " descriptors to core", artnet_fds); for(u = 0; u < artnet_fds; u++){ if(mm_manage_fd(artnet_fd[u].fd, BACKEND_NAME, 1, (void*) u)){ goto bail; @@ -452,6 +453,6 @@ static int artnet_shutdown(size_t n, instance** inst){ } free(artnet_fd); - fprintf(stderr, "ArtNet backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/evdev.c b/backends/evdev.c index 193b28b..4725ef7 100644 --- a/backends/evdev.c +++ b/backends/evdev.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "evdev" + #include #include #include @@ -16,8 +18,6 @@ #include "midimonster.h" #include "evdev.h" -#define BACKEND_NAME "evdev" - static struct { uint8_t detect; } evdev_config = { @@ -38,12 +38,12 @@ MM_PLUGIN_API int init(){ }; if(sizeof(evdev_channel_ident) != sizeof(uint64_t)){ - fprintf(stderr, "evdev channel identification union out of bounds\n"); + LOG("Channel identification union out of bounds"); return 1; } if(mm_backend_register(evdev)){ - fprintf(stderr, "Failed to register evdev backend\n"); + LOG("Failed to register backend"); return 1; } @@ -59,7 +59,7 @@ static int evdev_configure(char* option, char* value) { return 0; } - fprintf(stderr, "Unknown configuration option %s for evdev backend\n", option); + LOGPF("Unknown backend configuration option %s", option); return 1; } @@ -71,7 +71,7 @@ static instance* evdev_instance(){ evdev_instance_data* data = calloc(1, sizeof(evdev_instance_data)); if(!data){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -79,7 +79,7 @@ static instance* evdev_instance(){ #ifndef EVDEV_NO_UINPUT data->output_proto = libevdev_new(); if(!data->output_proto){ - fprintf(stderr, "Failed to initialize libevdev output prototype device\n"); + LOG("Failed to initialize libevdev output prototype device"); free(data); return NULL; } @@ -91,25 +91,25 @@ static instance* evdev_instance(){ static int evdev_attach(instance* inst, evdev_instance_data* data, char* node){ if(data->input_fd >= 0){ - fprintf(stderr, "Instance %s already was assigned an input device\n", inst->name); + LOGPF("Instance %s already assigned an input device", inst->name); return 1; } data->input_fd = open(node, O_RDONLY | O_NONBLOCK); if(data->input_fd < 0){ - fprintf(stderr, "Failed to open evdev input device node %s: %s\n", node, strerror(errno)); + LOGPF("Failed to open input device node %s: %s", node, strerror(errno)); return 1; } if(libevdev_new_from_fd(data->input_fd, &data->input_ev)){ - fprintf(stderr, "Failed to initialize libevdev for %s\n", node); + LOGPF("Failed to initialize libevdev for %s", node); close(data->input_fd); data->input_fd = -1; return 1; } if(data->exclusive && libevdev_grab(data->input_ev, LIBEVDEV_GRAB)){ - fprintf(stderr, "Failed to obtain exclusive device access on %s\n", node); + LOGPF("Failed to obtain exclusive device access on %s", node); } return 0; @@ -123,7 +123,7 @@ static char* evdev_find(char* name){ char device_name[UINPUT_MAX_NAME_SIZE], *result = NULL; if(!nodes){ - fprintf(stderr, "Failed to query input device nodes in %s: %s", INPUT_NODES, strerror(errno)); + LOGPF("Failed to query input device nodes in %s: %s", INPUT_NODES, strerror(errno)); return NULL; } @@ -133,12 +133,12 @@ static char* evdev_find(char* name){ fd = open(file_path, O_RDONLY); if(fd < 0){ - fprintf(stderr, "Failed to access %s: %s\n", file_path, strerror(errno)); + LOGPF("Failed to access %s: %s", file_path, strerror(errno)); continue; } if(ioctl(fd, EVIOCGNAME(sizeof(device_name)), device_name) < 0){ - fprintf(stderr, "Failed to read name for %s: %s\n", file_path, strerror(errno)); + LOGPF("Failed to read name for %s: %s", file_path, strerror(errno)); close(fd); continue; } @@ -146,7 +146,7 @@ static char* evdev_find(char* name){ close(fd); if(!strncmp(device_name, name, strlen(name))){ - fprintf(stderr, "Matched name %s for %s: %s\n", device_name, name, file_path); + LOGPF("Matched name %s for %s: %s", device_name, name, file_path); break; } } @@ -178,7 +178,7 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { else if(!strcmp(option, "input")){ next_token = evdev_find(value); if(!next_token){ - fprintf(stderr, "Failed to find evdev input device with name %s for instance %s\n", value, inst->name); + LOGPF("Failed to match input device with name %s for instance %s", value, inst->name); return 1; } if(evdev_attach(inst, data, next_token)){ @@ -190,7 +190,7 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { } else if(!strcmp(option, "exclusive")){ if(data->input_fd >= 0 && libevdev_grab(data->input_ev, LIBEVDEV_GRAB)){ - fprintf(stderr, "Failed to obtain exclusive device access on %s\n", inst->name); + LOGPF("Failed to obtain exclusive device access on %s", inst->name); } data->exclusive = 1; return 0; @@ -198,7 +198,7 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { else if(!strncmp(option, "relaxis.", 8)){ data->relative_axis = realloc(data->relative_axis, (data->relative_axes + 1) * sizeof(evdev_relaxis_config)); if(!data->relative_axis){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } data->relative_axis[data->relative_axes].inverted = 0; @@ -209,11 +209,11 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { data->relative_axis[data->relative_axes].inverted = 1; } else if(data->relative_axis[data->relative_axes].max == 0){ - fprintf(stderr, "Relative axis configuration for %s.%s has invalid range\n", inst->name, option + 8); + LOGPF("Relative axis configuration for %s.%s has invalid range", inst->name, option + 8); } data->relative_axis[data->relative_axes].current = strtoul(next_token, NULL, 0); if(data->relative_axis[data->relative_axes].code < 0){ - fprintf(stderr, "Failed to configure relative axis extents for %s.%s\n", inst->name, option + 8); + LOGPF("Failed to configure relative axis extents for %s.%s", inst->name, option + 8); return 1; } data->relative_axes++; @@ -242,13 +242,13 @@ static int evdev_configure_instance(instance* inst, char* option, char* value) { abs_info.flat = strtol(next_token, &next_token, 0); abs_info.resolution = strtol(next_token, &next_token, 0); if(libevdev_enable_event_code(data->output_proto, EV_ABS, libevdev_event_code_from_name(EV_ABS, option + 5), &abs_info)){ - fprintf(stderr, "Failed to enable absolute axis %s for output\n", option + 5); + LOGPF("Failed to enable absolute axis %s.%s for output", inst->name, option + 5); return 1; } return 0; } #endif - fprintf(stderr, "Unknown instance configuration parameter %s for evdev instance %s\n", option, inst->name); + LOGPF("Unknown instance configuration parameter %s for instance %s", option, inst->name); return 1; } @@ -262,14 +262,14 @@ static channel* evdev_channel(instance* inst, char* spec, uint8_t flags){ }; if(!separator){ - fprintf(stderr, "Invalid evdev channel specification %s\n", spec); + LOGPF("Invalid channel specification %s", spec); return NULL; } *(separator++) = 0; if(libevdev_event_type_from_name(spec) < 0){ - fprintf(stderr, "Invalid evdev type specification: %s", spec); + LOGPF("Invalid type specification: %s", spec); return NULL; } ident.fields.type = libevdev_event_type_from_name(spec); @@ -278,7 +278,7 @@ static channel* evdev_channel(instance* inst, char* spec, uint8_t flags){ ident.fields.code = libevdev_event_code_from_name(ident.fields.type, separator); } else{ - fprintf(stderr, "evdev Code name not recognized, using as number: %s\n", separator); + LOGPF("Code name not recognized, using as number: %s.%s", inst->name, separator); ident.fields.code = strtoul(separator, NULL, 10); } @@ -288,7 +288,7 @@ static channel* evdev_channel(instance* inst, char* spec, uint8_t flags){ //enable the event on the device //the previous check is necessary to not fail while enabling axes, which require additional information if(libevdev_enable_event_code(data->output_proto, ident.fields.type, ident.fields.code, NULL)){ - fprintf(stderr, "Failed to enable output event %s.%s%s\n", + LOGPF("Failed to enable output event %s.%s%s", libevdev_event_type_get_name(ident.fields.type), libevdev_event_code_get_name(ident.fields.type, ident.fields.code), (ident.fields.type == EV_ABS) ? ": To output absolute axes, specify their details in the configuration":""); @@ -342,13 +342,13 @@ static int evdev_push_event(instance* inst, evdev_instance_data* data, struct in } if(mm_channel_event(chan, val)){ - fprintf(stderr, "Failed to push evdev channel event to core\n"); + LOG("Failed to push channel event to core"); return 1; } } if(evdev_config.detect){ - fprintf(stderr, "Incoming evdev data for channel %s.%s.%s\n", inst->name, libevdev_event_type_get_name(event.type), libevdev_event_code_get_name(event.type, event.code)); + LOGPF("Incoming data for channel %s.%s.%s", inst->name, libevdev_event_type_get_name(event.type), libevdev_event_code_get_name(event.type, event.code)); } return 0; @@ -369,7 +369,7 @@ static int evdev_handle(size_t num, managed_fd* fds){ for(fd = 0; fd < num; fd++){ inst = (instance*) fds[fd].impl; if(!inst){ - fprintf(stderr, "evdev backend signaled for unknown fd\n"); + LOG("Signaled for unknown FD"); continue; } @@ -406,29 +406,29 @@ static int evdev_start(size_t n, instance** inst){ #ifndef EVDEV_NO_UINPUT if(data->output_enabled){ if(libevdev_uinput_create_from_device(data->output_proto, LIBEVDEV_UINPUT_OPEN_MANAGED, &data->output_ev)){ - fprintf(stderr, "Failed to create evdev output device: %s\n", strerror(errno)); + LOGPF("Failed to create output device: %s", strerror(errno)); return 1; } - fprintf(stderr, "Created device node %s for instance %s\n", libevdev_uinput_get_devnode(data->output_ev), inst[u]->name); + LOGPF("Created device node %s for instance %s", libevdev_uinput_get_devnode(data->output_ev), inst[u]->name); } #endif inst[u]->ident = data->input_fd; if(data->input_fd >= 0){ if(mm_manage_fd(data->input_fd, BACKEND_NAME, 1, inst[u])){ - fprintf(stderr, "Failed to register event input descriptor for instance %s\n", inst[u]->name); + LOGPF("Failed to register input descriptor for instance %s", inst[u]->name); return 1; } fds++; } if(data->input_fd <= 0 && !data->output_ev){ - fprintf(stderr, "Instance %s has neither input nor output device set up\n", inst[u]->name); + LOGPF("Instance %s has neither input nor output device set up", inst[u]->name); } } - fprintf(stderr, "evdev backend registered %zu descriptors to core\n", fds); + LOGPF("Registered %zu descriptors to core", fds); return 0; } @@ -447,7 +447,7 @@ static int evdev_set(instance* inst, size_t num, channel** c, channel_value* v) } if(!data->output_enabled){ - fprintf(stderr, "Instance %s not enabled for output\n", inst->name); + LOGPF("Instance %s not enabled for output (%" PRIsize_t " channel events)", inst->name, num); return 0; } @@ -483,20 +483,20 @@ static int evdev_set(instance* inst, size_t num, channel** c, channel_value* v) } if(libevdev_uinput_write_event(data->output_ev, ident.fields.type, ident.fields.code, value)){ - fprintf(stderr, "Failed to output event on instance %s\n", inst->name); + LOGPF("Failed to output event on instance %s", inst->name); return 1; } } //send syn event to publish all events if(libevdev_uinput_write_event(data->output_ev, EV_SYN, SYN_REPORT, 0)){ - fprintf(stderr, "Failed to output sync event on instance %s\n", inst->name); + LOGPF("Failed to output sync event on instance %s", inst->name); return 1; } return 0; #else - fprintf(stderr, "The evdev backend does not support output on this platform\n"); + LOG("No output support on this platform"); return 1; #endif } @@ -525,6 +525,6 @@ static int evdev_shutdown(size_t n, instance** inst){ free(inst[u]->impl); } - fprintf(stderr, "evdev backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/jack.c b/backends/jack.c index 42ecee3..d7f68c4 100644 --- a/backends/jack.c +++ b/backends/jack.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "jack" + #include #include #include @@ -8,7 +10,6 @@ #include #include -#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); @@ -729,6 +730,6 @@ static int mmjack_shutdown(size_t n, instance** inst){ free(inst[u]->impl); } - fprintf(stderr, "jack backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/libmmbackend.c b/backends/libmmbackend.c index 7dbb4ae..ffa403b 100644 --- a/backends/libmmbackend.c +++ b/backends/libmmbackend.c @@ -1,5 +1,7 @@ #include "libmmbackend.h" +#define LOGPF(format, ...) fprintf(stderr, "libmmbe\t" format "\n", __VA_ARGS__) + void mmbackend_parse_hostspec(char* spec, char** host, char** port, char** options){ size_t u = 0; @@ -52,7 +54,7 @@ int mmbackend_parse_sockaddr(char* host, char* port, struct sockaddr_storage* ad int error = getaddrinfo(host, port, &hints, &head); if(error || !head){ - fprintf(stderr, "Failed to parse address %s port %s: %s\n", host, port, gai_strerror(error)); + LOGPF("Failed to parse address %s port %s: %s", host, port, gai_strerror(error)); return 1; } @@ -76,7 +78,7 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uin status = getaddrinfo(host, port, &hints, &info); if(status){ - fprintf(stderr, "Failed to parse address %s port %s: %s\n", host, port, gai_strerror(status)); + LOGPF("Failed to parse address %s port %s: %s", host, port, gai_strerror(status)); return -1; } @@ -90,18 +92,18 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uin //set required socket options yes = 1; if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0){ - fprintf(stderr, "Failed to enable SO_REUSEADDR on socket\n"); + LOGPF("Failed to enable SO_REUSEADDR on socket: %s", strerror(errno)); } if(mcast){ yes = 1; if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&yes, sizeof(yes)) < 0){ - fprintf(stderr, "Failed to enable SO_BROADCAST on socket\n"); + LOGPF("Failed to enable SO_BROADCAST on socket: %s", strerror(errno)); } yes = 0; if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&yes, sizeof(yes)) < 0){ - fprintf(stderr, "Failed to disable IP_MULTICAST_LOOP on socket: %s\n", strerror(errno)); + LOGPF("Failed to disable IP_MULTICAST_LOOP on socket: %s", strerror(errno)); } } @@ -125,7 +127,7 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uin freeaddrinfo(info); if(!addr_it){ - fprintf(stderr, "Failed to create socket for %s port %s\n", host, port); + LOGPF("Failed to create socket for %s port %s", host, port); return -1; } @@ -139,7 +141,7 @@ int mmbackend_socket(char* host, char* port, int socktype, uint8_t listener, uin #else int flags = fcntl(fd, F_GETFL, 0); if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0){ - fprintf(stderr, "Failed to set socket nonblocking\n"); + LOGPF("Failed to set socket nonblocking: %s", strerror(errno)); close(fd); return -1; } @@ -153,7 +155,7 @@ int mmbackend_send(int fd, uint8_t* data, size_t length){ while(total < length){ sent = send(fd, data + total, length - total, 0); if(sent < 0){ - fprintf(stderr, "Failed to send: %s\n", strerror(errno)); + LOGPF("Failed to send: %s", strerror(errno)); return 1; } total += sent; diff --git a/backends/loopback.c b/backends/loopback.c index c2c3430..085d1df 100644 --- a/backends/loopback.c +++ b/backends/loopback.c @@ -1,8 +1,8 @@ +#define BACKEND_NAME "loopback" + #include #include "loopback.h" -#define BACKEND_NAME "loopback" - MM_PLUGIN_API int init(){ backend loopback = { .name = BACKEND_NAME, @@ -18,7 +18,7 @@ MM_PLUGIN_API int init(){ //register backend if(mm_backend_register(loopback)){ - fprintf(stderr, "Failed to register loopback backend\n"); + LOG("Failed to register backend"); return 1; } return 0; @@ -42,7 +42,7 @@ static instance* loopback_instance(){ i->impl = calloc(1, sizeof(loopback_instance_data)); if(!i->impl){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -64,13 +64,13 @@ static channel* loopback_channel(instance* inst, char* spec, uint8_t flags){ if(u == data->n){ data->name = realloc(data->name, (u + 1) * sizeof(char*)); if(!data->name){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } data->name[u] = strdup(spec); if(!data->name[u]){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } data->n++; @@ -109,6 +109,6 @@ static int loopback_shutdown(size_t n, instance** inst){ free(inst[u]->impl); } - fprintf(stderr, "Loopback backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/lua.c b/backends/lua.c index 2ce40f5..ee9e03f 100644 --- a/backends/lua.c +++ b/backends/lua.c @@ -1,5 +1,6 @@ -#include "lua.h" +#define BACKEND_NAME "lua" +#include "lua.h" #include #include #include @@ -7,7 +8,6 @@ #include #endif -#define BACKEND_NAME "lua" #define LUA_REGISTRY_KEY "_midimonster_lua_instance" static size_t timers = 0; @@ -37,7 +37,7 @@ MM_PLUGIN_API int init(){ //register backend if(mm_backend_register(lua)){ - fprintf(stderr, "Failed to register lua backend\n"); + LOG("Failed to register backend"); return 1; } @@ -45,7 +45,7 @@ MM_PLUGIN_API int init(){ //create the timer to expire intervals timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if(timer_fd < 0){ - fprintf(stderr, "Failed to create timer for Lua backend\n"); + LOG("Failed to create timer"); return 1; } #endif @@ -130,7 +130,7 @@ static int lua_callback_output(lua_State* interpreter){ lua_instance_data* data = NULL; if(lua_gettop(interpreter) != 2){ - fprintf(stderr, "Lua output function called with %d arguments, expected 2 (string, number)\n", lua_gettop(interpreter)); + LOGPF("Output function called with %d arguments, expected 2 (string, number)", lua_gettop(interpreter)); return 0; } @@ -157,7 +157,7 @@ static int lua_callback_output(lua_State* interpreter){ } } - fprintf(stderr, "Tried to set unknown channel %s.%s\n", inst->name, channel_name); + LOGPF("Tried to set unknown channel %s.%s", inst->name, channel_name); return 0; } @@ -167,7 +167,7 @@ static int lua_callback_interval(lua_State* interpreter){ int reference = LUA_NOREF; if(lua_gettop(interpreter) != 2){ - fprintf(stderr, "Lua output function called with %d arguments, expected 2 (string, number)\n", lua_gettop(interpreter)); + LOGPF("Interval function called with %d arguments, expected 2 (function, number)", lua_gettop(interpreter)); return 0; } @@ -217,7 +217,7 @@ static int lua_callback_interval(lua_State* interpreter){ //append new timer timer = realloc(timer, (timers + 1) * sizeof(lua_timer)); if(!timer){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); timers = 0; return 0; } @@ -240,7 +240,7 @@ static int lua_callback_value(lua_State* interpreter, uint8_t input){ const char* channel_name = NULL; if(lua_gettop(interpreter) != 1){ - fprintf(stderr, "Lua get_value function called with %d arguments, expected 1 (string)\n", lua_gettop(interpreter)); + LOGPF("get_value function called with %d arguments, expected 1 (string)", lua_gettop(interpreter)); return 0; } @@ -261,7 +261,7 @@ static int lua_callback_value(lua_State* interpreter, uint8_t input){ } } - fprintf(stderr, "Tried to get unknown channel %s.%s\n", inst->name, channel_name); + LOGPF("Tried to get unknown channel %s.%s", inst->name, channel_name); return 0; } @@ -274,7 +274,7 @@ static int lua_callback_output_value(lua_State* interpreter){ } static int lua_configure(char* option, char* value){ - fprintf(stderr, "The lua backend does not take any global configuration\n"); + LOG("No backend configuration possible"); return 1; } @@ -284,13 +284,13 @@ static int lua_configure_instance(instance* inst, char* option, char* value){ //load a lua file into the interpreter if(!strcmp(option, "script") || !strcmp(option, "source")){ if(luaL_dofile(data->interpreter, value)){ - fprintf(stderr, "Failed to load lua source file %s for instance %s: %s\n", value, inst->name, lua_tostring(data->interpreter, -1)); + LOGPF("Failed to load source file %s for instance %s: %s", value, inst->name, lua_tostring(data->interpreter, -1)); return 1; } return 0; } - fprintf(stderr, "Unknown configuration parameter %s for lua instance %s\n", option, inst->name); + LOGPF("Unknown instance configuration parameter %s for instance %s", option, inst->name); return 1; } @@ -302,14 +302,14 @@ static instance* lua_instance(){ lua_instance_data* data = calloc(1, sizeof(lua_instance_data)); if(!data){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } //load the interpreter data->interpreter = luaL_newstate(); if(!data->interpreter){ - fprintf(stderr, "Failed to initialize LUA\n"); + LOG("Failed to initialize interpreter"); free(data); return NULL; } @@ -348,7 +348,7 @@ static channel* lua_channel(instance* inst, char* spec, uint8_t flags){ data->input = realloc(data->input, (u + 1) * sizeof(double)); data->output = realloc(data->output, (u + 1) * sizeof(double)); if(!data->channel_name || !data->reference || !data->input || !data->output){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -356,7 +356,7 @@ static channel* lua_channel(instance* inst, char* spec, uint8_t flags){ data->input[u] = data->output[u] = 0.0; data->channel_name[u] = strdup(spec); if(!data->channel_name[u]){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } data->channels++; @@ -377,7 +377,7 @@ static int lua_set(instance* inst, size_t num, channel** c, channel_value* v){ lua_rawgeti(data->interpreter, LUA_REGISTRYINDEX, data->reference[c[n]->ident]); lua_pushnumber(data->interpreter, v[n].normalised); if(lua_pcall(data->interpreter, 1, 0, 0) != LUA_OK){ - fprintf(stderr, "Failed to call handler for %s.%s: %s\n", inst->name, data->channel_name[c[n]->ident], lua_tostring(data->interpreter, -1)); + LOGPF("Failed to call handler for %s.%s: %s", inst->name, data->channel_name[c[n]->ident], lua_tostring(data->interpreter, -1)); lua_pop(data->interpreter, 1); } } @@ -397,7 +397,7 @@ static int lua_handle(size_t num, managed_fd* fds){ //read the timer iteration to acknowledge the fd if(read(timer_fd, read_buffer, sizeof(read_buffer)) < 0){ - fprintf(stderr, "Failed to read from Lua timer: %s\n", strerror(errno)); + LOGPF("Failed to read timer: %s", strerror(errno)); return 1; } #else @@ -452,7 +452,7 @@ static int lua_start(size_t n, instance** inst){ #ifdef MMBACKEND_LUA_TIMERFD //register the timer with the core - fprintf(stderr, "Lua backend registering 1 descriptor to core\n"); + LOG("Registering 1 descriptor to core"); if(mm_manage_fd(timer_fd, BACKEND_NAME, 1, NULL)){ return 1; } @@ -488,6 +488,6 @@ static int lua_shutdown(size_t n, instance** inst){ timer_fd = -1; #endif - fprintf(stderr, "Lua backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/maweb.c b/backends/maweb.c index 18d0351..39a6cb2 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "maweb" + #include #include #include @@ -8,7 +10,6 @@ #include "libmmbackend.h" #include "maweb.h" -#define BACKEND_NAME "maweb" #define WS_LEN(a) ((a) & 0x7F) #define WS_OP(a) ((a) & 0x0F) #define WS_FLAG_FIN 0x80 @@ -88,7 +89,7 @@ MM_PLUGIN_API int init(){ //register backend if(mm_backend_register(maweb)){ - fprintf(stderr, "Failed to register maweb backend\n"); + LOG("Failed to register backend"); return 1; } return 0; @@ -139,7 +140,7 @@ static int maweb_configure(char* option, char* value){ return 0; } - fprintf(stderr, "Unknown maweb backend configuration option %s\n", option); + LOGPF("Unknown backend configuration option %s", option); return 1; } @@ -150,7 +151,7 @@ static int maweb_configure_instance(instance* inst, char* option, char* value){ if(!strcmp(option, "host")){ mmbackend_parse_hostspec(value, &host, &port, &fd_opts); if(!host){ - fprintf(stderr, "Invalid host specified for maweb instance %s\n", inst->name); + LOGPF("Invalid host specified for instance %s", inst->name); return 1; } free(data->host); @@ -179,7 +180,7 @@ static int maweb_configure_instance(instance* inst, char* option, char* value){ } return 0; #else - fprintf(stderr, "This build of the maweb backend only supports the default password\n"); + LOG("This build only supports the default password"); return 1; #endif } @@ -194,13 +195,13 @@ static int maweb_configure_instance(instance* inst, char* option, char* value){ data->cmdline = cmd_downgrade; } else{ - fprintf(stderr, "Unknown maweb commandline mode %s for instance %s\n", value, inst->name); + LOGPF("Unknown commandline mode %s for instance %s", value, inst->name); return 1; } return 0; } - fprintf(stderr, "Unknown configuration parameter %s for maweb instance %s\n", option, inst->name); + LOGPF("Unknown instance configuration parameter %s for instance %s", option, inst->name); return 1; } @@ -212,14 +213,14 @@ static instance* maweb_instance(){ maweb_instance_data* data = calloc(1, sizeof(maweb_instance_data)); if(!data){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } data->fd = -1; data->buffer = calloc(MAWEB_RECV_CHUNK, sizeof(uint8_t)); if(!data->buffer){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); free(data); return NULL; } @@ -241,7 +242,7 @@ static channel* maweb_channel(instance* inst, char* spec, uint8_t flags){ if(!strncmp(spec, "page", 4)){ chan.page = strtoul(spec + 4, &next_token, 10); if(*next_token != '.'){ - fprintf(stderr, "Failed to parse maweb channel spec %s: Missing separator\n", spec); + LOGPF("Failed to parse channel spec %s: Missing separator", spec); return NULL; } @@ -273,7 +274,7 @@ static channel* maweb_channel(instance* inst, char* spec, uint8_t flags){ if(!strcmp(spec, cmdline_keys[n].name)){ if((data->cmdline == cmd_remote && !cmdline_keys[n].press && !cmdline_keys[n].release) || (data->cmdline == cmd_console && !cmdline_keys[n].lua)){ - fprintf(stderr, "maweb cmdline key %s does not work with the current commandline mode for instance %s\n", spec, inst->name); + LOGPF("Key %s does not work with the current commandline mode for instance %s", spec, inst->name); return NULL; } @@ -293,7 +294,7 @@ static channel* maweb_channel(instance* inst, char* spec, uint8_t flags){ if(maweb_channel_index(data, chan.type, chan.page, chan.index) == -1){ data->channel = realloc(data->channel, (data->channels + 1) * sizeof(maweb_channel_data)); if(!data->channel){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } data->channel[data->channels] = chan; @@ -305,7 +306,7 @@ static channel* maweb_channel(instance* inst, char* spec, uint8_t flags){ return channel_ref; } - fprintf(stderr, "Failed to parse maweb channel spec %s\n", spec); + LOGPF("Failed to parse channel spec %s", spec); return NULL; } @@ -353,7 +354,7 @@ static int maweb_process_playback(instance* inst, int64_t page, maweb_channel_ty //ignore unused buttons return 0; } - fprintf(stderr, "maweb missing exec block data on exec %" PRIu64 ".%" PRIu64 "\n", page, exec_index); + LOGPF("Missing exec block data on exec %" PRIu64 ".%" PRIu64, page, exec_index); return 1; } @@ -395,7 +396,7 @@ static int maweb_process_playback(instance* inst, int64_t page, maweb_channel_ty } } - DBGPF("maweb page %" PRIu64 " exec %" PRIu64 " value %f running %" PRIu64 "\n", page, exec_index, json_obj_double(payload + control, "v", 0.0), json_obj_int(payload, "isRun", 0)); + DBGPF("Page %" PRIu64 " exec %" PRIu64 " value %f running %" PRIu64, page, exec_index, json_obj_double(payload + control, "v", 0.0), json_obj_int(payload, "isRun", 0)); exec_index++; block++; } @@ -408,12 +409,12 @@ static int maweb_process_playbacks(instance* inst, int64_t page, char* payload, uint64_t group = 0, subgroup, item, metatype; if(!page){ - fprintf(stderr, "maweb received playbacks for invalid page\n"); + LOG("Received playbacks for invalid page"); return 0; } if(!base_offset){ - fprintf(stderr, "maweb playback data missing item key\n"); + LOG("Playback data missing item key"); return 0; } @@ -448,7 +449,7 @@ static int maweb_process_playbacks(instance* inst, int64_t page, char* payload, group++; } updates_inflight--; - DBGPF("maweb playback message processing done, %" PRIu64 " updates inflight\n", updates_inflight); + DBGPF("Playback message processing done, %" PRIu64 " updates inflight", updates_inflight); return 0; } @@ -461,7 +462,7 @@ static int maweb_request_playbacks(instance* inst){ size_t page_index = 0, view = 3, channel = 0, offsets[3], channel_offset, channels; if(updates_inflight){ - fprintf(stderr, "maweb skipping update request, %" PRIu64 " updates still inflight\n", updates_inflight); + LOGPF("Skipping update request, %" PRIu64 " updates still inflight", updates_inflight); return 0; } @@ -522,7 +523,7 @@ static int maweb_request_playbacks(instance* inst){ snprintf(item_counts, sizeof(item_indices), "[%" PRIsize_t "]", ((channels / 5) * 5 + 5)); } - DBGPF("maweb poll range first %d: %d.%d last %d: %d.%d next %d: %d.%d\n", + DBGPF("Poll range first %d: %d.%d last %d: %d.%d next %d: %d.%d", data->channel[channel].type, data->channel[channel].page, data->channel[channel].index, data->channel[channel + channel_offset - 1].type, data->channel[channel + channel_offset - 1].page, data->channel[channel + channel_offset - 1].index, data->channel[channel + channel_offset].type, data->channel[channel + channel_offset].page, data->channel[channel + channel_offset].index); @@ -550,11 +551,11 @@ static int maweb_request_playbacks(instance* inst){ view, data->session); rv |= maweb_send_frame(inst, ws_text, (uint8_t*) xmit_buffer, strlen(xmit_buffer)); - DBGPF("maweb poll request: %s\n", xmit_buffer); + DBGPF("Poll request: %s", xmit_buffer); updates_inflight++; } - DBGPF("maweb poll request handling done, %" PRIu64 " updates requested\n", updates_inflight); + DBGPF("Poll request handling done, %" PRIu64 " updates requested", updates_inflight); return rv; } @@ -568,42 +569,42 @@ static int maweb_handle_message(instance* inst, char* payload, size_t payload_le field = json_obj_str(payload, "responseType", NULL); if(!strncmp(field, "login", 5)){ if(json_obj_bool(payload, "result", 0)){ - fprintf(stderr, "maweb login successful\n"); + LOG("Login successful"); data->login = 1; } else{ - fprintf(stderr, "maweb login failed\n"); + LOG("Login failed"); data->login = 0; } } if(!strncmp(field, "playbacks", 9)){ if(maweb_process_playbacks(inst, json_obj_int(payload, "iPage", 0), payload, payload_length)){ - fprintf(stderr, "maweb failed to handle/request input data\n"); + LOG("Failed to handle/request input data"); } return 0; } } - DBGPF("maweb message (%" PRIsize_t "): %s\n", payload_length, payload); + DBGPF("Incoming message (%" PRIsize_t "): %s", payload_length, payload); if(json_obj(payload, "session") == JSON_NUMBER){ data->session = json_obj_int(payload, "session", data->session); if(data->session < 0){ - fprintf(stderr, "maweb login failed\n"); + LOG("Login failed"); data->login = 0; return 0; } - fprintf(stderr, "maweb session id is now %" PRId64 "\n", data->session); + LOGPF("Session id is now %" PRId64, data->session); } if(json_obj_bool(payload, "forceLogin", 0)){ - fprintf(stderr, "maweb sending user credentials\n"); + LOG("Sending user credentials"); snprintf(xmit_buffer, sizeof(xmit_buffer), "{\"requestType\":\"login\",\"username\":\"%s\",\"password\":\"%s\",\"session\":%" PRIu64 "}", (data->peer_type == peer_dot2) ? "remote" : data->user, data->pass ? data->pass : MAWEB_DEFAULT_PASSWORD, data->session); maweb_send_frame(inst, ws_text, (uint8_t*) xmit_buffer, strlen(xmit_buffer)); } if(json_obj(payload, "status") && json_obj(payload, "appType")){ - fprintf(stderr, "maweb connection established\n"); + LOG("Connection established"); field = json_obj_str(payload, "appType", NULL); if(!strncmp(field, "dot2", 4)){ data->peer_type = peer_dot2; @@ -644,13 +645,13 @@ static int maweb_connect(instance* inst){ //and the whole websocket 'accept key' dance is plenty stupid as it is || mmbackend_send_str(data->fd, "Sec-WebSocket-Key: rbEQrXMEvCm4ZUjkj6juBQ==\r\n") || mmbackend_send_str(data->fd, "\r\n")){ - fprintf(stderr, "maweb backend failed to communicate with peer\n"); + LOG("Failed to communicate with peer"); return 1; } //register new fd if(mm_manage_fd(data->fd, BACKEND_NAME, 1, (void*) inst)){ - fprintf(stderr, "maweb backend failed to register fd\n"); + LOG("Failed to register FD"); return 1; } return 0; @@ -667,7 +668,7 @@ static ssize_t maweb_handle_lines(instance* inst, ssize_t bytes_read){ data->state = ws_http; } else{ - fprintf(stderr, "maweb received invalid HTTP response for instance %s\n", inst->name); + LOGPF("Invalid HTTP response for instance %s", inst->name); return -1; } } @@ -737,11 +738,11 @@ static ssize_t maweb_handle_ws(instance* inst, ssize_t bytes_read){ case ws_ping: //answer server ping with a pong if(maweb_send_frame(inst, ws_pong, payload, payload_length)){ - fprintf(stderr, "maweb failed to send pong\n"); + LOG("Failed to send pong"); } return header_length + payload_length; default: - fprintf(stderr, "maweb encountered unhandled frame type %02X\n", WS_OP(data->buffer[0])); + LOGPF("Unhandled frame type %02X", WS_OP(data->buffer[0])); //this is somewhat dicey, it might be better to handle only header + payload length for known but unhandled types return data->offset + bytes_read; } @@ -756,7 +757,7 @@ static int maweb_handle_fd(instance* inst){ if(bytes_left < 3){ data->buffer = realloc(data->buffer, (data->allocated + MAWEB_RECV_CHUNK) * sizeof(uint8_t)); if(!data->buffer){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } data->allocated += MAWEB_RECV_CHUNK; @@ -765,7 +766,7 @@ static int maweb_handle_fd(instance* inst){ bytes_read = recv(data->fd, data->buffer + data->offset, bytes_left - 1, 0); if(bytes_read < 0){ - fprintf(stderr, "maweb backend failed to receive: %s\n", strerror(errno)); + LOGPF("Failed to receive: %s", strerror(errno)); //TODO close, reopen return 1; } @@ -793,7 +794,7 @@ static int maweb_handle_fd(instance* inst){ bytes_handled = data->offset + bytes_read; data->offset = 0; //TODO close, reopen - fprintf(stderr, "maweb failed to handle incoming data\n"); + LOG("Failed to handle incoming data"); return 1; } else if(bytes_handled == 0){ @@ -818,7 +819,7 @@ static int maweb_set(instance* inst, size_t num, channel** c, channel_value* v){ size_t n; if(num && !data->login){ - fprintf(stderr, "maweb instance %s can not send output, not logged in\n", inst->name); + LOGPF("Instance %s can not send output, not logged in", inst->name); return 0; } @@ -904,16 +905,16 @@ static int maweb_set(instance* inst, size_t num, channel** c, channel_value* v){ } } else{ - fprintf(stderr, "maweb commandline key %s not executed on %s due to mode mismatch\n", + LOGPF("Key %s not executed on %s due to mode mismatch", cmdline_keys[chan->index].name, inst->name); continue; } break; default: - fprintf(stderr, "maweb control not yet implemented\n"); + LOG("Control not yet implemented"); return 1; } - DBGPF("maweb command out %s\n", xmit_buffer); + DBGPF("Command out %s", xmit_buffer); maweb_send_frame(inst, ws_text, (uint8_t*) xmit_buffer, strlen(xmit_buffer)); } return 0; @@ -927,7 +928,7 @@ static int maweb_keepalive(){ //fetch all defined instances if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); + LOG("Failed to fetch instance list"); return 1; } @@ -951,7 +952,7 @@ static int maweb_poll(){ //fetch all defined instances if(mm_backend_instances(BACKEND_NAME, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list\n"); + LOG( "Failed to fetch instance list"); return 1; } @@ -1004,13 +1005,13 @@ static int maweb_start(size_t n, instance** inst){ } if(maweb_connect(inst[u])){ - fprintf(stderr, "Failed to open connection to MA Web Remote for instance %s\n", inst[u]->name); + LOGPF("Failed to open connection for instance %s", inst[u]->name); free(inst); return 1; } } - fprintf(stderr, "maweb backend registering %" PRIsize_t " descriptors to core\n", n); + LOGPF("Registering %" PRIsize_t " descriptors to core", n); //initialize timeouts last_keepalive = last_update = mm_timestamp(); @@ -1048,6 +1049,6 @@ static int maweb_shutdown(size_t n, instance** inst){ free(inst[u]->impl); } - fprintf(stderr, "maweb backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/midi.c b/backends/midi.c index 2088774..11d759d 100644 --- a/backends/midi.c +++ b/backends/midi.c @@ -1,8 +1,9 @@ +#define BACKEND_NAME "midi" + #include #include #include "midi.h" -#define BACKEND_NAME "midi" static char* sequencer_name = NULL; static snd_seq_t* sequencer = NULL; @@ -37,13 +38,13 @@ MM_PLUGIN_API int init(){ }; if(sizeof(midi_channel_ident) != sizeof(uint64_t)){ - fprintf(stderr, "MIDI channel identification union out of bounds\n"); + LOG("Channel identification union out of bounds"); return 1; } //register backend if(mm_backend_register(midi)){ - fprintf(stderr, "Failed to register MIDI backend\n"); + LOG("Failed to register backend"); return 1; } @@ -64,7 +65,7 @@ static int midi_configure(char* option, char* value){ return 0; } - fprintf(stderr, "Unknown MIDI backend option %s\n", option); + LOGPF("Unknown backend option %s", option); return 1; } @@ -76,7 +77,7 @@ static instance* midi_instance(){ inst->impl = calloc(1, sizeof(midi_instance_data)); if(!inst->impl){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -90,7 +91,7 @@ static int midi_configure_instance(instance* inst, char* option, char* value){ if(!strcmp(option, "read")){ //connect input device if(data->read){ - fprintf(stderr, "MIDI instance %s was already connected to an input device\n", inst->name); + LOGPF("Instance %s was already connected to an input device", inst->name); return 1; } data->read = strdup(value); @@ -99,14 +100,14 @@ static int midi_configure_instance(instance* inst, char* option, char* value){ else if(!strcmp(option, "write")){ //connect output device if(data->write){ - fprintf(stderr, "MIDI instance %s was already connected to an output device\n", inst->name); + LOGPF("Instance %s was already connected to an output device", inst->name); return 1; } data->write = strdup(value); return 0; } - fprintf(stderr, "Unknown MIDI instance option %s\n", option); + LOGPF("Unknown instance option %s", option); return 1; } @@ -141,18 +142,18 @@ static channel* midi_channel(instance* inst, char* spec, uint8_t flags){ old_syntax = 1; } else{ - fprintf(stderr, "Unknown MIDI channel control type in %s\n", spec); + LOGPF("Unknown control type in %s", spec); return NULL; } ident.fields.channel = strtoul(channel, &channel, 10); if(ident.fields.channel > 15){ - fprintf(stderr, "MIDI channel out of range in midi channel spec %s\n", spec); + LOGPF("Channel out of range in spec %s", spec); return NULL; } if(*channel != '.'){ - fprintf(stderr, "Need MIDI channel specification of form channel., had %s\n", spec); + LOGPF("Need specification of form channel., had %s", spec); return NULL; } //skip the period @@ -182,7 +183,7 @@ static channel* midi_channel(instance* inst, char* spec, uint8_t flags){ ident.fields.type = aftertouch; } else{ - fprintf(stderr, "Unknown MIDI channel control type in %s\n", spec); + LOGPF("Unknown control type in %s", spec); return NULL; } } @@ -306,14 +307,14 @@ static int midi_handle(size_t num, managed_fd* fds){ ident.fields.control = ev->data.control.param; break; default: - fprintf(stderr, "Ignored MIDI event of unsupported type\n"); + LOG("Ignored event of unsupported type"); continue; } inst = mm_instance_find(BACKEND_NAME, ev->dest.port); if(!inst){ //FIXME might want to return failure - fprintf(stderr, "Delivered MIDI event did not match any instance\n"); + LOG("Delivered event did not match any instance"); continue; } @@ -327,10 +328,10 @@ static int midi_handle(size_t num, managed_fd* fds){ if(midi_config.detect && event_type){ if(ident.fields.type == pitchbend || ident.fields.type == aftertouch){ - fprintf(stderr, "Incoming MIDI data on channel %s.ch%d.%s\n", inst->name, ident.fields.channel, event_type); + LOGPF("Incoming data on channel %s.ch%d.%s", inst->name, ident.fields.channel, event_type); } else{ - fprintf(stderr, "Incoming MIDI data on channel %s.ch%d.%s%d\n", inst->name, ident.fields.channel, event_type, ident.fields.control); + LOGPF("Incoming data on channel %s.ch%d.%s%d", inst->name, ident.fields.channel, event_type, ident.fields.control); } } } @@ -347,16 +348,16 @@ static int midi_start(size_t n, instance** inst){ //connect to the sequencer if(snd_seq_open(&sequencer, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0){ - fprintf(stderr, "Failed to open ALSA sequencer\n"); + LOG("Failed to open ALSA sequencer"); goto bail; } snd_seq_nonblock(sequencer, 1); - fprintf(stderr, "MIDI client ID is %d\n", snd_seq_client_id(sequencer)); + LOGPF("Client ID is %d", snd_seq_client_id(sequencer)); //update the sequencer client name if(snd_seq_set_client_name(sequencer, sequencer_name ? sequencer_name : "MIDIMonster") < 0){ - fprintf(stderr, "Failed to set MIDI client name to %s\n", sequencer_name); + LOGPF("Failed to set client name to %s", sequencer_name); goto bail; } @@ -369,11 +370,11 @@ static int midi_start(size_t n, instance** inst){ //make connections if(data->write){ if(snd_seq_parse_address(sequencer, &addr, data->write) == 0){ - fprintf(stderr, "Connecting output of instance %s to MIDI device %s (%d:%d)\n", inst[p]->name, data->write, addr.client, addr.port); + LOGPF("Connecting output of instance %s to device %s (%d:%d)", inst[p]->name, data->write, addr.client, addr.port); snd_seq_connect_to(sequencer, data->port, addr.client, addr.port); } else{ - fprintf(stderr, "Failed to get destination MIDI device address: %s\n", data->write); + LOGPF("Failed to get destination device address: %s", data->write); } free(data->write); data->write = NULL; @@ -381,11 +382,11 @@ static int midi_start(size_t n, instance** inst){ if(data->read){ if(snd_seq_parse_address(sequencer, &addr, data->read) == 0){ - fprintf(stderr, "Connecting input from MIDI device %s to instance %s (%d:%d)\n", data->read, inst[p]->name, addr.client, addr.port); + LOGPF("Connecting input from device %s to instance %s (%d:%d)", data->read, inst[p]->name, addr.client, addr.port); snd_seq_connect_from(sequencer, data->port, addr.client, addr.port); } else{ - fprintf(stderr, "Failed to get source MIDI device address: %s\n", data->read); + LOGPF("Failed to get source device address: %s", data->read); } free(data->read); data->read = NULL; @@ -396,12 +397,12 @@ static int midi_start(size_t n, instance** inst){ nfds = snd_seq_poll_descriptors_count(sequencer, POLLIN | POLLOUT); pfds = calloc(nfds, sizeof(struct pollfd)); if(!pfds){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); goto bail; } nfds = snd_seq_poll_descriptors(sequencer, pfds, nfds, POLLIN | POLLOUT); - fprintf(stderr, "MIDI backend registering %d descriptors to core\n", nfds); + LOGPF("Registering %d descriptors to core", nfds); for(p = 0; p < nfds; p++){ if(mm_manage_fd(pfds[p].fd, BACKEND_NAME, 1, NULL)){ goto bail; @@ -440,6 +441,6 @@ static int midi_shutdown(size_t n, instance** inst){ free(sequencer_name); sequencer_name = NULL; - fprintf(stderr, "MIDI backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/ola.cpp b/backends/ola.cpp index fd121a0..09d68c9 100644 --- a/backends/ola.cpp +++ b/backends/ola.cpp @@ -1,3 +1,5 @@ +#define BACKEND_NAME "ola" + #include "ola.h" #include #include @@ -7,7 +9,6 @@ #include #include -#define BACKEND_NAME "ola" static ola::io::SelectServer* ola_select = NULL; static ola::OlaCallbackClient* ola_client = NULL; @@ -26,7 +27,7 @@ MM_PLUGIN_API int init(){ //register backend if(mm_backend_register(ola)){ - fprintf(stderr, "Failed to register OLA backend\n"); + LOG("Failed to register backend"); return 1; } @@ -35,7 +36,7 @@ MM_PLUGIN_API int init(){ } static int ola_configure(char* option, char* value){ - fprintf(stderr, "Unknown OLA backend option %s\n", option); + LOGPF("Unknown backend option %s", option); return 1; } @@ -48,7 +49,7 @@ static instance* ola_instance(){ data = (ola_instance_data*)calloc(1, sizeof(ola_instance_data)); if(!data){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -64,7 +65,7 @@ static int ola_configure_instance(instance* inst, char* option, char* value){ return 0; } - fprintf(stderr, "Unknown OLA option %s for instance %s\n", option, inst->name); + LOGPF("Unknown instance configuration option %s for instance %s", option, inst->name); return 1; } @@ -76,7 +77,7 @@ static channel* ola_channel(instance* inst, char* spec, uint8_t flags){ //primary channel sanity check if(!chan_a || chan_a > 512){ - fprintf(stderr, "Invalid OLA channel specification %s\n", spec); + LOGPF("Invalid channel specification %s", spec); return NULL; } chan_a--; @@ -85,14 +86,14 @@ static channel* ola_channel(instance* inst, char* spec, uint8_t flags){ if(*spec_next == '+'){ chan_b = strtoul(spec_next + 1, NULL, 10); if(!chan_b || chan_b > 512){ - fprintf(stderr, "Invalid wide-channel spec %s\n", spec); + LOGPF("Invalid wide-channel spec %s", spec); return NULL; } chan_b--; //if mapped mode differs, bail if(IS_ACTIVE(data->data.map[chan_b]) && data->data.map[chan_b] != (MAP_FINE | chan_a)){ - fprintf(stderr, "Fine channel already mapped for OLA spec %s\n", spec); + LOGPF("Fine channel already mapped for spec %s", spec); return NULL; } @@ -103,7 +104,7 @@ static channel* ola_channel(instance* inst, char* spec, uint8_t flags){ if(IS_ACTIVE(data->data.map[chan_a])){ if((*spec_next == '+' && data->data.map[chan_a] != (MAP_COARSE | chan_b)) || (*spec_next != '+' && data->data.map[chan_a] != (MAP_SINGLE | chan_a))){ - fprintf(stderr, "Primary OLA channel already mapped at differing mode: %s\n", spec); + LOGPF("Primary channel already mapped at differing mode: %s", spec); return NULL; } } @@ -189,7 +190,7 @@ static void ola_data_receive(unsigned int universe, const ola::DmxBuffer& ola_dm } if(!chan){ - fprintf(stderr, "Active channel %zu on %s not known to core\n", p, inst->name); + LOGPF("Active channel %" PRIsize_t " on %s not known to core", p, inst->name); return; } @@ -207,7 +208,7 @@ static void ola_data_receive(unsigned int universe, const ola::DmxBuffer& ola_dm } if(mm_channel_event(chan, val)){ - fprintf(stderr, "Failed to push OLA channel event to core\n"); + LOG("Failed to push event to core"); return; } } @@ -216,7 +217,7 @@ static void ola_data_receive(unsigned int universe, const ola::DmxBuffer& ola_dm static void ola_register_callback(const std::string &error) { if(!error.empty()){ - fprintf(stderr, "OLA backend failed to register for universe: %s\n", error.c_str()); + LOGPF("Failed to register for universe: %s", error.c_str()); } } @@ -228,20 +229,20 @@ static int ola_start(size_t n, instance** inst){ ola::network::IPV4SocketAddress ola_server(ola::network::IPV4Address::Loopback(), ola::OLA_DEFAULT_PORT); ola::network::TCPSocket* ola_socket = ola::network::TCPSocket::Connect(ola_server); if(!ola_socket){ - fprintf(stderr, "Failed to connect to OLA server\n"); + LOG("Failed to connect to server"); return 1; } ola_client = new ola::OlaCallbackClient(ola_socket); if(!ola_client->Setup()){ - fprintf(stderr, "Failed to start OLA client\n"); + LOG("Failed to start client"); goto bail; } ola_select->AddReadDescriptor(ola_socket); - fprintf(stderr, "OLA backend registering connection descriptor to core\n"); + LOG("Registering connection descriptor to core"); if(mm_manage_fd(ola_socket->ReadDescriptor(), BACKEND_NAME, 1, NULL)){ goto bail; } @@ -255,7 +256,7 @@ static int ola_start(size_t n, instance** inst){ //check for duplicate instances (using the same universe) for(p = 0; p < u; p++){ if(inst[u]->ident == inst[p]->ident){ - fprintf(stderr, "OLA universe used in multiple instances, use one instance: %s - %s\n", inst[u]->name, inst[p]->name); + LOGPF("Universe used in multiple instances, use one instance: %s - %s", inst[u]->name, inst[p]->name); goto bail; } } @@ -292,6 +293,6 @@ static int ola_shutdown(size_t n, instance** inst){ ola_select = NULL; } - fprintf(stderr, "OLA backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/osc.c b/backends/osc.c index 15b5c24..7b9a5a5 100644 --- a/backends/osc.c +++ b/backends/osc.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "osc" + #include #include #include @@ -11,7 +13,6 @@ */ #define osc_align(a) ((((a) / 4) + (((a) % 4) ? 1 : 0)) * 4) -#define BACKEND_NAME "osc" static struct { uint8_t detect; @@ -33,13 +34,13 @@ MM_PLUGIN_API int init(){ }; if(sizeof(osc_channel_ident) != sizeof(uint64_t)){ - fprintf(stderr, "OSC channel identification union out of bounds\n"); + LOG("Channel identification union out of bounds"); return 1; } //register backend if(mm_backend_register(osc)){ - fprintf(stderr, "Failed to register OSC backend\n"); + LOG("Failed to register backend"); return 1; } return 0; @@ -55,7 +56,7 @@ static size_t osc_data_length(osc_parameter_type t){ case double64: return 8; default: - fprintf(stderr, "Invalid OSC format specified %c\n", t); + LOGPF("Invalid OSC format specifier %c", t); return 0; } } @@ -78,7 +79,7 @@ static inline void osc_defaults(osc_parameter_type t, osc_parameter_value* max, max->d = 1.0; return; default: - fprintf(stderr, "Invalid OSC type, not setting any sane defaults\n"); + LOG("Invalid OSC type, not setting any sane defaults"); return; } } @@ -96,7 +97,7 @@ static inline osc_parameter_value osc_parse(osc_parameter_type t, uint8_t* data) v.i64 = be64toh(*((int64_t*) data)); break; default: - fprintf(stderr, "Invalid OSC type passed to parsing routine\n"); + LOG("Invalid OSC type passed to parsing routine"); } return v; } @@ -117,7 +118,7 @@ static inline int osc_deparse(osc_parameter_type t, osc_parameter_value v, uint8 memcpy(data, &u64, sizeof(u64)); break; default: - fprintf(stderr, "Invalid OSC type passed to parsing routine\n"); + LOG("Invalid OSC type passed to parsing routine"); return 1; } return 0; @@ -140,7 +141,7 @@ static inline osc_parameter_value osc_parse_value_spec(osc_parameter_type t, cha v.d = strtod(value, NULL); break; default: - fprintf(stderr, "Invalid OSC type passed to value parser\n"); + LOG("Invalid OSC type passed to value parser"); } return v; } @@ -181,7 +182,7 @@ static inline channel_value osc_parameter_normalise(osc_parameter_type t, osc_pa v.normalised = v.raw.dbl / range.d64; break; default: - fprintf(stderr, "Invalid OSC type passed to interpolation routine\n"); + LOG("Invalid OSC type passed to interpolation routine (normalise)"); } //clamp to range @@ -218,7 +219,7 @@ static inline osc_parameter_value osc_parameter_denormalise(osc_parameter_type t v.d = (range.d64 * cur.normalised) + min.d; break; default: - fprintf(stderr, "Invalid OSC type passed to interpolation routine\n"); + LOG("Invalid OSC type passed to interpolation routine (denormalise)"); } return v; @@ -232,27 +233,27 @@ static int osc_path_validate(char* path, uint8_t allow_patterns){ uint8_t square_open = 0, curly_open = 0; if(path[0] != '/'){ - fprintf(stderr, "%s is not a valid OSC path: Missing root /\n", path); + LOGPF("%s is not a valid OSC path: Missing root /", path); return 1; } for(u = 0; u < strlen(path); u++){ for(c = 0; c < sizeof(illegal_chars); c++){ if(path[u] == illegal_chars[c]){ - fprintf(stderr, "%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t "\n", path, illegal_chars[c], u); + LOGPF("%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t, path, illegal_chars[c], u); return 1; } } if(!isgraph(path[u])){ - fprintf(stderr, "%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t "\n", path, pattern_chars[c], u); + LOGPF("%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t, path, pattern_chars[c], u); return 1; } if(!allow_patterns){ for(c = 0; c < sizeof(pattern_chars); c++){ if(path[u] == pattern_chars[c]){ - fprintf(stderr, "%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t "\n", path, pattern_chars[c], u); + LOGPF("%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t, path, pattern_chars[c], u); return 1; } } @@ -261,14 +262,14 @@ static int osc_path_validate(char* path, uint8_t allow_patterns){ switch(path[u]){ case '{': if(square_open || curly_open){ - fprintf(stderr, "%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t "\n", path, pattern_chars[c], u); + LOGPF("%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t, path, pattern_chars[c], u); return 1; } curly_open = 1; break; case '[': if(square_open || curly_open){ - fprintf(stderr, "%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t "\n", path, pattern_chars[c], u); + LOGPF("%s is not a valid OSC path: Illegal '%c' at %" PRIsize_t, path, pattern_chars[c], u); return 1; } square_open = 1; @@ -281,14 +282,14 @@ static int osc_path_validate(char* path, uint8_t allow_patterns){ break; case '/': if(square_open || curly_open){ - fprintf(stderr, "%s is not a valid OSC path: Pattern across part boundaries\n", path); + LOGPF("%s is not a valid OSC path: Pattern across part boundaries", path); return 1; } } } if(square_open || curly_open){ - fprintf(stderr, "%s is not a valid OSC path: Unterminated pattern expression\n", path); + LOGPF("%s is not a valid OSC path: Unterminated pattern expression", path); return 1; } return 0; @@ -421,7 +422,7 @@ static int osc_configure(char* option, char* value){ return 0; } - fprintf(stderr, "Unknown configuration parameter %s for OSC backend\n", option); + LOGPF("Unknown backend configuration parameter %s", option); return 1; } @@ -430,21 +431,21 @@ static int osc_register_pattern(osc_instance_data* data, char* pattern_path, cha char* format = NULL, *token = NULL; if(osc_path_validate(pattern_path, 1)){ - fprintf(stderr, "Not a valid OSC pattern: %s\n", pattern_path); + LOGPF("Not a valid OSC pattern: %s", pattern_path); return 1; } //tokenize configuration format = strtok(configuration, " "); if(!format || strlen(format) < 1){ - fprintf(stderr, "Not a valid format specification for OSC pattern %s\n", pattern_path); + LOGPF("Not a valid format specification for OSC pattern %s", pattern_path); return 1; } //create pattern data->pattern = realloc(data->pattern, (data->patterns + 1) * sizeof(osc_channel)); if(!data->pattern){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } pattern = data->patterns; @@ -461,14 +462,14 @@ static int osc_register_pattern(osc_instance_data* data, char* pattern_path, cha || !data->pattern[pattern].min){ //this should fail config parsing and thus call the shutdown function, //which should properly free the rest of the data - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } //check format validity and store min/max values for(u = 0; u < strlen(format); u++){ if(!osc_data_length(format[u])){ - fprintf(stderr, "Invalid format specifier %c for pattern %s\n", format[u], pattern_path); + LOGPF("Invalid format specifier %c for pattern %s", format[u], pattern_path); return 1; } @@ -477,14 +478,14 @@ static int osc_register_pattern(osc_instance_data* data, char* pattern_path, cha //parse min/max values token = strtok(NULL, " "); if(!token){ - fprintf(stderr, "Missing minimum specification for parameter %" PRIsize_t " of OSC pattern %s\n", u, pattern_path); + LOGPF("Missing minimum specification for parameter %" PRIsize_t " of OSC pattern %s", u, pattern_path); return 1; } data->pattern[pattern].min[u] = osc_parse_value_spec(format[u], token); token = strtok(NULL, " "); if(!token){ - fprintf(stderr, "Missing maximum specification for parameter %" PRIsize_t " of OSC pattern %s\n", u, pattern_path); + LOGPF("Missing maximum specification for parameter %" PRIsize_t " of OSC pattern %s", u, pattern_path); return 1; } data->pattern[pattern].max[u] = osc_parse_value_spec(format[u], token); @@ -500,7 +501,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ if(!strcmp(option, "root")){ if(osc_path_validate(value, 0)){ - fprintf(stderr, "Not a valid OSC root: %s\n", value); + LOGPF("Not a valid OSC root: %s", value); return 1; } @@ -510,7 +511,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ data->root = strdup(value); if(!data->root){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return 1; } return 0; @@ -518,14 +519,14 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ else if(!strcmp(option, "bind")){ mmbackend_parse_hostspec(value, &host, &port, &fd_opts); if(!host || !port){ - fprintf(stderr, "Invalid bind address for instance %s\n", inst->name); + LOGPF("Invalid bind address for instance %s", inst->name); return 1; } //this requests a socket with SO_BROADCAST set, whether this is useful functionality for OSC is up for debate data->fd = mmbackend_socket(host, port, SOCK_DGRAM, 1, 1); if(data->fd < 0){ - fprintf(stderr, "Failed to bind for instance %s\n", inst->name); + LOGPF("Failed to bind for instance %s", inst->name); return 1; } return 0; @@ -543,12 +544,12 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ mmbackend_parse_hostspec(value, &host, &port, NULL); if(!host || !port){ - fprintf(stderr, "Invalid destination address for instance %s\n", inst->name); + LOGPF("Invalid destination address for instance %s", inst->name); return 1; } if(mmbackend_parse_sockaddr(host, port, &data->dest, &data->dest_len)){ - fprintf(stderr, "Failed to parse destination address for instance %s\n", inst->name); + LOGPF("Failed to parse destination address for instance %s", inst->name); return 1; } return 0; @@ -557,7 +558,7 @@ static int osc_configure_instance(instance* inst, char* option, char* value){ return osc_register_pattern(data, option, value); } - fprintf(stderr, "Unknown configuration parameter %s for OSC instance %s\n", option, inst->name); + LOGPF("Unknown instance configuration parameter %s for instance %s", option, inst->name); return 1; } @@ -569,7 +570,7 @@ static instance* osc_instance(){ osc_instance_data* data = calloc(1, sizeof(osc_instance_data)); if(!data){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -613,14 +614,14 @@ static channel* osc_map_channel(instance* inst, char* spec, uint8_t flags){ data->channel = realloc(data->channel, (u + 1) * sizeof(osc_channel)); if(!data->channel){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } memset(data->channel + u, 0, sizeof(osc_channel)); data->channel[u].path = strdup(spec); if(p != data->patterns){ - fprintf(stderr, "Matched pattern %s for %s\n", data->pattern[p].path, spec); + LOGPF("Matched pattern %s for %s", data->pattern[p].path, spec); data->channel[u].params = data->pattern[p].params; //just reuse the pointers from the pattern data->channel[u].type = data->pattern[p].type; @@ -632,12 +633,12 @@ static channel* osc_map_channel(instance* inst, char* spec, uint8_t flags){ data->channel[u].out = calloc(data->channel[u].params, sizeof(osc_parameter_value)); } else if(data->patterns){ - fprintf(stderr, "No pattern match found for %s\n", spec); + LOGPF("No pattern match found for %s", spec); } if(!data->channel[u].path || (data->channel[u].params && (!data->channel[u].in || !data->channel[u].out))){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } data->channels++; @@ -661,7 +662,7 @@ static int osc_output_channel(instance* inst, size_t channel){ //determine minimum packet size if(osc_align((data->root ? strlen(data->root) : 0) + strlen(data->channel[channel].path) + 1) + osc_align(data->channel[channel].params + 2) >= sizeof(xmit_buf)){ - fprintf(stderr, "Insufficient buffer size for OSC transmitting channel %s.%s\n", inst->name, data->channel[channel].path); + LOGPF("Insufficient buffer size for transmitting channel %s.%s", inst->name, data->channel[channel].path); return 1; } @@ -687,7 +688,7 @@ static int osc_output_channel(instance* inst, size_t channel){ //write data if(offset + osc_data_length(data->channel[channel].type[p]) >= sizeof(xmit_buf)){ - fprintf(stderr, "Insufficient buffer size for OSC transmitting channel %s.%s at parameter %" PRIsize_t "\n", inst->name, data->channel[channel].path, p); + LOGPF("Insufficient buffer size for transmitting channel %s.%s at parameter %" PRIsize_t, inst->name, data->channel[channel].path, p); return 1; } @@ -699,7 +700,7 @@ static int osc_output_channel(instance* inst, size_t channel){ //output packet if(sendto(data->fd, xmit_buf, offset, 0, (struct sockaddr*) &(data->dest), data->dest_len) < 0){ - fprintf(stderr, "Failed to transmit OSC packet: %s\n", strerror(errno)); + LOGPF("Failed to transmit packet: %s", strerror(errno)); } return 0; } @@ -718,7 +719,7 @@ static int osc_set(instance* inst, size_t num, channel** c, channel_value* v){ osc_instance_data* data = (osc_instance_data*) inst->impl; if(!data->dest_len){ - fprintf(stderr, "OSC instance %s does not have a destination, output is disabled (%" PRIsize_t " channels)\n", inst->name, num); + LOGPF("Instance %s does not have a destination, output is disabled (%" PRIsize_t " channels)", inst->name, num); return 0; } @@ -728,13 +729,13 @@ static int osc_set(instance* inst, size_t num, channel** c, channel_value* v){ //sanity check if(ident.fields.channel >= data->channels || ident.fields.parameter >= data->channel[ident.fields.channel].params){ - fprintf(stderr, "OSC channel identifier out of range\n"); + LOG("Channel identifier out of range"); return 1; } //if the format is unknown, don't output if(!data->channel[ident.fields.channel].params){ - fprintf(stderr, "OSC channel %s.%s requires format specification for output\n", inst->name, data->channel[ident.fields.channel].path); + LOGPF("Channel %s.%s requires format specification for output", inst->name, data->channel[ident.fields.channel].path); continue; } @@ -776,7 +777,7 @@ static int osc_process_packet(instance* inst, char* local_path, char* format, ui channel* chan = NULL; if(payload_len % 4){ - fprintf(stderr, "Invalid OSC packet, data length %" PRIsize_t "\n", payload_len); + LOGPF("Invalid packet, data length %" PRIsize_t, payload_len); return 0; } @@ -785,7 +786,7 @@ static int osc_process_packet(instance* inst, char* local_path, char* format, ui ident.fields.channel = c; //unconfigured input should work without errors (using default limits) if(data->channel[c].params && strlen(format) != data->channel[c].params){ - fprintf(stderr, "OSC message %s.%s had format %s, internal representation has %" PRIsize_t " parameters\n", inst->name, local_path, format, data->channel[c].params); + LOGPF("Message %s.%s had format %s, internal representation has %" PRIsize_t " parameters", inst->name, local_path, format, data->channel[c].params); continue; } @@ -830,7 +831,7 @@ static int osc_handle(size_t num, managed_fd* fds){ for(fd = 0; fd < num; fd++){ inst = (instance*) fds[fd].impl; if(!inst){ - fprintf(stderr, "OSC backend signaled for unknown fd\n"); + LOG("Signaled for unknown FD"); continue; } @@ -858,13 +859,13 @@ static int osc_handle(size_t num, managed_fd* fds){ osc_fmt = recv_buf + osc_align(strlen(recv_buf) + 1); if(*osc_fmt != ','){ //invalid format string - fprintf(stderr, "Invalid OSC format string in packet\n"); + LOGPF("Invalid format string in packet for instance %s", inst->name); continue; } osc_fmt++; if(osc_global_config.detect){ - fprintf(stderr, "Incoming OSC data: Path %s.%s Format %s\n", inst->name, osc_local, osc_fmt); + LOGPF("Incoming data: Path %s.%s Format %s", inst->name, osc_local, osc_fmt); } //FIXME check supplied data length @@ -880,11 +881,11 @@ static int osc_handle(size_t num, managed_fd* fds){ #else if(bytes_read < 0 && errno != EAGAIN){ #endif - fprintf(stderr, "OSC failed to receive data for instance %s: %s\n", inst->name, strerror(errno)); + LOGPF("Failed to receive data for instance %s: %s", inst->name, strerror(errno)); } if(bytes_read == 0){ - fprintf(stderr, "OSC descriptor for instance %s closed\n", inst->name); + LOGPF("Descriptor for instance %s closed", inst->name); return 1; } } @@ -903,7 +904,7 @@ static int osc_start(size_t n, instance** inst){ if(data->fd >= 0){ inst[u]->ident = data->fd; if(mm_manage_fd(data->fd, BACKEND_NAME, 1, inst[u])){ - fprintf(stderr, "Failed to register OSC descriptor for instance %s\n", inst[u]->name); + LOGPF("Failed to register descriptor for instance %s", inst[u]->name); return 1; } fds++; @@ -913,7 +914,7 @@ static int osc_start(size_t n, instance** inst){ } } - fprintf(stderr, "OSC backend registered %" PRIsize_t " descriptors to core\n", fds); + LOGPF("Registered %" PRIsize_t " descriptors to core", fds); return 0; } @@ -947,6 +948,6 @@ static int osc_shutdown(size_t n, instance** inst){ free(inst[u]->impl); } - fprintf(stderr, "OSC backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/sacn.c b/backends/sacn.c index 2a04245..ff2b61e 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "sacn" + #include #include #include @@ -15,7 +17,6 @@ //upper limit imposed by using the fd index as 16-bit part of the instance id #define MAX_FDS 4096 -#define BACKEND_NAME "sacn" enum /*_sacn_fd_flags*/ { mcast_loop = 1 @@ -49,13 +50,13 @@ MM_PLUGIN_API int init(){ }; if(sizeof(sacn_instance_id) != sizeof(uint64_t)){ - fprintf(stderr, "sACN instance identification union out of bounds\n"); + LOG("Instance identification union out of bounds"); return 1; } //register the backend if(mm_backend_register(sacn)){ - fprintf(stderr, "Failed to register sACN backend\n"); + LOG("Failed to register backend"); return 1; } @@ -65,7 +66,7 @@ MM_PLUGIN_API int init(){ static int sacn_listener(char* host, char* port, uint8_t flags){ int fd = -1, yes = 1; if(global_cfg.fds >= MAX_FDS){ - fprintf(stderr, "sACN backend descriptor limit reached\n"); + LOG("Descriptor limit reached"); return -1; } @@ -78,11 +79,11 @@ static int sacn_listener(char* host, char* port, uint8_t flags){ global_cfg.fd = realloc(global_cfg.fd, (global_cfg.fds + 1) * sizeof(sacn_fd)); if(!global_cfg.fd){ close(fd); - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return -1; } - fprintf(stderr, "sACN backend interface %" PRIsize_t " bound to %s port %s\n", global_cfg.fds, host, port); + LOGPF("Interface %" PRIsize_t " bound to %s port %s", global_cfg.fds, host, port); global_cfg.fd[global_cfg.fds].fd = fd; global_cfg.fd[global_cfg.fds].universes = 0; global_cfg.fd[global_cfg.fds].universe = NULL; @@ -91,7 +92,7 @@ static int sacn_listener(char* host, char* port, uint8_t flags){ if(flags & mcast_loop){ //set IP_MCAST_LOOP to allow local applications to receive output if(setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&yes, sizeof(yes)) < 0){ - fprintf(stderr, "Failed to disable IP_MULTICAST_LOOP on socket: %s\n", strerror(errno)); + LOGPF("Failed to re-enable IP_MULTICAST_LOOP on socket: %s", strerror(errno)); } } @@ -106,7 +107,7 @@ static int sacn_configure(char* option, char* value){ if(!strcmp(option, "name")){ if(strlen(value) > 63){ - fprintf(stderr, "Invalid sACN source name %s, limit is 63 characters\n", value); + LOGPF("Invalid source name %s, limit is 63 characters", value); return 1; } @@ -124,7 +125,7 @@ static int sacn_configure(char* option, char* value){ mmbackend_parse_hostspec(value, &host, &port, &next); if(!host){ - fprintf(stderr, "No valid sACN bind address provided\n"); + LOG("No valid bind address provided"); return 1; } @@ -133,14 +134,14 @@ static int sacn_configure(char* option, char* value){ } if(sacn_listener(host, port ? port : SACN_PORT, flags)){ - fprintf(stderr, "Failed to bind sACN descriptor: %s\n", value); + LOGPF("Failed to bind descriptor: %s", value); return 1; } return 0; } - fprintf(stderr, "Unknown sACN backend option %s\n", option); + LOGPF("Unknown backend configuration option %s", option); return 1; } @@ -157,7 +158,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ data->fd_index = strtoul(value, NULL, 10); if(data->fd_index >= global_cfg.fds){ - fprintf(stderr, "Configured sACN interface index is out of range on instance %s\n", inst->name); + LOGPF("Configured interface index is out of range on instance %s", inst->name); return 1; } return 0; @@ -170,7 +171,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ mmbackend_parse_hostspec(value, &host, &port, NULL); if(!host){ - fprintf(stderr, "No valid sACN destination for instance %s\n", inst->name); + LOGPF("No valid destination for instance %s", inst->name); return 1; } @@ -182,7 +183,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ for(u = 0; u < sizeof(data->cid_filter); u++){ data->cid_filter[u] = (strtoul(next, &next, 0) & 0xFF); } - fprintf(stderr, "Enabled source CID filter for instance %s\n", inst->name); + LOGPF("Enabled source CID filter for instance %s", inst->name); return 0; } else if(!strcmp(option, "unicast")){ @@ -190,7 +191,7 @@ static int sacn_configure_instance(instance* inst, char* option, char* value){ return 0; } - fprintf(stderr, "Unknown configuration option %s for sACN backend\n", option); + LOGPF("Unknown instance configuration option %s for instance %s", option, inst->name); return 1; } @@ -202,7 +203,7 @@ static instance* sacn_instance(){ inst->impl = calloc(1, sizeof(sacn_instance_data)); if(!inst->impl){ - fprintf(stderr, "Failed to allocate memory"); + LOG("Failed to allocate memory"); return NULL; } @@ -217,7 +218,7 @@ static channel* sacn_channel(instance* inst, char* spec, uint8_t flags){ //range check if(!chan_a || chan_a > 512){ - fprintf(stderr, "sACN channel out of range on instance %s: %s\n", inst->name, spec); + LOGPF("Channel out of range on instance %s: %s", inst->name, spec); return NULL; } chan_a--; @@ -226,14 +227,14 @@ static channel* sacn_channel(instance* inst, char* spec, uint8_t flags){ if(*spec_next == '+'){ chan_b = strtoul(spec_next + 1, NULL, 10); if(!chan_b || chan_b > 512){ - fprintf(stderr, "Invalid wide-channel spec on instance %s: %s\n", inst->name, spec); + LOGPF("Invalid wide-channel spec on instance %s: %s", inst->name, spec); return NULL; } chan_b--; //if already mapped, bail if(IS_ACTIVE(data->data.map[chan_b]) && data->data.map[chan_b] != (MAP_FINE | chan_a)){ - fprintf(stderr, "Fine channel %u already mapped on instance %s\n", chan_b, inst->name); + LOGPF("Fine channel %u already mapped on instance %s", chan_b, inst->name); return NULL; } @@ -244,7 +245,7 @@ static channel* sacn_channel(instance* inst, char* spec, uint8_t flags){ if(IS_ACTIVE(data->data.map[chan_a])){ if((*spec_next == '+' && data->data.map[chan_a] != (MAP_COARSE | chan_b)) || (*spec_next != '+' && data->data.map[chan_a] != (MAP_SINGLE | chan_a))){ - fprintf(stderr, "Primary sACN channel %u already mapped in another mode on instance %s\n", chan_a, inst->name); + LOGPF("Primary channel %u already mapped in another mode on instance %s", chan_a, inst->name); return NULL; } } @@ -290,7 +291,7 @@ static int sacn_transmit(instance* inst){ memcpy((((uint8_t*)pdu.data.data) + 1), data->data.out, 512); if(sendto(global_cfg.fd[data->fd_index].fd, (uint8_t*) &pdu, sizeof(pdu), 0, (struct sockaddr*) &data->dest_addr, data->dest_len) < 0){ - fprintf(stderr, "Failed to output sACN frame for instance %s: %s\n", inst->name, strerror(errno)); + LOGPF("Failed to output frame for instance %s: %s", inst->name, strerror(errno)); } //update last transmit timestamp @@ -311,7 +312,7 @@ static int sacn_set(instance* inst, size_t num, channel** c, channel_value* v){ } if(!data->xmit_prio){ - fprintf(stderr, "sACN instance %s not enabled for output (%" PRIsize_t " channel events)\n", inst->name, num); + LOGPF("Instance %s not enabled for output (%" PRIsize_t " channel events)", inst->name, num); return 0; } @@ -357,12 +358,12 @@ static int sacn_process_frame(instance* inst, sacn_frame_root* frame, sacn_frame if(data->format != 0xa1 || data->startcode_offset || be16toh(data->address_increment) != 1){ - fprintf(stderr, "sACN framing not supported\n"); + LOGPF("Framing not supported for incoming data on instance %s\n", inst->name); return 1; } if(be16toh(data->channels) > 513){ - fprintf(stderr, "Invalid sACN frame channel count\n"); + LOGPF("Invalid frame channel count %d on instance %s", be16toh(data->channels), inst->name); return 1; } @@ -396,7 +397,7 @@ static int sacn_process_frame(instance* inst, sacn_frame_root* frame, sacn_frame } if(!chan){ - fprintf(stderr, "Active channel %" PRIsize_t " on %s not known to core", u, inst->name); + LOGPF("Active channel %" PRIsize_t " on %s not known to core", u, inst->name); return 1; } @@ -413,7 +414,7 @@ static int sacn_process_frame(instance* inst, sacn_frame_root* frame, sacn_frame } if(mm_channel_event(chan, val)){ - fprintf(stderr, "Failed to push sACN channel event to core\n"); + LOG("Failed to push event to core"); return 1; } } @@ -464,7 +465,7 @@ static void sacn_discovery(size_t fd){ memcpy(pdu.data.data, global_cfg.fd[fd].universe + page * 512, universes * sizeof(uint16_t)); if(sendto(global_cfg.fd[fd].fd, (uint8_t*) &pdu, sizeof(pdu) - (512 - universes) * sizeof(uint16_t), 0, (struct sockaddr*) &discovery_dest, sizeof(discovery_dest)) < 0){ - fprintf(stderr, "Failed to output sACN universe discovery frame for interface %" PRIsize_t ": %s\n", fd, strerror(errno)); + LOGPF("Failed to output universe discovery frame for interface %" PRIsize_t ": %s", fd, strerror(errno)); } } } @@ -524,7 +525,7 @@ static int sacn_handle(size_t num, managed_fd* fds){ instance_id.fields.uni = be16toh(data->universe); inst = mm_instance_find(BACKEND_NAME, instance_id.label); if(inst && sacn_process_frame(inst, frame, data)){ - fprintf(stderr, "Failed to process sACN frame\n"); + LOG("Failed to process frame"); } } } @@ -535,11 +536,11 @@ static int sacn_handle(size_t num, managed_fd* fds){ #else if(bytes_read < 0 && errno != EAGAIN){ #endif - fprintf(stderr, "sACN failed to receive data: %s\n", strerror(errno)); + LOGPF("Failed to receive data: %s", strerror(errno)); } if(bytes_read == 0){ - fprintf(stderr, "sACN listener closed\n"); + LOG("Listener closed"); return 1; } } @@ -560,7 +561,7 @@ static int sacn_start(size_t n, instance** inst){ struct sockaddr_in* dest_v4 = NULL; if(!global_cfg.fds){ - fprintf(stderr, "Failed to start sACN backend: no descriptors bound\n"); + LOG("Failed to start, no descriptors bound"); free(inst); return 1; } @@ -573,14 +574,14 @@ static int sacn_start(size_t n, instance** inst){ inst[u]->ident = id.label; if(!data->uni){ - fprintf(stderr, "Please specify a universe on instance %s\n", inst[u]->name); + LOGPF("Please specify a universe on instance %s", inst[u]->name); goto bail; } //find duplicates for(p = 0; p < u; p++){ if(inst[u]->ident == inst[p]->ident){ - fprintf(stderr, "Colliding sACN instances, use one: %s - %s\n", inst[u]->name, inst[p]->name); + LOGPF("Colliding instances, use one: %s - %s", inst[u]->name, inst[p]->name); goto bail; } } @@ -588,7 +589,7 @@ static int sacn_start(size_t n, instance** inst){ if(!data->unicast_input){ mcast_req.imr_multiaddr.s_addr = htobe32(((uint32_t) 0xefff0000) | ((uint32_t) data->uni)); if(setsockopt(global_cfg.fd[data->fd_index].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (uint8_t*) &mcast_req, sizeof(mcast_req))){ - fprintf(stderr, "Failed to join Multicast group for sACN universe %u on instance %s: %s\n", data->uni, inst[u]->name, strerror(errno)); + LOGPF("Failed to join Multicast group for universe %u on instance %s: %s", data->uni, inst[u]->name, strerror(errno)); } } @@ -596,7 +597,7 @@ static int sacn_start(size_t n, instance** inst){ //add to list of advertised universes for this fd global_cfg.fd[data->fd_index].universe = realloc(global_cfg.fd[data->fd_index].universe, (global_cfg.fd[data->fd_index].universes + 1) * sizeof(uint16_t)); if(!global_cfg.fd[data->fd_index].universe){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); goto bail; } @@ -614,12 +615,12 @@ static int sacn_start(size_t n, instance** inst){ } } - fprintf(stderr, "sACN backend registering %" PRIsize_t " descriptors to core\n", global_cfg.fds); + LOGPF("Registering %" PRIsize_t " descriptors to core", global_cfg.fds); for(u = 0; u < global_cfg.fds; u++){ //allocate memory for storing last frame transmission timestamp global_cfg.fd[u].last_frame = calloc(global_cfg.fd[u].universes, sizeof(uint64_t)); if(!global_cfg.fd[u].last_frame){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); goto bail; } if(mm_manage_fd(global_cfg.fd[u].fd, BACKEND_NAME, 1, (void*) u)){ @@ -645,6 +646,6 @@ static int sacn_shutdown(size_t n, instance** inst){ free(global_cfg.fd[p].last_frame); } free(global_cfg.fd); - fprintf(stderr, "sACN backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/backends/winmidi.c b/backends/winmidi.c index c917ac6..0722ca2 100644 --- a/backends/winmidi.c +++ b/backends/winmidi.c @@ -1,3 +1,5 @@ +#define BACKEND_NAME "winmidi" + #include #include "libmmbackend.h" @@ -5,8 +7,6 @@ #include "winmidi.h" -#define BACKEND_NAME "winmidi" - static struct { uint8_t list_devices; uint8_t detect; @@ -37,13 +37,13 @@ MM_PLUGIN_API int init(){ }; if(sizeof(winmidi_channel_ident) != sizeof(uint64_t)){ - fprintf(stderr, "winmidi channel identification union out of bounds\n"); + LOG("Channel identification union out of bounds"); return 1; } //register backend if(mm_backend_register(winmidi)){ - fprintf(stderr, "Failed to register winmidi backend\n"); + LOG("Failed to register backend"); return 1; } @@ -68,7 +68,7 @@ static int winmidi_configure(char* option, char* value){ return 0; } - fprintf(stderr, "Unknown winmidi backend option %s\n", option); + LOGPF("Unknown backend option %s", option); return 1; } @@ -76,7 +76,7 @@ static int winmidi_configure_instance(instance* inst, char* option, char* value) winmidi_instance_data* data = (winmidi_instance_data*) inst->impl; if(!strcmp(option, "read")){ if(data->read){ - fprintf(stderr, "winmidi instance %s already connected to an input device\n", inst->name); + LOGPF("Instance %s already connected to an input device", inst->name); return 1; } data->read = strdup(value); @@ -84,14 +84,14 @@ static int winmidi_configure_instance(instance* inst, char* option, char* value) } if(!strcmp(option, "write")){ if(data->write){ - fprintf(stderr, "winmidi instance %s already connected to an output device\n", inst->name); + LOGPF("Instance %s already connected to an output device", inst->name); return 1; } data->write = strdup(value); return 0; } - fprintf(stderr, "Unknown winmidi instance option %s\n", option); + LOGPF("Unknown instance configuration option %s on instance %s", option, inst->name); return 1; } @@ -103,7 +103,7 @@ static instance* winmidi_instance(){ i->impl = calloc(1, sizeof(winmidi_instance_data)); if(!i->impl){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); return NULL; } @@ -124,18 +124,18 @@ static channel* winmidi_channel(instance* inst, char* spec, uint8_t flags){ } if(!next_token){ - fprintf(stderr, "Invalid winmidi channel specification %s\n", spec); + LOGPF("Invalid channel specification %s", spec); return NULL; } ident.fields.channel = strtoul(next_token, &next_token, 10); if(ident.fields.channel > 15){ - fprintf(stderr, "MIDI channel out of range in winmidi channel spec %s\n", spec); + LOGPF("MIDI channel out of range in spec %s", spec); return NULL; } if(*next_token != '.'){ - fprintf(stderr, "winmidi channel specification %s does not conform to channel.\n", spec); + LOGPF("Channel specification %s does not conform to channel.", spec); return NULL; } @@ -160,7 +160,7 @@ static channel* winmidi_channel(instance* inst, char* spec, uint8_t flags){ ident.fields.type = aftertouch; } else{ - fprintf(stderr, "Unknown winmidi channel control type in %s\n", spec); + LOGPF("Unknown control type in %s", spec); return NULL; } @@ -196,7 +196,7 @@ static int winmidi_set(instance* inst, size_t num, channel** c, channel_value* v } if(!data->device_out){ - fprintf(stderr, "winmidi instance %s has no output device\n", inst->name); + LOGPF("Instance %s has no output device", inst->name); return 0; } @@ -259,14 +259,14 @@ static int winmidi_handle(size_t num, managed_fd* fds){ //pretty-print channel-wide events if(backend_config.event[u].channel.fields.type == pitchbend || backend_config.event[u].channel.fields.type == aftertouch){ - fprintf(stderr, "Incoming MIDI data on channel %s.ch%d.%s, value %f\n", + LOGPF("Incoming data on channel %s.ch%d.%s, value %f", backend_config.event[u].inst->name, backend_config.event[u].channel.fields.channel, winmidi_type_name(backend_config.event[u].channel.fields.type), backend_config.event[u].value); } else{ - fprintf(stderr, "Incoming MIDI data on channel %s.ch%d.%s%d, value %f\n", + LOGPF("Incoming data on channel %s.ch%d.%s%d, value %f", backend_config.event[u].inst->name, backend_config.event[u].channel.fields.channel, winmidi_type_name(backend_config.event[u].channel.fields.type), @@ -279,7 +279,7 @@ static int winmidi_handle(size_t num, managed_fd* fds){ mm_channel_event(chan, backend_config.event[u].value); } } - DBGPF("winmidi flushed %" PRIsize_t " wakeups, handled %" PRIsize_t " events\n", bytes, backend_config.events_active); + DBGPF("Flushed %" PRIsize_t " wakeups, handled %" PRIsize_t " events", bytes, backend_config.events_active); backend_config.events_active = 0; LeaveCriticalSection(&backend_config.push_events); return 0; @@ -303,7 +303,7 @@ static void CALLBACK winmidi_input_callback(HMIDIIN device, unsigned message, DW }; //callbacks may run on different threads, so we queue all events and alert the main thread via the feedback socket - DBGPF("winmidi input callback on thread %ld\n", GetCurrentThreadId()); + DBGPF("Input callback on thread %ld", GetCurrentThreadId()); switch(message){ case MIM_MOREDATA: @@ -334,7 +334,7 @@ static void CALLBACK winmidi_input_callback(HMIDIIN device, unsigned message, DW return; case MIM_ERROR: //error in input stream - fprintf(stderr, "winmidi warning: error in input stream\n"); + LOG("Error in input stream"); return; case MIM_OPEN: case MIM_CLOSE: @@ -343,14 +343,14 @@ static void CALLBACK winmidi_input_callback(HMIDIIN device, unsigned message, DW } - DBGPF("winmidi incoming message type %d channel %d control %d value %f\n", + DBGPF("Incoming message type %d channel %d control %d value %f", ident.fields.type, ident.fields.channel, ident.fields.control, val.normalised); EnterCriticalSection(&backend_config.push_events); if(backend_config.events_alloc <= backend_config.events_active){ backend_config.event = realloc((void*) backend_config.event, (backend_config.events_alloc + 1) * sizeof(winmidi_event)); if(!backend_config.event){ - fprintf(stderr, "Failed to allocate memory\n"); + LOG("Failed to allocate memory"); backend_config.events_alloc = 0; backend_config.events_active = 0; LeaveCriticalSection(&backend_config.push_events); @@ -371,7 +371,7 @@ static void CALLBACK winmidi_input_callback(HMIDIIN device, unsigned message, DW } static void CALLBACK winmidi_output_callback(HMIDIOUT device, unsigned message, DWORD_PTR inst, DWORD param1, DWORD param2){ - DBGPF("winmidi output callback on thread %ld\n", GetCurrentThreadId()); + DBGPF("Output callback on thread %ld", GetCurrentThreadId()); } static int winmidi_match_input(char* prefix){ @@ -381,13 +381,13 @@ static int winmidi_match_input(char* prefix){ size_t n; if(!prefix){ - fprintf(stderr, "winmidi detected %u input devices\n", inputs); + LOGPF("Detected %u input devices", inputs); } else{ n = strtoul(prefix, &next_token, 10); if(!(*next_token) && n < inputs){ midiInGetDevCaps(n, &input_caps, sizeof(MIDIINCAPS)); - fprintf(stderr, "winmidi selected input device %s for ID %d\n", input_caps.szPname, n); + LOGPF("Selected input device %s for ID %d", input_caps.szPname, n); return n; } } @@ -396,10 +396,10 @@ static int winmidi_match_input(char* prefix){ for(n = 0; n < inputs; n++){ midiInGetDevCaps(n, &input_caps, sizeof(MIDIINCAPS)); if(!prefix){ - printf("\tID %d: %s\n", n, input_caps.szPname); + printf("\tID %d: %s", n, input_caps.szPname); } else if(!strncmp(input_caps.szPname, prefix, strlen(prefix))){ - fprintf(stderr, "winmidi selected input device %s (ID %" PRIsize_t ") for name %s\n", input_caps.szPname, n, prefix); + LOGPF("Selected input device %s (ID %" PRIsize_t ") for name %s", input_caps.szPname, n, prefix); return n; } } @@ -414,13 +414,13 @@ static int winmidi_match_output(char* prefix){ size_t n; if(!prefix){ - fprintf(stderr, "winmidi detected %u output devices\n", outputs); + LOGPF("Detected %u output devices", outputs); } else{ n = strtoul(prefix, &next_token, 10); if(!(*next_token) && n < outputs){ midiOutGetDevCaps(n, &output_caps, sizeof(MIDIOUTCAPS)); - fprintf(stderr, "winmidi selected output device %s for ID %d\n", output_caps.szPname, n); + LOGPF("Selected output device %s for ID %d", output_caps.szPname, n); return n; } } @@ -429,10 +429,10 @@ static int winmidi_match_output(char* prefix){ for(n = 0; n < outputs; n++){ midiOutGetDevCaps(n, &output_caps, sizeof(MIDIOUTCAPS)); if(!prefix){ - printf("\tID %d: %s\n", n, output_caps.szPname); + printf("\tID %d: %s", n, output_caps.szPname); } else if(!strncmp(output_caps.szPname, prefix, strlen(prefix))){ - fprintf(stderr, "winmidi selected output device %s (ID %" PRIsize_t " for name %s\n", output_caps.szPname, n, prefix); + LOGPF("Selected output device %s (ID %" PRIsize_t " for name %s", output_caps.szPname, n, prefix); return n; } } @@ -450,7 +450,7 @@ static int winmidi_start(size_t n, instance** inst){ //this really should be a size_t but getsockname specifies int* for some reason int sockadd_len = sizeof(sockadd); char* error = NULL; - DBGPF("winmidi main thread ID is %ld\n", GetCurrentThreadId()); + DBGPF("Main thread ID is %ld", GetCurrentThreadId()); //output device list if requested if(backend_config.list_devices){ @@ -462,13 +462,13 @@ static int winmidi_start(size_t n, instance** inst){ //for some reason the feedback connection fails to work on 'real' windows with ipv6 backend_config.socket_pair[0] = mmbackend_socket("127.0.0.1", "0", SOCK_DGRAM, 1, 0); if(backend_config.socket_pair[0] < 0){ - fprintf(stderr, "winmidi failed to open feedback socket\n"); + LOG("Failed to open feedback socket"); return 1; } if(getsockname(backend_config.socket_pair[0], (struct sockaddr*) &sockadd, &sockadd_len)){ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error, 0, NULL); - fprintf(stderr, "winmidi failed to query feedback socket information: %s\n", error); + LOGPF("Failed to query feedback socket information: %s", error); LocalFree(error); return 1; } @@ -484,15 +484,15 @@ static int winmidi_start(size_t n, instance** inst){ // ((struct sockaddr_in6*) &sockadd)->sin6_addr = in6addr_any; // break; default: - fprintf(stderr, "winmidi invalid feedback socket family\n"); + LOG("Invalid feedback socket family"); return 1; } - DBGPF("winmidi feedback socket family %d port %d\n", sockadd.ss_family, be16toh(((struct sockaddr_in*)&sockadd)->sin_port)); + DBGPF("Feedback socket family %d port %d", sockadd.ss_family, be16toh(((struct sockaddr_in*)&sockadd)->sin_port)); backend_config.socket_pair[1] = socket(sockadd.ss_family, SOCK_DGRAM, IPPROTO_UDP); if(backend_config.socket_pair[1] < 0 || connect(backend_config.socket_pair[1], (struct sockaddr*) &sockadd, sockadd_len)){ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error, 0, NULL); - fprintf(stderr, "winmidi failed to connect to feedback socket: %s\n", error); + LOGPF("Failed to connect to feedback socket: %s", error); LocalFree(error); return 1; } @@ -506,11 +506,11 @@ static int winmidi_start(size_t n, instance** inst){ if(data->read){ device = winmidi_match_input(data->read); if(device < 0){ - fprintf(stderr, "Failed to match input device %s for instance %s\n", data->read, inst[p]->name); + LOGPF("Failed to match input device %s for instance %s", data->read, inst[p]->name); goto bail; } if(midiInOpen(&(data->device_in), device, (DWORD_PTR) winmidi_input_callback, (DWORD_PTR) inst[p], CALLBACK_FUNCTION | MIDI_IO_STATUS) != MMSYSERR_NOERROR){ - fprintf(stderr, "Failed to open input device for instance %s\n", inst[p]->name); + LOGPF("Failed to open input device for instance %s", inst[p]->name); goto bail; } //start midi input callbacks @@ -521,18 +521,18 @@ static int winmidi_start(size_t n, instance** inst){ if(data->write){ device = winmidi_match_output(data->write); if(device < 0){ - fprintf(stderr, "Failed to match output device %s for instance %s\n", data->read, inst[p]->name); + LOGPF("Failed to match output device %s for instance %s", data->read, inst[p]->name); goto bail; } if(midiOutOpen(&(data->device_out), device, (DWORD_PTR) winmidi_output_callback, (DWORD_PTR) inst[p], CALLBACK_FUNCTION) != MMSYSERR_NOERROR){ - fprintf(stderr, "Failed to open output device for instance %s\n", inst[p]->name); + LOGPF("Failed to open output device for instance %s", inst[p]->name); goto bail; } } } //register the feedback socket to the core - fprintf(stderr, "winmidi backend registering 1 descriptor to core\n"); + LOG("Registering 1 descriptor to core"); if(mm_manage_fd(backend_config.socket_pair[0], BACKEND_NAME, 1, NULL)){ goto bail; } @@ -579,6 +579,6 @@ static int winmidi_shutdown(size_t n, instance** inst){ LeaveCriticalSection(&backend_config.push_events); DeleteCriticalSection(&backend_config.push_events); - fprintf(stderr, "winmidi backend shut down\n"); + LOG("Backend shut down"); return 0; } diff --git a/midimonster.h b/midimonster.h index eb19409..5844bb9 100644 --- a/midimonster.h +++ b/midimonster.h @@ -10,6 +10,11 @@ #define MIDIMONSTER_VERSION "v0.3-dist" #endif +/* Set backend name if unset */ +#ifndef BACKEND_NAME + #define BACKEND_NAME "unspec" +#endif + /* API call attributes and visibilities */ #ifndef MM_API #ifdef _WIN32 @@ -37,13 +42,15 @@ /* Debug messages only compile in when DEBUG is set */ #ifdef DEBUG - #define DBGPF(format, ...) fprintf(stderr, (format), __VA_ARGS__) - #define DBG(message) fprintf(stderr, "%s", (message)) + #define DBGPF(format, ...) fprintf(stderr, "debug/%s\t" format "\n", (BACKEND_NAME), __VA_ARGS__) #else #define DBGPF(format, ...) - #define DBG(message) #endif +/* Log messages should be routed through these macros to ensure interoperability with different core implementations */ +#define LOGPF(format, ...) fprintf(stderr, "%s\t" format "\n", (BACKEND_NAME), __VA_ARGS__) +#define LOG(message) fprintf(stderr, "%s\t%s\n", (BACKEND_NAME), (message)) + /* Stop compilation if the build system reports an error */ #ifdef BUILD_ERROR #error The build system reported an error, compilation stopped. Refer to the invocation for this compilation unit for more information. -- cgit v1.2.3 From 81e00a54b701529201464ba048c47a9e55a31c91 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 21 Dec 2019 20:50:55 +0100 Subject: Experimentally build lua backend for Windows --- backends/Makefile | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/backends/Makefile b/backends/Makefile index feefd7b..656e6b6 100644 --- a/backends/Makefile +++ b/backends/Makefile @@ -7,8 +7,12 @@ BACKEND_LIB = libmmbackend.o SYSTEM := $(shell uname -s) -CFLAGS += -g -fPIC -I../ -Wall -Wpedantic -CPPFLAGS += -g -fPIC -I../ +# Generate debug symbols unless overridden +CFLAGS ?= -g +CPPFLAGS ?= -g + +CFLAGS += -fPIC -I../ -Wall -Wpedantic +CPPFLAGS += -fPIC -I../ LDFLAGS += -shared # Build Linux backends if possible @@ -47,10 +51,13 @@ evdev.so: CFLAGS += $(shell pkg-config --cflags libevdev || echo "-DBUILD_ERROR= evdev.so: LDLIBS = $(shell pkg-config --libs libevdev || echo "-DBUILD_ERROR=\"Missing pkg-config data for libevdev\"") ola.so: LDLIBS = -lola ola.so: CPPFLAGS += -Wno-write-strings + # The pkg-config name for liblua5.3 is subject to discussion. I prefer 'lua5.3' (which works on Debian and OSX), # but Arch requires 'lua53' which works on Debian, too, but breaks on OSX. lua.so: CFLAGS += $(shell pkg-config --cflags lua53 || pkg-config --cflags lua5.3 || echo "-DBUILD_ERROR=\"Missing pkg-config data for lua53\"") lua.so: LDLIBS += $(shell pkg-config --libs lua53 || pkg-config --libs lua5.3 || echo "-DBUILD_ERROR=\"Missing pkg-config data for lua53\"") +lua.dll: CFLAGS += $(shell pkg-config --cflags lua53 || pkg-config --cflags lua5.3 || echo "-DBUILD_ERROR=\"Missing pkg-config data for lua53\"") +lua.dll: LDLIBS += -L../libs -llua53 %.so :: %.c %.h $(BACKEND_LIB) $(CC) $(CFLAGS) $(LDLIBS) $< $(ADDITIONAL_OBJS) -o $@ $(LDFLAGS) @@ -66,10 +73,12 @@ all: $(BACKEND_LIB) $(BACKENDS) ../libmmapi.a: $(MAKE) -C ../ midimonster.exe -windows: export CC = x86_64-w64-mingw32-gcc -windows: LDLIBS += -lmmapi -windows: LDFLAGS += -L../ +%.dll: export CC = x86_64-w64-mingw32-gcc +%.dll: LDLIBS += -lmmapi +%.dll: LDFLAGS += -L../ +%.dll: CFLAGS += -Wno-format -Wno-pointer-sign windows: CFLAGS += -Wno-format -Wno-pointer-sign +windows: export CC = x86_64-w64-mingw32-gcc windows: ../libmmapi.a $(BACKEND_LIB) $(WINDOWS_BACKENDS) full: $(BACKEND_LIB) $(BACKENDS) $(OPTIONAL_BACKENDS) -- cgit v1.2.3 From d041d89d07d1a62302db9ff5948a345447a82d23 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sun, 22 Dec 2019 13:07:37 +0100 Subject: Add priority to sACN example config --- configs/launchctl-sacn.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/launchctl-sacn.cfg b/configs/launchctl-sacn.cfg index 0f4a19b..dedfc0f 100644 --- a/configs/launchctl-sacn.cfg +++ b/configs/launchctl-sacn.cfg @@ -14,6 +14,7 @@ read = Launch Control [sacn out] universe = 1 +priority = 100 [map] -- cgit v1.2.3 From 172d8a210f7df36a26b01d2fe018ff4c959a6987 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sun, 22 Dec 2019 13:12:37 +0100 Subject: Fix typo --- backends/libmmbackend.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/libmmbackend.h b/backends/libmmbackend.h index 76e588f..aa0d0f0 100644 --- a/backends/libmmbackend.h +++ b/backends/libmmbackend.h @@ -94,7 +94,7 @@ size_t json_obj_offset(char* json, char* key); size_t json_array_offset(char* json, uint64_t key); /* - * Check for for a key within a JSON object / index within an array + * Check for a key within a JSON object / index within an array * Assumes a zero-terminated, validated JSON object / array as input * Returns type of value */ -- cgit v1.2.3 From 15b314d40692d4e86b5a030aab22e68c0f6aff51 Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 23 Dec 2019 16:49:29 +0100 Subject: Multi-layering example configuration --- configs/layering.cfg | 18 ++++++++++++++ configs/layering.lua | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 configs/layering.cfg create mode 100644 configs/layering.lua diff --git a/configs/layering.cfg b/configs/layering.cfg new file mode 100644 index 0000000..3acfe5e --- /dev/null +++ b/configs/layering.cfg @@ -0,0 +1,18 @@ +[backend artnet] +bind = 0.0.0.0 + +[midi in] +read = Launch Control + +[artnet out] +destination = 255.255.255.255 +universe = 1 + +[lua layers] +script = layering.lua + +[map] +in.ch0.cc{0..15} > layers.in{0..15} +layers.out{0..511} > out.{1..512} + +in.ch0.note0 > layers.control diff --git a/configs/layering.lua b/configs/layering.lua new file mode 100644 index 0000000..0ced715 --- /dev/null +++ b/configs/layering.lua @@ -0,0 +1,70 @@ +current_layer = 0 + +function control(value) + current_layer = math.floor(value * 31.99); +end + +function in0(value) + output("out"..((current_layer * 16)), value) + print("Output on out"..((current_layer * 16))) +end + +function in1(value) + output("out"..((current_layer * 16)) + 1, value) +end + +function in2(value) + output("out"..((current_layer * 16)) + 2, value) +end + +function in3(value) + output("out"..((current_layer * 16)) + 3, value) +end + +function in4(value) + output("out"..((current_layer * 16)) + 4, value) +end + +function in5(value) + output("out"..((current_layer * 16)) + 5, value) +end + +function in6(value) + output("out"..((current_layer * 16)) + 6, value) +end + +function in7(value) + output("out"..((current_layer * 16)) + 7, value) +end + +function in8(value) + output("out"..((current_layer * 16)) + 8, value) +end + +function in9(value) + output("out"..((current_layer * 16)) + 9, value) +end + +function in10(value) + output("out"..((current_layer * 16)) + 10, value) +end + +function in11(value) + output("out"..((current_layer * 16)) + 11, value) +end + +function in12(value) + output("out"..((current_layer * 16)) + 12, value) +end + +function in13(value) + output("out"..((current_layer * 16)) + 13, value) +end + +function in14(value) + output("out"..((current_layer * 16)) + 14, value) +end + +function in15(value) + output("out"..((current_layer * 16)) + 15, value) +end -- cgit v1.2.3 From f4b448d304c22f7bf9c8b2675707d6924fbaba54 Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 23 Dec 2019 17:56:38 +0100 Subject: Add some comments to the layering example --- configs/layering.cfg | 5 +++++ configs/layering.lua | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/configs/layering.cfg b/configs/layering.cfg index 3acfe5e..7adcd6f 100644 --- a/configs/layering.cfg +++ b/configs/layering.cfg @@ -1,3 +1,8 @@ +; This configuration demonstrates how to create a "layered" mapping +; using the Lua backend. The 'control' channel on the layers instance +; selects the offset to which the 16 input channels (mapped from +; the rotaries of a Launch Control) are mapped on the output instance + [backend artnet] bind = 0.0.0.0 diff --git a/configs/layering.lua b/configs/layering.lua index 0ced715..834ed09 100644 --- a/configs/layering.lua +++ b/configs/layering.lua @@ -1,9 +1,15 @@ +-- This global variable has the current base offset for the input channels. +-- We want to map 16 input channels (from MIDI) to 512 output channels (ArtNet), +-- so we have 32 possible offsets (32 * 16 = 512) current_layer = 0 +-- Set the current_layer based on the control input channel function control(value) current_layer = math.floor(value * 31.99); end +-- Handler functions for the input channels +-- Calculate the channel offset and just output the value the input channel provides function in0(value) output("out"..((current_layer * 16)), value) print("Output on out"..((current_layer * 16))) -- cgit v1.2.3 From 535181b25ccbc492f741b9eeb111a02dfd038b41 Mon Sep 17 00:00:00 2001 From: cbdev Date: Mon, 23 Dec 2019 20:22:14 +0100 Subject: Fix lua order of operations --- configs/layering.lua | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/configs/layering.lua b/configs/layering.lua index 834ed09..5d9458d 100644 --- a/configs/layering.lua +++ b/configs/layering.lua @@ -12,65 +12,65 @@ end -- Calculate the channel offset and just output the value the input channel provides function in0(value) output("out"..((current_layer * 16)), value) - print("Output on out"..((current_layer * 16))) + print("Output on out"..(current_layer * 16)) end function in1(value) - output("out"..((current_layer * 16)) + 1, value) + output("out"..((current_layer * 16) + 1), value) end function in2(value) - output("out"..((current_layer * 16)) + 2, value) + output("out"..((current_layer * 16) + 2), value) end function in3(value) - output("out"..((current_layer * 16)) + 3, value) + output("out"..((current_layer * 16) + 3), value) end function in4(value) - output("out"..((current_layer * 16)) + 4, value) + output("out"..((current_layer * 16) + 4), value) end function in5(value) - output("out"..((current_layer * 16)) + 5, value) + output("out"..((current_layer * 16) + 5), value) end function in6(value) - output("out"..((current_layer * 16)) + 6, value) + output("out"..((current_layer * 16) + 6), value) end function in7(value) - output("out"..((current_layer * 16)) + 7, value) + output("out"..((current_layer * 16) + 7), value) end function in8(value) - output("out"..((current_layer * 16)) + 8, value) + output("out"..((current_layer * 16) + 8), value) end function in9(value) - output("out"..((current_layer * 16)) + 9, value) + output("out"..((current_layer * 16) + 9), value) end function in10(value) - output("out"..((current_layer * 16)) + 10, value) + output("out"..((current_layer * 16) + 10), value) end function in11(value) - output("out"..((current_layer * 16)) + 11, value) + output("out"..((current_layer * 16) + 11), value) end function in12(value) - output("out"..((current_layer * 16)) + 12, value) + output("out"..((current_layer * 16) + 12), value) end function in13(value) - output("out"..((current_layer * 16)) + 13, value) + output("out"..((current_layer * 16) + 13), value) end function in14(value) - output("out"..((current_layer * 16)) + 14, value) + output("out"..((current_layer * 16) + 14), value) end function in15(value) - output("out"..((current_layer * 16)) + 15, value) + output("out"..((current_layer * 16) + 15), value) end -- cgit v1.2.3 From cedbf74db776414988621e8113f5869b29c2cb41 Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 24 Dec 2019 00:50:05 +0100 Subject: Fix version define for Windows --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 75c9d0d..990aec3 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ midimonster: LDLIBS = -ldl # Replace version string with current git-describe if possible ifneq "$(GITVERSION)" "" midimonster: CFLAGS += -DMIDIMONSTER_VERSION=\"$(GITVERSION)\" +midimonster.exe: CFLAGS += -DMIDIMONSTER_VERSION=\"$(GITVERSION)\" endif # Work around strange linker passing convention differences in Linux and OSX -- cgit v1.2.3 From 67e0226e88efd01a3f6dd60759ce6bca029967dd Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 25 Dec 2019 11:45:27 +0100 Subject: Fix uninitialized variable --- backends/maweb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/maweb.c b/backends/maweb.c index 39a6cb2..f81ab46 100644 --- a/backends/maweb.c +++ b/backends/maweb.c @@ -752,7 +752,7 @@ static ssize_t maweb_handle_ws(instance* inst, ssize_t bytes_read){ static int maweb_handle_fd(instance* inst){ maweb_instance_data* data = (maweb_instance_data*) inst->impl; - ssize_t bytes_read, bytes_left = data->allocated - data->offset, bytes_handled; + ssize_t bytes_read, bytes_left = data->allocated - data->offset, bytes_handled = 0; if(bytes_left < 3){ data->buffer = realloc(data->buffer, (data->allocated + MAWEB_RECV_CHUNK) * sizeof(uint8_t)); -- cgit v1.2.3 From 85fc921042efa68b0a34a413dd84bb1ea7a998cc Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 28 Dec 2019 14:51:26 +0100 Subject: Check API pointer before use, fix spelling --- backend.c | 2 +- installer.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend.c b/backend.c index 2af2f37..a2b120f 100644 --- a/backend.c +++ b/backend.c @@ -189,7 +189,7 @@ void channels_free(){ size_t u; for(u = 0; u < nchannels; u++){ DBGPF("Destroying channel %lu on instance %s\n", channels[u]->ident, channels[u]->instance->name); - if(channels[u]->impl){ + if(channels[u]->impl && channels[u]->instance->backend->channel_free){ channels[u]->instance->backend->channel_free(channels[u]); } free(channels[u]); diff --git a/installer.sh b/installer.sh index c85b70e..15ad203 100755 --- a/installer.sh +++ b/installer.sh @@ -106,7 +106,7 @@ UPDATER-PREP () { printf "\nInitializing repository...\n" cd $tmp_path git init $tmp_path - printf "Sucessfully imported settings from %s\n" "$updater_file" + printf "Successfully imported settings from %s\n" "$updater_file" ) NIGHTLY_CHECK printf "Preparation successful\n\n" -- cgit v1.2.3 From f7e071444605ec72a6f4577dc7fc63b880d4dd61 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 28 Dec 2019 15:11:26 +0100 Subject: Fix OSX CI --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bdaf63a..7db9167 100644 --- a/.travis.yml +++ b/.travis.yml @@ -180,7 +180,8 @@ install: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ccache ola lua openssl jack; fi +# 'brew install' sometimes returns non-zero for some arcane reason. Executing 'true' resets the exit code and allows Travis to continue building... + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ccache ola lua openssl jack; true; fi # OpenSSL is not a proper install due to some Apple bull, so provide additional locations via the environment... # Additionally, newer versions of this "recipe" seem to use the name 'openssl@1.1' instead of plain 'openssl' and there seems to be # no way to programmatically get the link and include paths. Genius! Hardcoding the new version for the time being... -- cgit v1.2.3 From e4374c59881032ef644fbb2fd54a554dc4d914b1 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Tue, 31 Dec 2019 00:35:02 +0100 Subject: Automated travis deployment --- .travis-ci.sh | 33 ++++++++++++++++++++++++++++++++- .travis.yml | 10 ++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/.travis-ci.sh b/.travis-ci.sh index da36c17..593b254 100644 --- a/.travis-ci.sh +++ b/.travis-ci.sh @@ -76,9 +76,40 @@ elif [[ $TASK = 'windows' ]]; then travis_fold start "make_windows" make windows; travis_fold end "make_windows" + + if [ "$(git describe)" == "$(git describe --abbrev=0)" ]; then + mkdir ./deployment + mkdir ./deployment/backends + mkdir ./deployment/docs + cp ./midimonster.exe ./deployment/ + cp ./backends/*.dll ./deployment/backends/ + cp ./monster.cfg ./deployment/monster.cfg + cp ./backends/*.md ./deployment/docs/ + cp -r ./configs ./deployment/ + cd ./deployment + zip -r "./midimonster-$(git describe)-windows.zip" "./" + rm -v !("*.zip") + fi + + else # Otherwise compile as normal travis_fold start "make" make full; + +if [ "$(git describe)" == "$(git describe --abbrev=0)" ]; then + mkdir ./deployment + mkdir ./deployment/backends + mkdir ./deployment/docs + cp ./midimonster ./deployment/ + cp ./backends/*.so ./deployment/backends/ + cp ./monster.cfg ./deployment/monster.cfg + cp ./backends/*.md ./deployment/docs/ + cp -r ./configs ./deployment/ + cd ./deployment + tar czf "midimonster-$(git describe)-linux64.tgz" * + rm -v !("*.tgz") + fi + travis_fold end "make" -fi +fi \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 7db9167..3299c66 100644 --- a/.travis.yml +++ b/.travis.yml @@ -200,3 +200,13 @@ before_install: after_script: - if [ "$TASK" = "coverity" ]; then tail -n 10000 ${TRAVIS_BUILD_DIR}/cov-int/build-log.txt; cat ${TRAVIS_BUILD_DIR}/cov-int/scm_log.txt; fi + +deploy: + provider: releases + api_key: $GITHUB_TOKEN +file: + - "./deployment/*" + skip_cleanup: true + draft: true + on: + tags: true \ No newline at end of file -- cgit v1.2.3 From bbcefdf737452e2fcb4b7703a6348825a2112994 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Tue, 31 Dec 2019 00:42:12 +0100 Subject: fix travis deployment --- .travis.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3299c66..ea6ffc5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -204,9 +204,8 @@ after_script: deploy: provider: releases api_key: $GITHUB_TOKEN -file: - - "./deployment/*" - skip_cleanup: true - draft: true - on: - tags: true \ No newline at end of file + file: ./deployment/* + skip_cleanup: true + draft: true + on: + tags: true \ No newline at end of file -- cgit v1.2.3 From 54685b03160279242c51288a306f332c07c82625 Mon Sep 17 00:00:00 2001 From: Spacelord Date: Tue, 31 Dec 2019 00:55:00 +0100 Subject: Diversify automated deploy per host OS --- .travis-ci.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis-ci.sh b/.travis-ci.sh index 593b254..a50398b 100644 --- a/.travis-ci.sh +++ b/.travis-ci.sh @@ -88,7 +88,7 @@ elif [[ $TASK = 'windows' ]]; then cp -r ./configs ./deployment/ cd ./deployment zip -r "./midimonster-$(git describe)-windows.zip" "./" - rm -v !("*.zip") + rm -v !(*.zip) fi @@ -107,7 +107,7 @@ if [ "$(git describe)" == "$(git describe --abbrev=0)" ]; then cp ./backends/*.md ./deployment/docs/ cp -r ./configs ./deployment/ cd ./deployment - tar czf "midimonster-$(git describe)-linux64.tgz" * + tar czf "midimonster-$(git describe)-$TRAVIS_OS_NAME.tgz" * rm -v !("*.tgz") fi -- cgit v1.2.3 From 7d18bbb88b79c23c7e920eaecac75df77c38a02a Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 31 Dec 2019 01:27:01 +0100 Subject: Fix deployment directory cleanup --- .travis-ci.sh | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/.travis-ci.sh b/.travis-ci.sh index a50398b..1475dea 100644 --- a/.travis-ci.sh +++ b/.travis-ci.sh @@ -76,7 +76,7 @@ elif [[ $TASK = 'windows' ]]; then travis_fold start "make_windows" make windows; travis_fold end "make_windows" - + travis_fold start "deploy_windows" if [ "$(git describe)" == "$(git describe --abbrev=0)" ]; then mkdir ./deployment mkdir ./deployment/backends @@ -88,28 +88,27 @@ elif [[ $TASK = 'windows' ]]; then cp -r ./configs ./deployment/ cd ./deployment zip -r "./midimonster-$(git describe)-windows.zip" "./" - rm -v !(*.zip) + find . ! -iname '*.zip' -delete fi - - + travis_fold end "deploy_windows" else # Otherwise compile as normal travis_fold start "make" make full; - -if [ "$(git describe)" == "$(git describe --abbrev=0)" ]; then - mkdir ./deployment - mkdir ./deployment/backends - mkdir ./deployment/docs - cp ./midimonster ./deployment/ - cp ./backends/*.so ./deployment/backends/ - cp ./monster.cfg ./deployment/monster.cfg - cp ./backends/*.md ./deployment/docs/ - cp -r ./configs ./deployment/ - cd ./deployment - tar czf "midimonster-$(git describe)-$TRAVIS_OS_NAME.tgz" * - rm -v !("*.tgz") - fi - travis_fold end "make" -fi \ No newline at end of file + travis_fold start "deploy_unix" + if [ "$(git describe)" == "$(git describe --abbrev=0)" ]; then + mkdir ./deployment + mkdir ./deployment/backends + mkdir ./deployment/docs + cp ./midimonster ./deployment/ + cp ./backends/*.so ./deployment/backends/ + cp ./monster.cfg ./deployment/monster.cfg + cp ./backends/*.md ./deployment/docs/ + cp -r ./configs ./deployment/ + cd ./deployment + tar czf "midimonster-$(git describe)-$TRAVIS_OS_NAME.tgz" * + find . ! -iname '*.tgz' -delete + fi + travis_fold end "deploy_unix" +fi -- cgit v1.2.3 From 599430276d4cc7ca3cec27513a5a318fd5e5de25 Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 31 Dec 2019 01:53:23 +0100 Subject: Pull tags in CI before build --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea6ffc5..6c81d1b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,6 @@ addons: - *core_build - mingw-w64 - matrix: fast_finish: true include: @@ -179,6 +178,8 @@ install: - if [ "$TASK" = "codespell" ]; then pip install --user git+https://github.com/codespell-project/codespell.git; fi before_install: +# Travis clones with --branch, which omits tags. Since we use them for the version string at build time, fetch them + - git pull --tags - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi # 'brew install' sometimes returns non-zero for some arcane reason. Executing 'true' resets the exit code and allows Travis to continue building... - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ccache ola lua openssl jack; true; fi @@ -208,4 +209,4 @@ deploy: skip_cleanup: true draft: true on: - tags: true \ No newline at end of file + tags: true -- cgit v1.2.3 From 87fe68ef7d929b2f79e695df649b374fe0e2c572 Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 31 Dec 2019 10:33:29 +0100 Subject: Enable globs for Travis deployments --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6c81d1b..21c2a40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -204,6 +204,7 @@ after_script: deploy: provider: releases + file_glob: true api_key: $GITHUB_TOKEN file: ./deployment/* skip_cleanup: true -- cgit v1.2.3