From 34a194cc101d7c77202b79a06e285573541d823f Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 16 Mar 2019 15:32:52 +0100 Subject: Only start backends with active instances --- midimonster.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 98d8459..a3e5e1f 100644 --- a/midimonster.h +++ b/midimonster.h @@ -29,7 +29,7 @@ struct _managed_fd; * * int init() * The only function that should be exported by the shared object. * Called when the shared object is attached. Should register - * a backend structure with the core. + * a backend structure containing callable entry points with the core. * Returning anything other than zero causes midimonster to fail the * startup checks. * * mmbackend_configure @@ -46,7 +46,8 @@ struct _managed_fd; * out-of-memory condition and terminates the program. * * mmbackend_start * Called after all instances have been created and all mappings - * have been set up. May be used to connect to backing hardware + * have been set up. Only backends for which instances have been configured + * receive the start call. May be used to connect to backing hardware * or to update runtime-specific data in the various data structures. * Returning a non-zero value signals an error starting the backend * and stops further progress. @@ -68,7 +69,9 @@ struct _managed_fd; * Return the maximum sleep interval for this backend in milliseconds. * If not implemented, a maximum interval of one second is used. * * mmbackend_shutdown - * Clean up all allocations, finalize all hardware connections. + * Clean up all allocations, finalize all hardware connections. All registered + * backends receive the shutdown call, regardless of whether they have been + * started previously. * Return value is currently ignored. */ typedef int (*mmbackend_handle_event)(struct _backend_instance* inst, size_t channels, struct _backend_channel** c, struct _channel_value* v); -- cgit v1.2.3 From 28000d6e09d5372ada278bc8e8d9960c5f15e678 Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 19 Mar 2019 00:31:47 +0100 Subject: Allow the fd set to be updated at translation time (Fixes #8) --- midimonster.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index a3e5e1f..cffbf67 100644 --- a/midimonster.h +++ b/midimonster.h @@ -179,8 +179,6 @@ channel* mm_channel(instance* i, uint64_t ident, uint8_t create); /* * Register a file descriptor to be selected on. The backend * will be notified via the mmbackend_process_fd call. - * This function may only be called from within the mmbackend_start - * procedure. */ int mm_manage_fd(int fd, char* backend, int manage, void* impl); /* -- cgit v1.2.3 From 0928bc2c59a38c411a35c49d83fd468e5e0dc43c Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 19 Mar 2019 00:36:23 +0100 Subject: Documentation update --- midimonster.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index cffbf67..572b5fb 100644 --- a/midimonster.h +++ b/midimonster.h @@ -177,12 +177,13 @@ instance* mm_instance_find(char* backend, uint64_t ident); channel* mm_channel(instance* i, uint64_t ident, uint8_t create); //TODO channel* mm_channel_find() /* - * Register a file descriptor to be selected on. The backend - * will be notified via the mmbackend_process_fd call. + * Register (manage = 1) or unregister (manage = 0) a file descriptor + * to be selected on. The backend will be notified when the descriptor + * becomes ready to read via its registered mmbackend_process_fd call. */ int mm_manage_fd(int fd, char* backend, int manage, void* impl); /* - * Notifies the core of a channel event. Used by backends to + * Notifies the core of a channel event. Called by backends to * inject events gathered from their backing implementation. */ int mm_channel_event(channel* c, channel_value v); -- cgit v1.2.3 From b618c4a6b74a52f830ca53029e1cc680d56a2501 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 6 Jul 2019 17:25:12 +0200 Subject: Implement Lua backend --- midimonster.h | 1 + 1 file changed, 1 insertion(+) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 572b5fb..8a18155 100644 --- a/midimonster.h +++ b/midimonster.h @@ -5,6 +5,7 @@ #include #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) +#define clamp(val,max,min) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) #ifdef DEBUG #define DBGPF(format, ...) fprintf(stderr, (format), __VA_ARGS__) #define DBG(message) fprintf(stderr, "%s", (message)) -- cgit v1.2.3 From 5bd8e81e2821f1378c6773fbc1f06df063dbbd22 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 20 Jul 2019 18:10:56 +0200 Subject: Implement multi-channel mapping syntax --- midimonster.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 8a18155..1fc85b7 100644 --- a/midimonster.h +++ b/midimonster.h @@ -3,9 +3,15 @@ #include #include #include + +/* Straight-forward min / max macros */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) + +/* Clamp a value to a range */ #define clamp(val,max,min) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) + +/* 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)) @@ -14,10 +20,13 @@ #define DBG(message) #endif +/* Pull in additional defines for non-linux platforms */ #include "portability.h" +/* Default configuration file name to read when no other is specified */ #define DEFAULT_CFG "monster.cfg" +/* Forward declare some of the structs so we can use them in eachother */ struct _channel_value; struct _backend_channel; struct _backend_instance; @@ -86,6 +95,7 @@ typedef int (*mmbackend_start)(); typedef uint32_t (*mmbackend_interval)(); typedef int (*mmbackend_shutdown)(); +/* Channel event value, .normalised is used by backends to determine channel values */ typedef struct _channel_value { union { double dbl; @@ -94,6 +104,10 @@ typedef struct _channel_value { double normalised; } channel_value; +/* + * Backend callback structure + * Used to register a backend with the core using mm_backend_register() + */ typedef struct /*_mm_backend*/ { char* name; mmbackend_configure conf; @@ -108,6 +122,10 @@ typedef struct /*_mm_backend*/ { mmbackend_interval interval; } backend; +/* + * Backend instance structure - do not allocate directly! + * Use the memory returned by mm_instance() + */ typedef struct _backend_instance { backend* backend; uint64_t ident; @@ -115,20 +133,51 @@ typedef struct _backend_instance { char* name; } instance; +/* + * Channel specification glob + */ +typedef struct /*_mm_channel_glob*/ { + size_t offset[2]; + union { + void* impl; + uint64_t u64[2]; + } limits; + uint64_t values; +} channel_glob; + +/* + * (Multi-)Channel specification + */ +typedef struct /*_mm_channel_spec*/ { + char* spec; + uint8_t internal; + size_t channels; + size_t globs; + channel_glob* glob; +} channel_spec; + +/* + * Instance channel structure + * Backends may either manage their own channel registry + * or use the memory returned by mm_channel() + */ typedef struct _backend_channel { instance* instance; uint64_t ident; void* impl; } channel; -//FIXME might be replaced by struct pollfd -//FIXME who frees impl +/* + * File descriptor management structure + * Register for the core event loop using mm_manage_fd() + */ typedef struct _managed_fd { int fd; backend* backend; void* impl; } managed_fd; +/* Internal channel mapping structure - Core use only */ typedef struct /*_mm_channel_mapping*/ { channel* from; size_t destinations; -- cgit v1.2.3 From 59857ead2d439d450afc6f5144c9c08e8d0c8a5c Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 24 Jul 2019 21:12:01 +0200 Subject: Fix issues found by Coverity Scan --- midimonster.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 1fc85b7..7f70f5b 100644 --- a/midimonster.h +++ b/midimonster.h @@ -26,7 +26,7 @@ /* Default configuration file name to read when no other is specified */ #define DEFAULT_CFG "monster.cfg" -/* Forward declare some of the structs so we can use them in eachother */ +/* Forward declare some of the structs so we can use them in each other */ struct _channel_value; struct _backend_channel; struct _backend_instance; -- cgit v1.2.3 From 20a6882a063404858588596bd3f12bdd9e53460a Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 3 Aug 2019 18:42:39 +0200 Subject: Windows build compatiblity --- midimonster.h | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 7f70f5b..eb118c6 100644 --- a/midimonster.h +++ b/midimonster.h @@ -4,6 +4,21 @@ #include #include +#ifndef MM_API + #ifdef _WIN32 + #define MM_API __attribute__((dllimport)) + #else + #define MM_API + #endif +#endif + +/* GCC ignores the visibility attributes on some API functions, so override visibility */ +#if !defined(_WIN32) && defined(__GNUC__) && !defined(__clang__) + #undef MM_API + #define MM_API + #pragma GCC visibility push(default) +#endif + /* Straight-forward min / max macros */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -187,7 +202,7 @@ typedef struct /*_mm_channel_mapping*/ { /* * Register a new backend. */ -int mm_backend_register(backend b); +int MM_API mm_backend_register(backend b); /* * Provides a pointer to a newly (zero-)allocated instance. @@ -201,7 +216,8 @@ int mm_backend_register(backend b); * mmbackend_shutdown procedure of the backend, eg. by querying * all instances for the backend. */ -instance* mm_instance(); +instance* MM_API mm_instance(); + /* * Finds an instance matching the specified backend and identifier. * Since setting an identifier for an instance is optional, @@ -209,7 +225,8 @@ instance* mm_instance(); * Instance identifiers may for example be set in the backends * mmbackend_start call. */ -instance* mm_instance_find(char* backend, uint64_t ident); +instance* MM_API mm_instance_find(char* backend, uint64_t ident); + /* * Provides a pointer to a channel structure, pre-filled with * the provided instance reference and identifier. @@ -224,30 +241,35 @@ instance* mm_instance_find(char* backend, uint64_t ident); * this function, the backend will receive a call to its channel_free * function. */ -channel* mm_channel(instance* i, uint64_t ident, uint8_t create); +channel* MM_API mm_channel(instance* i, uint64_t ident, uint8_t create); //TODO channel* mm_channel_find() + /* * Register (manage = 1) or unregister (manage = 0) a file descriptor * to be selected on. The backend will be notified when the descriptor * becomes ready to read via its registered mmbackend_process_fd call. */ -int mm_manage_fd(int fd, char* backend, int manage, void* impl); +int MM_API mm_manage_fd(int fd, char* backend, int manage, void* impl); + /* * Notifies the core of a channel event. Called by backends to * inject events gathered from their backing implementation. */ -int mm_channel_event(channel* c, channel_value v); +int MM_API mm_channel_event(channel* c, channel_value v); + /* * Query all active instances for a given backend. * *i will need to be freed by the caller. */ -int mm_backend_instances(char* backend, size_t* n, instance*** i); +int MM_API mm_backend_instances(char* backend, size_t* n, instance*** i); + /* * Query an internal timestamp, which is updated every core iteration. * This timestamp should not be used as a performance counter, but can be * used for timeouting. Resolution is milliseconds. */ -uint64_t mm_timestamp(); +uint64_t MM_API mm_timestamp(); + /* * Create a channel-to-channel mapping. This API should not * be used by backends. It is only exported for core modules. -- cgit v1.2.3 From 47a5f9a21bd661f9161d6175ebd074962daee255 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 7 Aug 2019 17:25:24 +0200 Subject: Fix export visibilities for GCC --- midimonster.h | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index eb118c6..270a61f 100644 --- a/midimonster.h +++ b/midimonster.h @@ -12,13 +12,6 @@ #endif #endif -/* GCC ignores the visibility attributes on some API functions, so override visibility */ -#if !defined(_WIN32) && defined(__GNUC__) && !defined(__clang__) - #undef MM_API - #define MM_API - #pragma GCC visibility push(default) -#endif - /* Straight-forward min / max macros */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -202,7 +195,7 @@ typedef struct /*_mm_channel_mapping*/ { /* * Register a new backend. */ -int MM_API mm_backend_register(backend b); +MM_API int mm_backend_register(backend b); /* * Provides a pointer to a newly (zero-)allocated instance. @@ -216,7 +209,7 @@ int MM_API mm_backend_register(backend b); * mmbackend_shutdown procedure of the backend, eg. by querying * all instances for the backend. */ -instance* MM_API mm_instance(); +MM_API instance* mm_instance(); /* * Finds an instance matching the specified backend and identifier. @@ -225,7 +218,7 @@ instance* MM_API mm_instance(); * Instance identifiers may for example be set in the backends * mmbackend_start call. */ -instance* MM_API mm_instance_find(char* backend, uint64_t ident); +MM_API instance* mm_instance_find(char* backend, uint64_t ident); /* * Provides a pointer to a channel structure, pre-filled with @@ -241,7 +234,7 @@ instance* MM_API mm_instance_find(char* backend, uint64_t ident); * this function, the backend will receive a call to its channel_free * function. */ -channel* MM_API mm_channel(instance* i, uint64_t ident, uint8_t create); +MM_API channel* mm_channel(instance* i, uint64_t ident, uint8_t create); //TODO channel* mm_channel_find() /* @@ -249,26 +242,26 @@ channel* MM_API mm_channel(instance* i, uint64_t ident, uint8_t create); * to be selected on. The backend will be notified when the descriptor * becomes ready to read via its registered mmbackend_process_fd call. */ -int MM_API mm_manage_fd(int fd, char* backend, int manage, void* impl); +MM_API int mm_manage_fd(int fd, char* backend, int manage, void* impl); /* * Notifies the core of a channel event. Called by backends to * inject events gathered from their backing implementation. */ -int MM_API mm_channel_event(channel* c, channel_value v); +MM_API int mm_channel_event(channel* c, channel_value v); /* * Query all active instances for a given backend. * *i will need to be freed by the caller. */ -int MM_API mm_backend_instances(char* backend, size_t* n, instance*** i); +MM_API int mm_backend_instances(char* backend, size_t* n, instance*** i); /* * Query an internal timestamp, which is updated every core iteration. * This timestamp should not be used as a performance counter, but can be * used for timeouting. Resolution is milliseconds. */ -uint64_t MM_API mm_timestamp(); +MM_API uint64_t mm_timestamp(); /* * Create a channel-to-channel mapping. This API should not -- cgit v1.2.3 From 49855046f683deb7fdadc2c3d8caf513099b4803 Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 4 Sep 2019 20:26:24 +0200 Subject: Use platform-independent specifiers for printf calls --- midimonster.h | 1 + 1 file changed, 1 insertion(+) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 270a61f..491cc11 100644 --- a/midimonster.h +++ b/midimonster.h @@ -3,6 +3,7 @@ #include #include #include +#include #ifndef MM_API #ifdef _WIN32 -- cgit v1.2.3 From 350f0d2d2eaff5f0d57b09857102e2df1e96d733 Mon Sep 17 00:00:00 2001 From: cbdev Date: Thu, 7 Nov 2019 18:44:19 +0100 Subject: Makefile install target and packaging instructions (Fixes #28) --- midimonster.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 491cc11..b05326c 100644 --- a/midimonster.h +++ b/midimonster.h @@ -33,7 +33,18 @@ #include "portability.h" /* Default configuration file name to read when no other is specified */ -#define DEFAULT_CFG "monster.cfg" +#ifndef DEFAULT_CFG + #define DEFAULT_CFG "monster.cfg" +#endif + +/* Default backend plugin location */ +#ifndef PLUGINS + #ifndef _WIN32 + #define PLUGINS "./backends/" + #else + #define PLUGINS "backends\\" + #endif +#endif /* Forward declare some of the structs so we can use them in each other */ struct _channel_value; -- cgit v1.2.3 From a0831a2b970404eaa9b80ff97ab46ee759131414 Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 3 Dec 2019 22:37:45 +0100 Subject: Add error checking for shell callouts during build --- midimonster.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index b05326c..3922b03 100644 --- a/midimonster.h +++ b/midimonster.h @@ -29,6 +29,11 @@ #define DBG(message) #endif +/* 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. +#endif + /* Pull in additional defines for non-linux platforms */ #include "portability.h" -- cgit v1.2.3 From 1107a91861189d28d771d02d721d61b403aac38a Mon Sep 17 00:00:00 2001 From: cbdev Date: Wed, 4 Dec 2019 01:21:14 +0100 Subject: Explicitly mark the backend init symbol visible --- midimonster.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'midimonster.h') diff --git a/midimonster.h b/midimonster.h index 3922b03..1192d6a 100644 --- a/midimonster.h +++ b/midimonster.h @@ -5,6 +5,7 @@ #include #include +/* API call attributes and visibilities */ #ifndef MM_API #ifdef _WIN32 #define MM_API __attribute__((dllimport)) @@ -13,6 +14,15 @@ #endif #endif +/* Some build systems may apply the -fvisibility=hidden parameter from the core build to the backends, so mark the init function visible */ +#ifndef MM_PLUGIN_API + #ifdef _WIN32 + #define MM_PLUGIN_API __attribute__((dllexport)) + #else + #define MM_PLUGIN_API __attribute__((visibility ("default"))) + #endif +#endif + /* Straight-forward min / max macros */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) -- 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) --- midimonster.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'midimonster.h') 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