aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile22
-rw-r--r--TODO13
-rw-r--r--backend.c42
-rw-r--r--backends/artnet.c28
-rw-r--r--backends/artnet.h4
-rw-r--r--backends/evdev.c31
-rw-r--r--backends/evdev.h4
-rw-r--r--backends/jack.c24
-rw-r--r--backends/jack.h4
-rw-r--r--backends/loopback.c14
-rw-r--r--backends/loopback.h4
-rw-r--r--backends/lua.c25
-rw-r--r--backends/lua.h4
-rw-r--r--backends/maweb.c29
-rw-r--r--backends/maweb.h4
-rw-r--r--backends/midi.c27
-rw-r--r--backends/midi.h4
-rw-r--r--backends/ola.cpp29
-rw-r--r--backends/ola.h4
-rw-r--r--backends/osc.c31
-rw-r--r--backends/osc.h4
-rw-r--r--backends/sacn.c29
-rw-r--r--backends/sacn.h4
-rw-r--r--backends/winmidi.c29
-rw-r--r--backends/winmidi.h4
-rw-r--r--config.c3
-rw-r--r--installer_todo1
-rw-r--r--midimonster.c27
-rw-r--r--midimonster.h9
29 files changed, 155 insertions, 302 deletions
diff --git a/Makefile b/Makefile
index 8dab638..75c9d0d 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)
@@ -65,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
diff --git a/TODO b/TODO
index cba1c15..1f1269d 100644
--- a/TODO
+++ b/TODO
@@ -1,15 +1,8 @@
-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/backend.c b/backend.c
index 3a18f41..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");
@@ -256,30 +262,56 @@ 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;
}
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 e01f038..b181296 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,22 +435,15 @@ static int artnet_start(){
rv = 0;
bail:
- free(inst);
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 f6a6709..59bd53f 100644
--- a/backends/artnet.h
+++ b/backends/artnet.h
@@ -10,8 +10,8 @@ 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_shutdown();
+static int artnet_start(size_t n, instance** inst);
+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 0da5ae6..d2eeba8 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;
}
@@ -512,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);
@@ -542,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 6504416..0c877fc 100644
--- a/backends/evdev.h
+++ b/backends/evdev.h
@@ -15,8 +15,8 @@ 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_shutdown();
+static int evdev_start(size_t n, instance** inst);
+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 e7bed04..eb53190 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,20 +682,13 @@ static int mmjack_start(){
rv = 0;
bail:
pthread_mutexattr_destroy(&mutex_attr);
- free(inst);
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;
@@ -741,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 a7f3e8b..66c66db 100644
--- a/backends/jack.h
+++ b/backends/jack.h
@@ -9,8 +9,8 @@ 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_shutdown();
+static int mmjack_start(size_t n, instance** inst);
+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 41e6f85..c2c3430 100644
--- a/backends/loopback.c
+++ b/backends/loopback.c
@@ -92,20 +92,14 @@ 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;
}
-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 ee51c66..c508d72 100644
--- a/backends/loopback.h
+++ b/backends/loopback.h
@@ -7,8 +7,8 @@ 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_shutdown();
+static int loopback_start(size_t n, instance** inst);
+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 40e6613..2ce40f5 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");
@@ -469,17 +460,10 @@ static int lua_start(){
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
@@ -495,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 4ea5b0a..75f03c4 100644
--- a/backends/lua.h
+++ b/backends/lua.h
@@ -16,8 +16,8 @@ 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_shutdown();
+static int lua_start(size_t n, instance** inst);
+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 d008cc0..8cf201e 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
@@ -1029,17 +1017,10 @@ static int maweb_start(){
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);
@@ -1065,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 92776ca..2088774 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,18 +412,12 @@ static int midi_start(){
bail:
free(pfds);
- free(inst);
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;
@@ -445,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 4e16f90..66a02bc 100644
--- a/backends/midi.h
+++ b/backends/midi.h
@@ -7,8 +7,8 @@ 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_shutdown();
+static int midi_start(size_t n, instance** inst);
+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 c13e8f9..fd121a0 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();
@@ -249,18 +248,6 @@ static int ola_start(){
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;
- }
-
- //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 +264,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;
@@ -288,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 0c42bac..083e971 100644
--- a/backends/ola.h
+++ b/backends/ola.h
@@ -11,8 +11,8 @@ 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_shutdown();
+ static int ola_start(size_t n, instance** inst);
+ static int ola_shutdown(size_t n, instance** inst);
}
#define MAP_COARSE 0x0200
diff --git a/backends/osc.c b/backends/osc.c
index 757ad89..2c65ecb 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);
@@ -891,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;
@@ -915,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++;
@@ -926,21 +914,13 @@ static int osc_start(){
}
fprintf(stderr, "OSC backend registered %" PRIsize_t " descriptors to core\n", fds);
-
- free(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++){
@@ -967,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 6f3b923..f8ff3ff 100644
--- a/backends/osc.h
+++ b/backends/osc.h
@@ -14,8 +14,8 @@ 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_shutdown();
+static int osc_start(size_t n, instance** inst);
+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 edb648d..ef422e8 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);
@@ -530,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
@@ -543,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);
@@ -624,23 +613,15 @@ static int sacn_start(){
rv = 0;
bail:
- free(inst);
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 1d3268c..726fa68 100644
--- a/backends/sacn.h
+++ b/backends/sacn.h
@@ -7,8 +7,8 @@ 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_shutdown();
+static int sacn_start(size_t n, instance** inst);
+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 790257b..090e438 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,20 +539,13 @@ static int winmidi_start(){
rv = 0;
bail:
- free(inst);
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);
@@ -586,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 985c46a..81e7439 100644
--- a/backends/winmidi.h
+++ b/backends/winmidi.h
@@ -7,8 +7,8 @@ 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_shutdown();
+static int winmidi_start(size_t n, instance** inst);
+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/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
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 <configfile>\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..1f5c936 100644
--- a/midimonster.h
+++ b/midimonster.h
@@ -5,6 +5,11 @@
#include <stdint.h>
#include <inttypes.h>
+/* 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
@@ -129,9 +134,9 @@ 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)();
+typedef int (*mmbackend_shutdown)(size_t ninstances, struct _backend_instance** inst);
/* Bit masks for the `flags` parameter to mmbackend_parse_channel */
typedef enum {