clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit c7136a595a513d033b4a3fdf4953898f74e8f8d4
parent 24a3df699319f3b2828e47db7313875c7ccc40b4
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Sat, 18 Dec 2021 19:10:26 +0100

work in progress

Diffstat:
Minclude/clap/all.h | 6+++++-
Ainclude/clap/converters/vst2-convert.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Rinclude/clap/ext/draft/vst3-convert.h -> include/clap/converters/vst3-convert.h | 0
Ainclude/clap/entry.h | 24++++++++++++++++++++++++
Dinclude/clap/ext/draft/thread-pool.h | 67-------------------------------------------------------------------
Dinclude/clap/ext/draft/vst2-convert.h | 47-----------------------------------------------
Ainclude/clap/ext/thread-pool.h | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/plugin-factory.h | 42++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/plugin-invalidation.h | 39+++++++++++++++++++++++++++++++++++++++
Minclude/clap/plugin.h | 62--------------------------------------------------------------
Minclude/clap/version.h | 2+-
11 files changed, 226 insertions(+), 178 deletions(-)

diff --git a/include/clap/all.h b/include/clap/all.h @@ -20,13 +20,16 @@ #include "ext/note-name.h" #include "ext/note-ports.h" #include "ext/event-filter.h" +#include "ext/thread-pool.h" #include "ext/draft/preset-load.h" #include "ext/draft/quick-controls.h" -#include "ext/draft/thread-pool.h" #include "ext/draft/track-info.h" #include "ext/draft/tuning.h" #include "ext/draft/file-reference.h" #include "ext/draft/vst2-convert.h" #include "ext/draft/vst3-convert.h" #include "ext/draft/midi-mappings.h" + +#include "converters/vst2-converter.h" +#include "converters/vst3-converter.h" +\ No newline at end of file diff --git a/include/clap/converters/vst2-convert.h b/include/clap/converters/vst2-convert.h @@ -0,0 +1,47 @@ +#pragma once + +#include "../../clap.h" +#include "../../stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_vst2_converter { + uint32_t vst2_plugin_id; + const char *vst2_plugin_name; + const char *clap_plugin_id; + + // [main-thread] + bool (*convert_state)(const struct *clap_vst2_converter *converter, const clap_istream *vst2, const clap_ostream *clap); + + // converts the vst2 param id and normalized value to clap param id and + // plain value. + // [thread-safe] + bool (*convert_normalized_value)(const struct *clap_vst2_converter *converter, + uint32_t vst2_param_id, + double vst2_normalized_value, + clap_id * clap_param_id, + double * clap_plain_value); + + // converts the vst2 param id and plain value to clap param id and + // plain value. + // [thread-safe] + bool (*convert_plain_value)(const struct *clap_vst2_converter *converter, + uint32_t vst2_param_id, + double vst2_plain_value, + clap_id * clap_param_id, + double * clap_plain_value); +} clap_vst2_converter; + +static CLAP_CONSTEXPR const char CLAP_VST2_CONVERTER_FACTORY_ID[] = "clap.vst2-converter"; + +typedef struct clap_vst2_converter_factory +{ + uint32_t (*count)(const struct clap_vst2_converter_factory *factory); + const clap_vst2_converter *(*get)(const struct clap_vst2_converter_factory *factory, uint32_t index); +} clap_vst2_converter_factory; + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/ext/draft/vst3-convert.h b/include/clap/converters/vst3-convert.h diff --git a/include/clap/entry.h b/include/clap/entry.h @@ -0,0 +1,24 @@ +#pragma once + +#include "version.h" +#include "macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_plugin_entry { + clap_version clap_version; // initialized to CLAP_VERSION + + bool (*init)(const char *plugin_path); + void (*deinit)(void); + + const void (*get_factory)(const char *factory_id); +} clap_plugin_entry; + +/* Entry point */ +CLAP_EXPORT extern const struct clap_plugin_entry clap_plugin_entry; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/draft/thread-pool.h b/include/clap/ext/draft/thread-pool.h @@ -1,66 +0,0 @@ -#pragma once - -#include "../../clap.h" - -/// @page -/// -/// This extension let the plugin use the host's thread pool. -/// -/// The plugin must provide @ref clap_plugin_thread_pool, and the host may provide @ref -/// clap_host_thread_pool. If it doesn't, the plugin should process its data by its own mean. In the -/// worst case, a single threaded for-loop. -/// -/// Simple example with N voices to process -/// -/// @code -/// void myplug_thread_pool_exec(const clap_plugin *plugin, uint32_t voice_index) -/// { -/// compute_voice(plugin, voice_index); -/// } -/// -/// void myplug_process(const clap_plugin *plugin, const clap_process *process) -/// { -/// ... -/// bool didComputeVoices = false; -/// if (host_thread_pool && host_thread_pool.exec) -/// didComputeVoices = host_thread_pool.request_exec(host, plugin, N); -/// -/// if (!didComputeVoices) -/// for (uint32_t i = 0; i < N; ++i) -/// myplug_thread_pool_exec(plugin, N); -/// ... -/// } -/// @endcode -/// -/// Be aware that using a thread pool may break hard real-time rules due to the thread -/// synchronization involved. -/// -/// If the host knows that it is running under hard real-time pressure it may decide to not -/// provide this interface. - -static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_POOL[] = "clap.thread-pool.draft/0"; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct clap_plugin_thread_pool { - // Called by the thread pool - void (*exec)(const clap_plugin *plugin, uint32_t task_index); -} clap_plugin_thread_pool; - -typedef struct clap_host_thread_pool { - // Schedule num_tasks jobs in the host thread pool. - // It can't be called concurrently or from the thread pool. - // Will block until all the tasks are processed. - // This must be used exclusively for realtime processing within the process call. - // Returns true if the host did execute all the tasks, false if it rejected the request. - // The host should check that the plugin is within the process call, and if not, reject the exec - // request. - // [audio-thread] - bool (*request_exec)(const clap_host *host, uint32_t num_tasks); -} clap_host_thread_pool; - -#ifdef __cplusplus -} -#endif -\ No newline at end of file diff --git a/include/clap/ext/draft/vst2-convert.h b/include/clap/ext/draft/vst2-convert.h @@ -1,46 +0,0 @@ -#pragma once - -#include "../../clap.h" -#include "../../stream.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_VST2_CONVERT[] = "clap.vst2-convert.draft/0"; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct clap_plugin_vst2_convert { - // Copies the name and VST2 plugin id that we can convert from. - // Returns the lenght of the name. - // [thread-safe] - int32_t (*get_vst2_plugin_id)(const clap_plugin *plugin, - uint32_t * vst2_plugin_id, - char * name, - uint32_t name_size); - - // Loads the plugin state from stream using the VST2 chunk. - // [main-thread] - bool (*restore_vst2_state)(const clap_plugin *plugin, clap_istream *stream); - - // converts the vst2 param id and normalized value to clap param id and - // plain value. - // [thread-safe] - bool (*convert_normalized_value)(const clap_plugin *plugin, - uint32_t vst2_param_id, - double vst2_normalized_value, - clap_id * clap_param_id, - double * clap_plain_value); - - // converts the vst2 param id and plain value to clap param id and - // plain value. - // [thread-safe] - bool (*convert_plain_value)(const clap_plugin *plugin, - uint32_t vst2_param_id, - double vst2_plain_value, - clap_id * clap_param_id, - double * clap_plain_value); -} clap_plugin_vst2_convert; - -#ifdef __cplusplus -} -#endif -\ No newline at end of file diff --git a/include/clap/ext/thread-pool.h b/include/clap/ext/thread-pool.h @@ -0,0 +1,66 @@ +#pragma once + +#include "../clap.h" + +/// @page +/// +/// This extension let the plugin use the host's thread pool. +/// +/// The plugin must provide @ref clap_plugin_thread_pool, and the host may provide @ref +/// clap_host_thread_pool. If it doesn't, the plugin should process its data by its own mean. In the +/// worst case, a single threaded for-loop. +/// +/// Simple example with N voices to process +/// +/// @code +/// void myplug_thread_pool_exec(const clap_plugin *plugin, uint32_t voice_index) +/// { +/// compute_voice(plugin, voice_index); +/// } +/// +/// void myplug_process(const clap_plugin *plugin, const clap_process *process) +/// { +/// ... +/// bool didComputeVoices = false; +/// if (host_thread_pool && host_thread_pool.exec) +/// didComputeVoices = host_thread_pool.request_exec(host, plugin, N); +/// +/// if (!didComputeVoices) +/// for (uint32_t i = 0; i < N; ++i) +/// myplug_thread_pool_exec(plugin, N); +/// ... +/// } +/// @endcode +/// +/// Be aware that using a thread pool may break hard real-time rules due to the thread +/// synchronization involved. +/// +/// If the host knows that it is running under hard real-time pressure it may decide to not +/// provide this interface. + +static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_POOL[] = "clap.thread-pool"; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_plugin_thread_pool { + // Called by the thread pool + void (*exec)(const clap_plugin *plugin, uint32_t task_index); +} clap_plugin_thread_pool; + +typedef struct clap_host_thread_pool { + // Schedule num_tasks jobs in the host thread pool. + // It can't be called concurrently or from the thread pool. + // Will block until all the tasks are processed. + // This must be used exclusively for realtime processing within the process call. + // Returns true if the host did execute all the tasks, false if it rejected the request. + // The host should check that the plugin is within the process call, and if not, reject the exec + // request. + // [audio-thread] + bool (*request_exec)(const clap_host *host, uint32_t num_tasks); +} clap_host_thread_pool; + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/plugin-factory.h b/include/clap/plugin-factory.h @@ -0,0 +1,41 @@ +#pragma once + +#include "plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLAP_PLUGIN_FACTORY_ID "clap.plugin-factory" + +// This interface is the entry point of the dynamic library. +// +// There is an invalidation mechanism for the set of plugins which is based on files. +// The host can watch the plugin DSO's mtime and a set of files's mtime provided by +// get_clap_invalidation_source(). +// +// The set of plugins must not change, except during a call to refresh() by the host. +// +// Every methods must be thread-safe. +struct clap_plugin_factory { + /* Get the number of plugins available. + * [thread-safe] */ + uint32_t (*get_plugin_count)(void); + + /* Retrieves a plugin descriptor by its index. + * Returns null in case of error. + * The descriptor does not need to be freed. + * [thread-safe] */ + const clap_plugin_descriptor *(*get_plugin_descriptor)(uint32_t index); + + /* Create a clap_plugin by its plugin_id. + * The returned pointer must be freed by calling plugin->destroy(plugin); + * The plugin is not allowed to use the host callbacks in the create method. + * Returns null in case of error. + * [thread-safe] */ + const clap_plugin *(*create_plugin)(const clap_host *host, const char *plugin_id); +}; + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/plugin-invalidation.h b/include/clap/plugin-invalidation.h @@ -0,0 +1,38 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLAP_PLUGIN_INVALIDATION_ID "clap.plugin-invalidation" + +typedef struct clap_plugin_invalidation_source { + // Directory containing the file(s) to scan + const char *directory; + + // globing pattern, in the form *.dll + const char *filename_glob; + + // should the directory be scanned recursively? + bool recursive_scan; +} clap_plugin_invalidation_source; + +// Used to figure out when a plugin needs to be scanned again. +// Imagine a situation with a single entry point: my-plugin.clap which then scans itself +// a set of "sub-plugins", +struct clap_plugin_invalidation { + // Get the number of invalidation source. + uint32_t (*count)(void); + + // Get the invalidation source by its index. + // [thread-safe] + const clap_plugin_invalidation_source *(*get)(uint32_t index); + + // In case the host detected a invalidation event, it can call refresh() to let the + // plugin_entry scan the set of plugins available. + void (*refresh)(void); +}; + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/plugin.h b/include/clap/plugin.h @@ -101,68 +101,6 @@ typedef struct clap_plugin { void (*on_main_thread)(const struct clap_plugin *plugin); } clap_plugin; -///////////////// -// ENTRY POINT // -///////////////// - -typedef struct clap_plugin_invalidation_source { - // Directory containing the file(s) to scan - const char *directory; - - // globing pattern, in the form *.dll - const char *filename_glob; - - // should the directory be scanned recursively? - bool recursive_scan; -} clap_plugin_invalidation_source; - -// This interface is the entry point of the dynamic library. -// -// There is an invalidation mechanism for the set of plugins which is based on files. -// The host can watch the plugin DSO's mtime and a set of files's mtime provided by -// get_clap_invalidation_source(). -// -// The set of plugins must not change, except during a call to refresh() by the host. -// -// Every methods must be thread-safe. -struct clap_plugin_entry { - clap_version clap_version; // initialized to CLAP_VERSION - - bool (*init)(const char *plugin_path); - void (*deinit)(void); - - /* Get the number of plugins available. - * [thread-safe] */ - uint32_t (*get_plugin_count)(void); - - /* Retrieves a plugin descriptor by its index. - * Returns null in case of error. - * The descriptor does not need to be freed. - * [thread-safe] */ - const clap_plugin_descriptor *(*get_plugin_descriptor)(uint32_t index); - - /* Create a clap_plugin by its plugin_id. - * The returned pointer must be freed by calling plugin->destroy(plugin); - * The plugin is not allowed to use the host callbacks in the create method. - * Returns null in case of error. - * [thread-safe] */ - const clap_plugin *(*create_plugin)(const clap_host *host, const char *plugin_id); - - // Get the number of invalidation source. - uint32_t (*get_invalidation_source_count)(void); - - // Get the invalidation source by its index. - // [thread-safe] - const clap_plugin_invalidation_source *(*get_invalidation_source)(uint32_t index); - - // In case the host detected a invalidation event, it can call refresh() to let the - // plugin_entry scan the set of plugins available. - void (*refresh)(void); -}; - -/* Entry point */ -CLAP_EXPORT extern const struct clap_plugin_entry clap_plugin_entry; - #ifdef __cplusplus } #endif diff --git a/include/clap/version.h b/include/clap/version.h @@ -23,7 +23,7 @@ typedef struct clap_version { #endif #define CLAP_VERSION_MAJOR 0 -#define CLAP_VERSION_MINOR 15 +#define CLAP_VERSION_MINOR 16 #define CLAP_VERSION_REVISION 0 #define CLAP_VERSION ((clap_version){CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION})