clap

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

commit bd62a2949498805ea371f32364fcf9f6eda96769
parent 841527300b1e3a9fce48c29425c7c2da30777095
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date:   Wed, 20 Dec 2023 11:25:43 +0100

Move extensions out of draft

Diffstat:
Minclude/clap/clap.h | 21+++++++++++----------
Ainclude/clap/ext/audio-ports-activation.h | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/configurable-audio-ports.h | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/context-menu.h | 164+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dinclude/clap/ext/draft/audio-ports-activation.h | 59-----------------------------------------------------------
Dinclude/clap/ext/draft/configurable-audio-ports.h | 57---------------------------------------------------------
Dinclude/clap/ext/draft/context-menu.h | 164-------------------------------------------------------------------------------
Dinclude/clap/ext/draft/param-indication.h | 73-------------------------------------------------------------------------
Dinclude/clap/ext/draft/preset-load.h | 49-------------------------------------------------
Dinclude/clap/ext/draft/remote-controls.h | 79-------------------------------------------------------------------------------
Dinclude/clap/ext/draft/state-context.h | 64----------------------------------------------------------------
Dinclude/clap/ext/draft/surround.h | 83-------------------------------------------------------------------------------
Dinclude/clap/ext/draft/track-info.h | 62--------------------------------------------------------------
Ainclude/clap/ext/param-indication.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/preset-load.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/remote-controls.h | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/state-context.h | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/surround.h | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/clap/ext/track-info.h | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dinclude/clap/factory/draft/preset-discovery.h | 327-------------------------------------------------------------------------------
Ainclude/clap/factory/preset-discovery.h | 327+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 files changed, 1028 insertions(+), 1027 deletions(-)

diff --git a/include/clap/clap.h b/include/clap/clap.h @@ -28,44 +28,45 @@ #include "entry.h" #include "factory/plugin-factory.h" +#include "factory/preset-discovery.h" + #include "factory/draft/plugin-invalidation.h" -#include "factory/draft/preset-discovery.h" #include "plugin.h" #include "plugin-features.h" #include "host.h" +#include "ext/audio-ports-activation.h" #include "ext/audio-ports-config.h" #include "ext/audio-ports.h" +#include "ext/configurable-audio-ports.h" +#include "ext/context-menu.h" #include "ext/event-registry.h" #include "ext/gui.h" #include "ext/latency.h" #include "ext/log.h" #include "ext/note-name.h" #include "ext/note-ports.h" +#include "ext/param-indication.h" #include "ext/params.h" #include "ext/posix-fd-support.h" +#include "ext/preset-load.h" +#include "ext/remote-controls.h" #include "ext/render.h" +#include "ext/state-context.h" #include "ext/state.h" +#include "ext/surround.h" #include "ext/tail.h" #include "ext/thread-check.h" #include "ext/thread-pool.h" #include "ext/timer-support.h" +#include "ext/track-info.h" #include "ext/voice-info.h" #include "ext/draft/ambisonic.h" -#include "ext/draft/audio-ports-activation.h" -#include "ext/draft/context-menu.h" #include "ext/draft/cv.h" #include "ext/draft/midi-mappings.h" -#include "ext/draft/param-indication.h" -#include "ext/draft/preset-load.h" -#include "ext/draft/remote-controls.h" #include "ext/draft/resource-directory.h" -#include "ext/draft/state-context.h" -#include "ext/draft/surround.h" -#include "ext/draft/track-info.h" #include "ext/draft/triggers.h" #include "ext/draft/tuning.h" -#include "ext/draft/configurable-audio-ports.h" #include "ext/draft/extensible-audio-ports.h" diff --git a/include/clap/ext/audio-ports-activation.h b/include/clap/ext/audio-ports-activation.h @@ -0,0 +1,59 @@ +#pragma once + +#include "../plugin.h" + +/// @page Audio Ports Activation +/// +/// This extension provides a way for the host to activate and de-activate audio ports. +/// Deactivating a port provides the following benefits: +/// - the plugin knows ahead of time that a given input is not present and can choose +/// an optimized computation path, +/// - the plugin knows that an output is not consumed by the host, and doesn't need to +/// compute it. +/// +/// Audio ports can only be activated or deactivated when the plugin is deactivated, unless +/// can_activate_while_processing() returns true. +/// +/// Audio buffers must still be provided if the audio port is deactivated. +/// In such case, they shall be filled with 0 (or whatever is the neutral value in your context) +/// and the constant_mask shall be set. +/// +/// Audio ports are initially in the active state after creating the plugin instance. +/// Audio ports state are not saved in the plugin state, so the host must restore the +/// audio ports state after creating the plugin instance. +/// +/// Audio ports state is invalidated by clap_plugin_audio_ports_config.select() and +/// clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_LIST). + +static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_ACTIVATION[] = + "clap.audio-ports-activation/draft-2"; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_plugin_audio_ports_activation { + // Returns true if the plugin supports activation/deactivation while processing. + // [main-thread] + bool(CLAP_ABI *can_activate_while_processing)(const clap_plugin_t *plugin); + + // Activate the given port. + // + // It is only possible to activate and de-activate on the audio-thread if + // can_activate_while_processing() returns true. + // + // sample_size indicate if the host will provide 32 bit audio buffers or 64 bits one. + // Possible values are: 32, 64 or 0 if unspecified. + // + // returns false if failed, or invalid parameters + // [active ? audio-thread : main-thread] + bool(CLAP_ABI *set_active)(const clap_plugin_t *plugin, + bool is_input, + uint32_t port_index, + bool is_active, + uint32_t sample_size); +} clap_plugin_audio_ports_activation_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/configurable-audio-ports.h b/include/clap/ext/configurable-audio-ports.h @@ -0,0 +1,57 @@ +#pragma once + +#include "audio-ports.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// This extension lets the host configure the plugin's input and output audio ports. +// This is a "push" approach to audio ports configuration. +static CLAP_CONSTEXPR const char CLAP_EXT_CONFIGURABLE_AUDIO_PORTS[] = + "clap.configurable-audio-ports.draft1"; + +typedef struct clap_audio_port_configuration_request { + // Identifies the port by is_input and port_index + bool is_input; + uint32_t port_index; + + // The requested number of channels. + uint32_t channel_count; + + // The port type, see audio-ports.h, clap_audio_port_info.port_type for interpretation. + const char *port_type; + + // cast port_details according to port_type: + // - CLAP_PORT_MONO: (discard) + // - CLAP_PORT_STEREO: (discard) + // - CLAP_PORT_SURROUND: const uint8_t *channel_map + // - CLAP_PORT_AMBISONIC: const clap_ambisonic_config_t *info + const void *port_details; +} clap_audio_port_configuration_request_t; + +typedef struct clap_plugin_configurable_audio_ports { + // Returns true if the given configurations can be applied using apply_configuration(). + // [main-thread && !active] + bool(CLAP_ABI *can_apply_configuration)( + const clap_plugin_t *plugin, + const struct clap_audio_port_configuration_request *requests, + uint32_t request_count); + + // Submit a bunch of configuration requests which will atomically be applied together, + // or discarded together. + // + // Once the configuration is successfully applied, it isn't necessary for the plugin to call + // clap_host_audio_ports->changed(); and it isn't necessary for the host to scan the + // audio ports. + // + // Returns true if applied. + // [main-thread && !active] + bool(CLAP_ABI *apply_configuration)(const clap_plugin_t *plugin, + const struct clap_audio_port_configuration_request *requests, + uint32_t request_count); +} clap_plugin_configurable_audio_ports_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/context-menu.h b/include/clap/ext/context-menu.h @@ -0,0 +1,164 @@ +#pragma once + +#include "../plugin.h" + +// This extension lets the host and plugin exchange menu items and let the plugin ask the host to +// show its context menu. + +static CLAP_CONSTEXPR const char CLAP_EXT_CONTEXT_MENU[] = "clap.context-menu.draft/0"; + +#ifdef __cplusplus +extern "C" { +#endif + +// There can be different target kind for a context menu +enum { + CLAP_CONTEXT_MENU_TARGET_KIND_GLOBAL = 0, + CLAP_CONTEXT_MENU_TARGET_KIND_PARAM = 1, + // TODO: kind trigger once the trigger ext is marked as stable +}; + +// Describes the context menu target +typedef struct clap_context_menu_target { + uint32_t kind; + clap_id id; +} clap_context_menu_target_t; + +enum { + // Adds a clickable menu entry. + // data: const clap_context_menu_item_entry_t* + CLAP_CONTEXT_MENU_ITEM_ENTRY, + + // Adds a clickable menu entry which will feature both a checkmark and a label. + // data: const clap_context_menu_item_check_entry_t* + CLAP_CONTEXT_MENU_ITEM_CHECK_ENTRY, + + // Adds a separator line. + // data: NULL + CLAP_CONTEXT_MENU_ITEM_SEPARATOR, + + // Starts a sub menu with the given label. + // data: const clap_context_menu_item_begin_submenu_t* + CLAP_CONTEXT_MENU_ITEM_BEGIN_SUBMENU, + + // Ends the current sub menu. + // data: NULL + CLAP_CONTEXT_MENU_ITEM_END_SUBMENU, + + // Adds a title entry + // data: const clap_context_menu_item_title_t * + CLAP_CONTEXT_MENU_ITEM_TITLE, +}; +typedef uint32_t clap_context_menu_item_kind_t; + +typedef struct clap_context_menu_entry { + // text to be displayed + const char *label; + + // if false, then the menu entry is greyed out and not clickable + bool is_enabled; + clap_id action_id; +} clap_context_menu_entry_t; + +typedef struct clap_context_menu_check_entry { + // text to be displayed + const char *label; + + // if false, then the menu entry is greyed out and not clickable + bool is_enabled; + + // if true, then the menu entry will be displayed as checked + bool is_checked; + clap_id action_id; +} clap_context_menu_check_entry_t; + +typedef struct clap_context_menu_item_title { + // text to be displayed + const char *title; + + // if false, then the menu entry is greyed out + bool is_enabled; +} clap_context_menu_item_title_t; + +typedef struct clap_context_menu_submenu { + // text to be displayed + const char *label; + + // if false, then the menu entry is greyed out and won't show submenu + bool is_enabled; +} clap_context_menu_submenu_t; + +// Context menu builder. +// This object isn't thread-safe and must be used on the same thread as it was provided. +typedef struct clap_context_menu_builder { + void *ctx; + + // Adds an entry to the menu. + // item_data type is determined by item_kind. + // Returns true on success. + bool(CLAP_ABI *add_item)(const struct clap_context_menu_builder *builder, + clap_context_menu_item_kind_t item_kind, + const void *item_data); + + // Returns true if the menu builder supports the given item kind + bool(CLAP_ABI *supports)(const struct clap_context_menu_builder *builder, + clap_context_menu_item_kind_t item_kind); +} clap_context_menu_builder_t; + +typedef struct clap_plugin_context_menu { + // Insert plugin's menu items into the menu builder. + // If target is null, assume global context. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *populate)(const clap_plugin_t *plugin, + const clap_context_menu_target_t *target, + const clap_context_menu_builder_t *builder); + + // Performs the given action, which was previously provided to the host via populate(). + // If target is null, assume global context. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *perform)(const clap_plugin_t *plugin, + const clap_context_menu_target_t *target, + clap_id action_id); +} clap_plugin_context_menu_t; + +typedef struct clap_host_context_menu { + // Insert host's menu items into the menu builder. + // If target is null, assume global context. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *populate)(const clap_host_t *host, + const clap_context_menu_target_t *target, + const clap_context_menu_builder_t *builder); + + // Performs the given action, which was previously provided to the plugin via populate(). + // If target is null, assume global context. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *perform)(const clap_host_t *host, + const clap_context_menu_target_t *target, + clap_id action_id); + + // Returns true if the host can display a popup menu for the plugin. + // This may depend upon the current windowing system used to display the plugin, so the + // return value is invalidated after creating the plugin window. + // [main-thread] + bool(CLAP_ABI *can_popup)(const clap_host_t *host); + + // Shows the host popup menu for a given parameter. + // If the plugin is using embedded GUI, then x and y are relative to the plugin's window, + // otherwise they're absolute coordinate, and screen index might be set accordingly. + // If target is null, assume global context. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *popup)(const clap_host_t *host, + const clap_context_menu_target_t *target, + int32_t screen_index, + int32_t x, + int32_t y); +} clap_host_context_menu_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/draft/audio-ports-activation.h b/include/clap/ext/draft/audio-ports-activation.h @@ -1,59 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -/// @page Audio Ports Activation -/// -/// This extension provides a way for the host to activate and de-activate audio ports. -/// Deactivating a port provides the following benefits: -/// - the plugin knows ahead of time that a given input is not present and can choose -/// an optimized computation path, -/// - the plugin knows that an output is not consumed by the host, and doesn't need to -/// compute it. -/// -/// Audio ports can only be activated or deactivated when the plugin is deactivated, unless -/// can_activate_while_processing() returns true. -/// -/// Audio buffers must still be provided if the audio port is deactivated. -/// In such case, they shall be filled with 0 (or whatever is the neutral value in your context) -/// and the constant_mask shall be set. -/// -/// Audio ports are initially in the active state after creating the plugin instance. -/// Audio ports state are not saved in the plugin state, so the host must restore the -/// audio ports state after creating the plugin instance. -/// -/// Audio ports state is invalidated by clap_plugin_audio_ports_config.select() and -/// clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_LIST). - -static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_ACTIVATION[] = - "clap.audio-ports-activation/draft-2"; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct clap_plugin_audio_ports_activation { - // Returns true if the plugin supports activation/deactivation while processing. - // [main-thread] - bool(CLAP_ABI *can_activate_while_processing)(const clap_plugin_t *plugin); - - // Activate the given port. - // - // It is only possible to activate and de-activate on the audio-thread if - // can_activate_while_processing() returns true. - // - // sample_size indicate if the host will provide 32 bit audio buffers or 64 bits one. - // Possible values are: 32, 64 or 0 if unspecified. - // - // returns false if failed, or invalid parameters - // [active ? audio-thread : main-thread] - bool(CLAP_ABI *set_active)(const clap_plugin_t *plugin, - bool is_input, - uint32_t port_index, - bool is_active, - uint32_t sample_size); -} clap_plugin_audio_ports_activation_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/configurable-audio-ports.h b/include/clap/ext/draft/configurable-audio-ports.h @@ -1,57 +0,0 @@ -#pragma once - -#include "../audio-ports.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// This extension lets the host configure the plugin's input and output audio ports. -// This is a "push" approach to audio ports configuration. -static CLAP_CONSTEXPR const char CLAP_EXT_CONFIGURABLE_AUDIO_PORTS[] = - "clap.configurable-audio-ports.draft1"; - -typedef struct clap_audio_port_configuration_request { - // Identifies the port by is_input and port_index - bool is_input; - uint32_t port_index; - - // The requested number of channels. - uint32_t channel_count; - - // The port type, see audio-ports.h, clap_audio_port_info.port_type for interpretation. - const char *port_type; - - // cast port_details according to port_type: - // - CLAP_PORT_MONO: (discard) - // - CLAP_PORT_STEREO: (discard) - // - CLAP_PORT_SURROUND: const uint8_t *channel_map - // - CLAP_PORT_AMBISONIC: const clap_ambisonic_config_t *info - const void *port_details; -} clap_audio_port_configuration_request_t; - -typedef struct clap_plugin_configurable_audio_ports { - // Returns true if the given configurations can be applied using apply_configuration(). - // [main-thread && !active] - bool(CLAP_ABI *can_apply_configuration)( - const clap_plugin_t *plugin, - const struct clap_audio_port_configuration_request *requests, - uint32_t request_count); - - // Submit a bunch of configuration requests which will atomically be applied together, - // or discarded together. - // - // Once the configuration is successfully applied, it isn't necessary for the plugin to call - // clap_host_audio_ports->changed(); and it isn't necessary for the host to scan the - // audio ports. - // - // Returns true if applied. - // [main-thread && !active] - bool(CLAP_ABI *apply_configuration)(const clap_plugin_t *plugin, - const struct clap_audio_port_configuration_request *requests, - uint32_t request_count); -} clap_plugin_configurable_audio_ports_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/context-menu.h b/include/clap/ext/draft/context-menu.h @@ -1,164 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -// This extension lets the host and plugin exchange menu items and let the plugin ask the host to -// show its context menu. - -static CLAP_CONSTEXPR const char CLAP_EXT_CONTEXT_MENU[] = "clap.context-menu.draft/0"; - -#ifdef __cplusplus -extern "C" { -#endif - -// There can be different target kind for a context menu -enum { - CLAP_CONTEXT_MENU_TARGET_KIND_GLOBAL = 0, - CLAP_CONTEXT_MENU_TARGET_KIND_PARAM = 1, - // TODO: kind trigger once the trigger ext is marked as stable -}; - -// Describes the context menu target -typedef struct clap_context_menu_target { - uint32_t kind; - clap_id id; -} clap_context_menu_target_t; - -enum { - // Adds a clickable menu entry. - // data: const clap_context_menu_item_entry_t* - CLAP_CONTEXT_MENU_ITEM_ENTRY, - - // Adds a clickable menu entry which will feature both a checkmark and a label. - // data: const clap_context_menu_item_check_entry_t* - CLAP_CONTEXT_MENU_ITEM_CHECK_ENTRY, - - // Adds a separator line. - // data: NULL - CLAP_CONTEXT_MENU_ITEM_SEPARATOR, - - // Starts a sub menu with the given label. - // data: const clap_context_menu_item_begin_submenu_t* - CLAP_CONTEXT_MENU_ITEM_BEGIN_SUBMENU, - - // Ends the current sub menu. - // data: NULL - CLAP_CONTEXT_MENU_ITEM_END_SUBMENU, - - // Adds a title entry - // data: const clap_context_menu_item_title_t * - CLAP_CONTEXT_MENU_ITEM_TITLE, -}; -typedef uint32_t clap_context_menu_item_kind_t; - -typedef struct clap_context_menu_entry { - // text to be displayed - const char *label; - - // if false, then the menu entry is greyed out and not clickable - bool is_enabled; - clap_id action_id; -} clap_context_menu_entry_t; - -typedef struct clap_context_menu_check_entry { - // text to be displayed - const char *label; - - // if false, then the menu entry is greyed out and not clickable - bool is_enabled; - - // if true, then the menu entry will be displayed as checked - bool is_checked; - clap_id action_id; -} clap_context_menu_check_entry_t; - -typedef struct clap_context_menu_item_title { - // text to be displayed - const char *title; - - // if false, then the menu entry is greyed out - bool is_enabled; -} clap_context_menu_item_title_t; - -typedef struct clap_context_menu_submenu { - // text to be displayed - const char *label; - - // if false, then the menu entry is greyed out and won't show submenu - bool is_enabled; -} clap_context_menu_submenu_t; - -// Context menu builder. -// This object isn't thread-safe and must be used on the same thread as it was provided. -typedef struct clap_context_menu_builder { - void *ctx; - - // Adds an entry to the menu. - // item_data type is determined by item_kind. - // Returns true on success. - bool(CLAP_ABI *add_item)(const struct clap_context_menu_builder *builder, - clap_context_menu_item_kind_t item_kind, - const void *item_data); - - // Returns true if the menu builder supports the given item kind - bool(CLAP_ABI *supports)(const struct clap_context_menu_builder *builder, - clap_context_menu_item_kind_t item_kind); -} clap_context_menu_builder_t; - -typedef struct clap_plugin_context_menu { - // Insert plugin's menu items into the menu builder. - // If target is null, assume global context. - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *populate)(const clap_plugin_t *plugin, - const clap_context_menu_target_t *target, - const clap_context_menu_builder_t *builder); - - // Performs the given action, which was previously provided to the host via populate(). - // If target is null, assume global context. - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *perform)(const clap_plugin_t *plugin, - const clap_context_menu_target_t *target, - clap_id action_id); -} clap_plugin_context_menu_t; - -typedef struct clap_host_context_menu { - // Insert host's menu items into the menu builder. - // If target is null, assume global context. - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *populate)(const clap_host_t *host, - const clap_context_menu_target_t *target, - const clap_context_menu_builder_t *builder); - - // Performs the given action, which was previously provided to the plugin via populate(). - // If target is null, assume global context. - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *perform)(const clap_host_t *host, - const clap_context_menu_target_t *target, - clap_id action_id); - - // Returns true if the host can display a popup menu for the plugin. - // This may depend upon the current windowing system used to display the plugin, so the - // return value is invalidated after creating the plugin window. - // [main-thread] - bool(CLAP_ABI *can_popup)(const clap_host_t *host); - - // Shows the host popup menu for a given parameter. - // If the plugin is using embedded GUI, then x and y are relative to the plugin's window, - // otherwise they're absolute coordinate, and screen index might be set accordingly. - // If target is null, assume global context. - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *popup)(const clap_host_t *host, - const clap_context_menu_target_t *target, - int32_t screen_index, - int32_t x, - int32_t y); -} clap_host_context_menu_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/param-indication.h b/include/clap/ext/draft/param-indication.h @@ -1,73 +0,0 @@ -#pragma once - -#include "../params.h" -#include "../../color.h" - -// This extension lets the host tell the plugin to display a little color based indication on the -// parameter. This can be used to indicate: -// - a physical controller is mapped to a parameter -// - the parameter is current playing an automation -// - the parameter is overriding the automation -// - etc... -// -// The color semantic depends upon the host here and the goal is to have a consistent experience -// across all plugins. - -static CLAP_CONSTEXPR const char CLAP_EXT_PARAM_INDICATION[] = "clap.param-indication.draft/4"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - // The host doesn't have an automation for this parameter - CLAP_PARAM_INDICATION_AUTOMATION_NONE = 0, - - // The host has an automation for this parameter, but it isn't playing it - CLAP_PARAM_INDICATION_AUTOMATION_PRESENT = 1, - - // The host is playing an automation for this parameter - CLAP_PARAM_INDICATION_AUTOMATION_PLAYING = 2, - - // The host is recording an automation on this parameter - CLAP_PARAM_INDICATION_AUTOMATION_RECORDING = 3, - - // The host should play an automation for this parameter, but the user has started to adjust this - // parameter and is overriding the automation playback - CLAP_PARAM_INDICATION_AUTOMATION_OVERRIDING = 4, -}; - -typedef struct clap_plugin_param_indication { - // Sets or clears a mapping indication. - // - // has_mapping: does the parameter currently has a mapping? - // color: if set, the color to use to highlight the control in the plugin GUI - // label: if set, a small string to display on top of the knob which identifies the hardware - // controller description: if set, a string which can be used in a tooltip, which describes the - // current mapping - // - // Parameter indications should not be saved in the plugin context, and are off by default. - // [main-thread] - void(CLAP_ABI *set_mapping)(const clap_plugin_t *plugin, - clap_id param_id, - bool has_mapping, - const clap_color_t *color, - const char *label, - const char *description); - - // Sets or clears an automation indication. - // - // automation_state: current automation state for the given parameter - // color: if set, the color to use to display the automation indication in the plugin GUI - // - // Parameter indications should not be saved in the plugin context, and are off by default. - // [main-thread] - void(CLAP_ABI *set_automation)(const clap_plugin_t *plugin, - clap_id param_id, - uint32_t automation_state, - const clap_color_t *color); -} clap_plugin_param_indication_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/preset-load.h b/include/clap/ext/draft/preset-load.h @@ -1,49 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -static const char CLAP_EXT_PRESET_LOAD[] = "clap.preset-load.draft/2"; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct clap_plugin_preset_load { - // Loads a preset in the plugin native preset file format from a location. - // The preset discovery provider defines the location and load_key to be passed to this function. - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *from_location)(const clap_plugin_t *plugin, - uint32_t location_kind, - const char *location, - const char *load_key); -} clap_plugin_preset_load_t; - -typedef struct clap_host_preset_load { - // Called if clap_plugin_preset_load.load() failed. - // os_error: the operating system error, if applicable. If not applicable set it to a non-error - // value, eg: 0 on unix and Windows. - // - // [main-thread] - void(CLAP_ABI *on_error)(const clap_host_t *host, - uint32_t location_kind, - const char *location, - const char *load_key, - int32_t os_error, - const char *msg); - - // Informs the host that the following preset has been loaded. - // This contributes to keep in sync the host preset browser and plugin preset browser. - // If the preset was loaded from a container file, then the load_key must be set, otherwise it - // must be null. - // - // [main-thread] - void(CLAP_ABI *loaded)(const clap_host_t *host, - uint32_t location_kind, - const char *location, - const char *load_key); -} clap_host_preset_load_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/remote-controls.h b/include/clap/ext/draft/remote-controls.h @@ -1,79 +0,0 @@ -#pragma once - -#include "../../plugin.h" -#include "../../string-sizes.h" - -// This extension let the plugin provide a structured way of mapping parameters to an hardware -// controller. -// -// This is done by providing a set of remote control pages organized by section. -// A page contains up to 8 controls, which references parameters using param_id. -// -// |`- [section:main] -// | `- [name:main] performance controls -// |`- [section:osc] -// | |`- [name:osc1] osc1 page -// | |`- [name:osc2] osc2 page -// | |`- [name:osc-sync] osc sync page -// | `- [name:osc-noise] osc noise page -// |`- [section:filter] -// | |`- [name:flt1] filter 1 page -// | `- [name:flt2] filter 2 page -// |`- [section:env] -// | |`- [name:env1] env1 page -// | `- [name:env2] env2 page -// |`- [section:lfo] -// | |`- [name:lfo1] env1 page -// | `- [name:lfo2] env2 page -// `- etc... -// -// One possible workflow is to have a set of buttons, which correspond to a section. -// Pressing that button once gets you to the first page of the section. -// Press it again to cycle through the section's pages. - -static CLAP_CONSTEXPR const char CLAP_EXT_REMOTE_CONTROLS[] = "clap.remote-controls.draft/2"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum { CLAP_REMOTE_CONTROLS_COUNT = 8 }; - -typedef struct clap_remote_controls_page { - char section_name[CLAP_NAME_SIZE]; - clap_id page_id; - char page_name[CLAP_NAME_SIZE]; - clap_id param_ids[CLAP_REMOTE_CONTROLS_COUNT]; - - // This is used to separate device pages versus preset pages. - // If true, then this page is specific to this preset. - bool is_for_preset; -} clap_remote_controls_page_t; - -typedef struct clap_plugin_remote_controls { - // Returns the number of pages. - // [main-thread] - uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); - - // Get a page by index. - // Returns true on success and stores the result into page. - // [main-thread] - bool(CLAP_ABI *get)(const clap_plugin_t *plugin, - uint32_t page_index, - clap_remote_controls_page_t *page); -} clap_plugin_remote_controls_t; - -typedef struct clap_host_remote_controls { - // Informs the host that the remote controls have changed. - // [main-thread] - void(CLAP_ABI *changed)(const clap_host_t *host); - - // Suggest a page to the host because it corresponds to what the user is currently editing in the - // plugin's GUI. - // [main-thread] - void(CLAP_ABI *suggest_page)(const clap_host_t *host, clap_id page_id); -} clap_host_remote_controls_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/state-context.h b/include/clap/ext/draft/state-context.h @@ -1,64 +0,0 @@ -#pragma once - -#include "../../plugin.h" -#include "../../stream.h" - -/// @page state-context extension -/// @brief extended state handling -/// -/// This extension lets the host save and load the plugin state with different semantics depending -/// on the context. -/// -/// Briefly, when loading a preset or duplicating a device, the plugin may want to partially load -/// the state and initialize certain things differently. -/// -/// Save and Load operations may have a different context. -/// All three operations should be equivalent: -/// 1. clap_plugin_state_context.load(clap_plugin_state.save(), CLAP_STATE_CONTEXT_FOR_PRESET) -/// 2. clap_plugin_state.load(clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET)) -/// 3. clap_plugin_state_context.load( -/// clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET), -/// CLAP_STATE_CONTEXT_FOR_PRESET) -/// -/// If the plugin implements CLAP_EXT_STATE_CONTEXT then it is mandatory to also implement -/// CLAP_EXT_STATE. - -#ifdef __cplusplus -extern "C" { -#endif - -static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context.draft/1"; - -enum clap_plugin_state_context_type { - // suitable for duplicating a plugin instance - CLAP_STATE_CONTEXT_FOR_DUPLICATE = 1, - - // suitable for loading a state as a preset - CLAP_STATE_CONTEXT_FOR_PRESET = 2, -}; - -typedef struct clap_plugin_state_context { - // Saves the plugin state into stream, according to context_type. - // Returns true if the state was correctly saved. - // - // Note that the result may be loaded by both clap_plugin_state.load() and - // clap_plugin_state_context.load(). - // [main-thread] - bool(CLAP_ABI *save)(const clap_plugin_t *plugin, - const clap_ostream_t *stream, - uint32_t context_type); - - // Loads the plugin state from stream, according to context_type. - // Returns true if the state was correctly restored. - // - // Note that the state may have been saved by clap_plugin_state.save() or - // clap_plugin_state_context.save() with a different context_type. - // [main-thread] - bool(CLAP_ABI *load)(const clap_plugin_t *plugin, - const clap_istream_t *stream, - uint32_t context_type); -} clap_plugin_state_context_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/surround.h b/include/clap/ext/draft/surround.h @@ -1,83 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -// This extension can be used to specify the channel mapping used by the plugin. -// -// To have consistent surround features across all the plugin instances, -// here is the proposed workflow: -// 1. the plugin queries the host preferred channel mapping and -// adjusts its configuration to match it. -// 2. the host checks how the plugin is effectively configured and honors it. -// -// If the host decides to change the project's surround setup: -// 1. deactivate the plugin -// 2. host calls clap_plugin_surround->changed() -// 3. plugin calls clap_host_surround->get_preferred_channel_map() -// 4. plugin eventually calls clap_host_surround->changed() -// 5. host calls clap_plugin_surround->get_channel_map() if changed -// 6. host activates the plugin and can start processing audio -// -// If the plugin wants to change its surround setup: -// 1. call host->request_restart() if the plugin is active -// 2. once deactivated plugin calls clap_host_surround->changed() -// 3. host calls clap_plugin_surround->get_channel_map() -// 4. host activates the plugin and can start processing audio - -static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND[] = "clap.surround.draft/4"; - -static CLAP_CONSTEXPR const char CLAP_PORT_SURROUND[] = "surround"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - CLAP_SURROUND_FL = 0, // Front Left - CLAP_SURROUND_FR = 1, // Front Right - CLAP_SURROUND_FC = 2, // Front Center - CLAP_SURROUND_LFE = 3, // Low Frequency - CLAP_SURROUND_BL = 4, // Back Left - CLAP_SURROUND_BR = 5, // Back Right - CLAP_SURROUND_FLC = 6, // Front Left of Center - CLAP_SURROUND_FRC = 7, // Front Right of Center - CLAP_SURROUND_BC = 8, // Back Center - CLAP_SURROUND_SL = 9, // Side Left - CLAP_SURROUND_SR = 10, // Side Right - CLAP_SURROUND_TC = 11, // Top Center - CLAP_SURROUND_TFL = 12, // Front Left Height - CLAP_SURROUND_TFC = 13, // Front Center Height - CLAP_SURROUND_TFR = 14, // Front Right Height - CLAP_SURROUND_TBL = 15, // Rear Left Height - CLAP_SURROUND_TBC = 16, // Rear Center Height - CLAP_SURROUND_TBR = 17, // Rear Right Height -}; - -typedef struct clap_plugin_surround { - // Checks if a given channel mask is supported. - // The channel mask is a bitmask, for example: - // (1 << CLAP_SURROUND_FL) | (1 << CLAP_SURROUND_FR) | ... - // [main-thread] - bool(CLAP_ABI *is_channel_mask_supported)(const clap_plugin_t *plugin, uint64_t channel_mask); - - // Stores the surround identifier of each channel into the channel_map array. - // Returns the number of elements stored in channel_map. - // channel_map_capacity must be greater or equal to the channel count of the given port. - // [main-thread] - uint32_t(CLAP_ABI *get_channel_map)(const clap_plugin_t *plugin, - bool is_input, - uint32_t port_index, - uint8_t *channel_map, - uint32_t channel_map_capacity); -} clap_plugin_surround_t; - -typedef struct clap_host_surround { - // Informs the host that the channel map has changed. - // The channel map can only change when the plugin is de-activated. - // [main-thread] - void(CLAP_ABI *changed)(const clap_host_t *host); -} clap_host_surround_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/track-info.h b/include/clap/ext/draft/track-info.h @@ -1,62 +0,0 @@ -#pragma once - -#include "../../plugin.h" -#include "../../color.h" -#include "../../string-sizes.h" - -// This extension let the plugin query info about the track it's in. -// It is useful when the plugin is created, to initialize some parameters (mix, dry, wet) -// and pick a suitable configuration regarding audio port type and channel count. - -static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO[] = "clap.track-info.draft/1"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - CLAP_TRACK_INFO_HAS_TRACK_NAME = (1 << 0), - CLAP_TRACK_INFO_HAS_TRACK_COLOR = (1 << 1), - CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL = (1 << 2), - - // This plugin is on a return track, initialize with wet 100% - CLAP_TRACK_INFO_IS_FOR_RETURN_TRACK = (1 << 3), - - // This plugin is on a bus track, initialize with appropriate settings for bus processing - CLAP_TRACK_INFO_IS_FOR_BUS = (1 << 4), - - // This plugin is on the master, initialize with appropriate settings for channel processing - CLAP_TRACK_INFO_IS_FOR_MASTER = (1 << 5), -}; - -typedef struct clap_track_info { - uint64_t flags; // see the flags above - - // track name, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_NAME - char name[CLAP_NAME_SIZE]; - - // track color, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_COLOR - clap_color_t color; - - // available if flags contain CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL - // see audio-ports.h, struct clap_audio_port_info to learn how to use channel count and port type - int32_t audio_channel_count; - const char *audio_port_type; -} clap_track_info_t; - -typedef struct clap_plugin_track_info { - // Called when the info changes. - // [main-thread] - void(CLAP_ABI *changed)(const clap_plugin_t *plugin); -} clap_plugin_track_info_t; - -typedef struct clap_host_track_info { - // Get info about the track the plugin belongs to. - // Returns true on success and stores the result into info. - // [main-thread] - bool(CLAP_ABI *get)(const clap_host_t *host, clap_track_info_t *info); -} clap_host_track_info_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/param-indication.h b/include/clap/ext/param-indication.h @@ -0,0 +1,73 @@ +#pragma once + +#include "params.h" +#include "../color.h" + +// This extension lets the host tell the plugin to display a little color based indication on the +// parameter. This can be used to indicate: +// - a physical controller is mapped to a parameter +// - the parameter is current playing an automation +// - the parameter is overriding the automation +// - etc... +// +// The color semantic depends upon the host here and the goal is to have a consistent experience +// across all plugins. + +static CLAP_CONSTEXPR const char CLAP_EXT_PARAM_INDICATION[] = "clap.param-indication.draft/4"; + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + // The host doesn't have an automation for this parameter + CLAP_PARAM_INDICATION_AUTOMATION_NONE = 0, + + // The host has an automation for this parameter, but it isn't playing it + CLAP_PARAM_INDICATION_AUTOMATION_PRESENT = 1, + + // The host is playing an automation for this parameter + CLAP_PARAM_INDICATION_AUTOMATION_PLAYING = 2, + + // The host is recording an automation on this parameter + CLAP_PARAM_INDICATION_AUTOMATION_RECORDING = 3, + + // The host should play an automation for this parameter, but the user has started to adjust this + // parameter and is overriding the automation playback + CLAP_PARAM_INDICATION_AUTOMATION_OVERRIDING = 4, +}; + +typedef struct clap_plugin_param_indication { + // Sets or clears a mapping indication. + // + // has_mapping: does the parameter currently has a mapping? + // color: if set, the color to use to highlight the control in the plugin GUI + // label: if set, a small string to display on top of the knob which identifies the hardware + // controller description: if set, a string which can be used in a tooltip, which describes the + // current mapping + // + // Parameter indications should not be saved in the plugin context, and are off by default. + // [main-thread] + void(CLAP_ABI *set_mapping)(const clap_plugin_t *plugin, + clap_id param_id, + bool has_mapping, + const clap_color_t *color, + const char *label, + const char *description); + + // Sets or clears an automation indication. + // + // automation_state: current automation state for the given parameter + // color: if set, the color to use to display the automation indication in the plugin GUI + // + // Parameter indications should not be saved in the plugin context, and are off by default. + // [main-thread] + void(CLAP_ABI *set_automation)(const clap_plugin_t *plugin, + clap_id param_id, + uint32_t automation_state, + const clap_color_t *color); +} clap_plugin_param_indication_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/preset-load.h b/include/clap/ext/preset-load.h @@ -0,0 +1,49 @@ +#pragma once + +#include "../plugin.h" + +static const char CLAP_EXT_PRESET_LOAD[] = "clap.preset-load.draft/2"; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_plugin_preset_load { + // Loads a preset in the plugin native preset file format from a location. + // The preset discovery provider defines the location and load_key to be passed to this function. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *from_location)(const clap_plugin_t *plugin, + uint32_t location_kind, + const char *location, + const char *load_key); +} clap_plugin_preset_load_t; + +typedef struct clap_host_preset_load { + // Called if clap_plugin_preset_load.load() failed. + // os_error: the operating system error, if applicable. If not applicable set it to a non-error + // value, eg: 0 on unix and Windows. + // + // [main-thread] + void(CLAP_ABI *on_error)(const clap_host_t *host, + uint32_t location_kind, + const char *location, + const char *load_key, + int32_t os_error, + const char *msg); + + // Informs the host that the following preset has been loaded. + // This contributes to keep in sync the host preset browser and plugin preset browser. + // If the preset was loaded from a container file, then the load_key must be set, otherwise it + // must be null. + // + // [main-thread] + void(CLAP_ABI *loaded)(const clap_host_t *host, + uint32_t location_kind, + const char *location, + const char *load_key); +} clap_host_preset_load_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/remote-controls.h b/include/clap/ext/remote-controls.h @@ -0,0 +1,79 @@ +#pragma once + +#include "../plugin.h" +#include "../string-sizes.h" + +// This extension let the plugin provide a structured way of mapping parameters to an hardware +// controller. +// +// This is done by providing a set of remote control pages organized by section. +// A page contains up to 8 controls, which references parameters using param_id. +// +// |`- [section:main] +// | `- [name:main] performance controls +// |`- [section:osc] +// | |`- [name:osc1] osc1 page +// | |`- [name:osc2] osc2 page +// | |`- [name:osc-sync] osc sync page +// | `- [name:osc-noise] osc noise page +// |`- [section:filter] +// | |`- [name:flt1] filter 1 page +// | `- [name:flt2] filter 2 page +// |`- [section:env] +// | |`- [name:env1] env1 page +// | `- [name:env2] env2 page +// |`- [section:lfo] +// | |`- [name:lfo1] env1 page +// | `- [name:lfo2] env2 page +// `- etc... +// +// One possible workflow is to have a set of buttons, which correspond to a section. +// Pressing that button once gets you to the first page of the section. +// Press it again to cycle through the section's pages. + +static CLAP_CONSTEXPR const char CLAP_EXT_REMOTE_CONTROLS[] = "clap.remote-controls.draft/2"; + +#ifdef __cplusplus +extern "C" { +#endif + +enum { CLAP_REMOTE_CONTROLS_COUNT = 8 }; + +typedef struct clap_remote_controls_page { + char section_name[CLAP_NAME_SIZE]; + clap_id page_id; + char page_name[CLAP_NAME_SIZE]; + clap_id param_ids[CLAP_REMOTE_CONTROLS_COUNT]; + + // This is used to separate device pages versus preset pages. + // If true, then this page is specific to this preset. + bool is_for_preset; +} clap_remote_controls_page_t; + +typedef struct clap_plugin_remote_controls { + // Returns the number of pages. + // [main-thread] + uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); + + // Get a page by index. + // Returns true on success and stores the result into page. + // [main-thread] + bool(CLAP_ABI *get)(const clap_plugin_t *plugin, + uint32_t page_index, + clap_remote_controls_page_t *page); +} clap_plugin_remote_controls_t; + +typedef struct clap_host_remote_controls { + // Informs the host that the remote controls have changed. + // [main-thread] + void(CLAP_ABI *changed)(const clap_host_t *host); + + // Suggest a page to the host because it corresponds to what the user is currently editing in the + // plugin's GUI. + // [main-thread] + void(CLAP_ABI *suggest_page)(const clap_host_t *host, clap_id page_id); +} clap_host_remote_controls_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/state-context.h b/include/clap/ext/state-context.h @@ -0,0 +1,64 @@ +#pragma once + +#include "../plugin.h" +#include "../stream.h" + +/// @page state-context extension +/// @brief extended state handling +/// +/// This extension lets the host save and load the plugin state with different semantics depending +/// on the context. +/// +/// Briefly, when loading a preset or duplicating a device, the plugin may want to partially load +/// the state and initialize certain things differently. +/// +/// Save and Load operations may have a different context. +/// All three operations should be equivalent: +/// 1. clap_plugin_state_context.load(clap_plugin_state.save(), CLAP_STATE_CONTEXT_FOR_PRESET) +/// 2. clap_plugin_state.load(clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET)) +/// 3. clap_plugin_state_context.load( +/// clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET), +/// CLAP_STATE_CONTEXT_FOR_PRESET) +/// +/// If the plugin implements CLAP_EXT_STATE_CONTEXT then it is mandatory to also implement +/// CLAP_EXT_STATE. + +#ifdef __cplusplus +extern "C" { +#endif + +static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context.draft/1"; + +enum clap_plugin_state_context_type { + // suitable for duplicating a plugin instance + CLAP_STATE_CONTEXT_FOR_DUPLICATE = 1, + + // suitable for loading a state as a preset + CLAP_STATE_CONTEXT_FOR_PRESET = 2, +}; + +typedef struct clap_plugin_state_context { + // Saves the plugin state into stream, according to context_type. + // Returns true if the state was correctly saved. + // + // Note that the result may be loaded by both clap_plugin_state.load() and + // clap_plugin_state_context.load(). + // [main-thread] + bool(CLAP_ABI *save)(const clap_plugin_t *plugin, + const clap_ostream_t *stream, + uint32_t context_type); + + // Loads the plugin state from stream, according to context_type. + // Returns true if the state was correctly restored. + // + // Note that the state may have been saved by clap_plugin_state.save() or + // clap_plugin_state_context.save() with a different context_type. + // [main-thread] + bool(CLAP_ABI *load)(const clap_plugin_t *plugin, + const clap_istream_t *stream, + uint32_t context_type); +} clap_plugin_state_context_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/surround.h b/include/clap/ext/surround.h @@ -0,0 +1,83 @@ +#pragma once + +#include "../plugin.h" + +// This extension can be used to specify the channel mapping used by the plugin. +// +// To have consistent surround features across all the plugin instances, +// here is the proposed workflow: +// 1. the plugin queries the host preferred channel mapping and +// adjusts its configuration to match it. +// 2. the host checks how the plugin is effectively configured and honors it. +// +// If the host decides to change the project's surround setup: +// 1. deactivate the plugin +// 2. host calls clap_plugin_surround->changed() +// 3. plugin calls clap_host_surround->get_preferred_channel_map() +// 4. plugin eventually calls clap_host_surround->changed() +// 5. host calls clap_plugin_surround->get_channel_map() if changed +// 6. host activates the plugin and can start processing audio +// +// If the plugin wants to change its surround setup: +// 1. call host->request_restart() if the plugin is active +// 2. once deactivated plugin calls clap_host_surround->changed() +// 3. host calls clap_plugin_surround->get_channel_map() +// 4. host activates the plugin and can start processing audio + +static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND[] = "clap.surround.draft/4"; + +static CLAP_CONSTEXPR const char CLAP_PORT_SURROUND[] = "surround"; + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + CLAP_SURROUND_FL = 0, // Front Left + CLAP_SURROUND_FR = 1, // Front Right + CLAP_SURROUND_FC = 2, // Front Center + CLAP_SURROUND_LFE = 3, // Low Frequency + CLAP_SURROUND_BL = 4, // Back Left + CLAP_SURROUND_BR = 5, // Back Right + CLAP_SURROUND_FLC = 6, // Front Left of Center + CLAP_SURROUND_FRC = 7, // Front Right of Center + CLAP_SURROUND_BC = 8, // Back Center + CLAP_SURROUND_SL = 9, // Side Left + CLAP_SURROUND_SR = 10, // Side Right + CLAP_SURROUND_TC = 11, // Top Center + CLAP_SURROUND_TFL = 12, // Front Left Height + CLAP_SURROUND_TFC = 13, // Front Center Height + CLAP_SURROUND_TFR = 14, // Front Right Height + CLAP_SURROUND_TBL = 15, // Rear Left Height + CLAP_SURROUND_TBC = 16, // Rear Center Height + CLAP_SURROUND_TBR = 17, // Rear Right Height +}; + +typedef struct clap_plugin_surround { + // Checks if a given channel mask is supported. + // The channel mask is a bitmask, for example: + // (1 << CLAP_SURROUND_FL) | (1 << CLAP_SURROUND_FR) | ... + // [main-thread] + bool(CLAP_ABI *is_channel_mask_supported)(const clap_plugin_t *plugin, uint64_t channel_mask); + + // Stores the surround identifier of each channel into the channel_map array. + // Returns the number of elements stored in channel_map. + // channel_map_capacity must be greater or equal to the channel count of the given port. + // [main-thread] + uint32_t(CLAP_ABI *get_channel_map)(const clap_plugin_t *plugin, + bool is_input, + uint32_t port_index, + uint8_t *channel_map, + uint32_t channel_map_capacity); +} clap_plugin_surround_t; + +typedef struct clap_host_surround { + // Informs the host that the channel map has changed. + // The channel map can only change when the plugin is de-activated. + // [main-thread] + void(CLAP_ABI *changed)(const clap_host_t *host); +} clap_host_surround_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/track-info.h b/include/clap/ext/track-info.h @@ -0,0 +1,62 @@ +#pragma once + +#include "../plugin.h" +#include "../color.h" +#include "../string-sizes.h" + +// This extension let the plugin query info about the track it's in. +// It is useful when the plugin is created, to initialize some parameters (mix, dry, wet) +// and pick a suitable configuration regarding audio port type and channel count. + +static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO[] = "clap.track-info.draft/1"; + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + CLAP_TRACK_INFO_HAS_TRACK_NAME = (1 << 0), + CLAP_TRACK_INFO_HAS_TRACK_COLOR = (1 << 1), + CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL = (1 << 2), + + // This plugin is on a return track, initialize with wet 100% + CLAP_TRACK_INFO_IS_FOR_RETURN_TRACK = (1 << 3), + + // This plugin is on a bus track, initialize with appropriate settings for bus processing + CLAP_TRACK_INFO_IS_FOR_BUS = (1 << 4), + + // This plugin is on the master, initialize with appropriate settings for channel processing + CLAP_TRACK_INFO_IS_FOR_MASTER = (1 << 5), +}; + +typedef struct clap_track_info { + uint64_t flags; // see the flags above + + // track name, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_NAME + char name[CLAP_NAME_SIZE]; + + // track color, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_COLOR + clap_color_t color; + + // available if flags contain CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL + // see audio-ports.h, struct clap_audio_port_info to learn how to use channel count and port type + int32_t audio_channel_count; + const char *audio_port_type; +} clap_track_info_t; + +typedef struct clap_plugin_track_info { + // Called when the info changes. + // [main-thread] + void(CLAP_ABI *changed)(const clap_plugin_t *plugin); +} clap_plugin_track_info_t; + +typedef struct clap_host_track_info { + // Get info about the track the plugin belongs to. + // Returns true on success and stores the result into info. + // [main-thread] + bool(CLAP_ABI *get)(const clap_host_t *host, clap_track_info_t *info); +} clap_host_track_info_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/factory/draft/preset-discovery.h b/include/clap/factory/draft/preset-discovery.h @@ -1,327 +0,0 @@ -/* - Preset Discovery API. - - Preset Discovery enables a plug-in host to identify where presets are found, what - extensions they have, which plug-ins they apply to, and other metadata associated with the - presets so that they can be indexed and searched for quickly within the plug-in host's browser. - - This has a number of advantages for the user: - - it allows them to browse for presets from one central location in a consistent way - - the user can browse for presets without having to commit to a particular plug-in first - - The API works as follow to index presets and presets metadata: - 1. clap_plugin_entry.get_factory(CLAP_PRESET_DISCOVERY_FACTORY_ID) - 2. clap_preset_discovery_factory_t.create(...) - 3. clap_preset_discovery_provider.init() (only necessary the first time, declarations - can be cached) - `-> clap_preset_discovery_indexer.declare_filetype() - `-> clap_preset_discovery_indexer.declare_location() - `-> clap_preset_discovery_indexer.declare_soundpack() (optional) - `-> clap_preset_discovery_indexer.set_invalidation_watch_file() (optional) - 4. crawl the given locations and monitor file system changes - `-> clap_preset_discovery_indexer.get_metadata() for each presets files - - Then to load a preset, use ext/draft/preset-load.h. - TODO: create a dedicated repo for other plugin abi preset-load extension. - - The design of this API deliberately does not define a fixed set tags or categories. It is the - plug-in host's job to try to intelligently map the raw list of features that are found for a - preset and to process this list to generate something that makes sense for the host's tagging and - categorization system. The reason for this is to reduce the work for a plug-in developer to add - Preset Discovery support for their existing preset file format and not have to be concerned with - all the different hosts and how they want to receive the metadata. - - VERY IMPORTANT: - - the whole indexing process has to be **fast** - - clap_preset_provider->get_metadata() has to be fast and avoid unnecessary operations - - the whole indexing process must not be interactive - - don't show dialogs, windows, ... - - don't ask for user input -*/ - -#pragma once - -#include "../../private/std.h" -#include "../../private/macros.h" -#include "../../version.h" - -// Use it to retrieve const clap_preset_discovery_factory_t* from -// clap_plugin_entry.get_factory() -static const CLAP_CONSTEXPR char CLAP_PRESET_DISCOVERY_FACTORY_ID[] = - "clap.preset-discovery-factory/draft-2"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum clap_preset_discovery_location_kind { - // The preset are located in a file on the OS filesystem. - // The location is then a path which works with the OS file system functions (open, stat, ...) - // So both '/' and '\' shall work on Windows as a separator. - CLAP_PRESET_DISCOVERY_LOCATION_FILE = 0, - - // The preset is bundled within the plugin DSO itself. - // The location must then be null, as the preset are within the plugin itself and then the plugin - // will act as a preset container. - CLAP_PRESET_DISCOVERY_LOCATION_PLUGIN = 1, -}; - -enum clap_preset_discovery_flags { - // This is for factory or sound-pack presets. - CLAP_PRESET_DISCOVERY_IS_FACTORY_CONTENT = 1 << 0, - - // This is for user presets. - CLAP_PRESET_DISCOVERY_IS_USER_CONTENT = 1 << 1, - - // This location is meant for demo presets, those are preset which may trigger - // some limitation in the plugin because they require additional features which the user - // needs to purchase or the content itself needs to be bought and is only available in - // demo mode. - CLAP_PRESET_DISCOVERY_IS_DEMO_CONTENT = 1 << 2, - - // This preset is a user's favorite - CLAP_PRESET_DISCOVERY_IS_FAVORITE = 1 << 3, -}; - -// TODO: move clap_timestamp_t, CLAP_TIMESTAMP_UNKNOWN and clap_plugin_id_t to parent files once we -// settle with preset discovery - -// This type defines a timestamp: the number of seconds since UNIX EPOCH. -// See C's time_t time(time_t *). -typedef uint64_t clap_timestamp_t; - -// Value for unknown timestamp. -static const clap_timestamp_t CLAP_TIMESTAMP_UNKNOWN = 0; - -// Pair of plugin ABI and plugin identifier -typedef struct clap_plugin_id { - // The plugin ABI name, in lowercase. - // eg: "clap" - const char *abi; - - // The plugin ID, for example "com.u-he.Diva". - // If the ABI rely upon binary plugin ids, then they shall be hex encoded (lower case). - const char *id; -} clap_plugin_id_t; - -// Receiver that receives the metadata for a single preset file. -// The host would define the various callbacks in this interface and the preset parser function -// would then call them. -// -// This interface isn't thread-safe. -typedef struct clap_preset_discovery_metadata_receiver { - void *receiver_data; // reserved pointer for the metadata receiver - - // If there is an error reading metadata from a file this should be called with an error - // message. - // os_error: the operating system error, if applicable. If not applicable set it to a non-error - // value, eg: 0 on unix and Windows. - void(CLAP_ABI *on_error)(const struct clap_preset_discovery_metadata_receiver *receiver, - int32_t os_error, - const char *error_message); - - // This must be called for every preset in the file and before any preset metadata is - // sent with the calls below. - // - // If the preset file is a preset container then name and load_key are mandatory, otherwise - // they are optional. - // - // The load_key is a machine friendly string used to load the preset inside the container via a - // the preset-load plug-in extension. The load_key can also just be the subpath if that's what - // the plugin wants but it could also be some other unique id like a database primary key or a - // binary offset. It's use is entirely up to the plug-in. - // - // If the function returns false, then the provider must stop calling back into the receiver. - bool(CLAP_ABI *begin_preset)(const struct clap_preset_discovery_metadata_receiver *receiver, - const char *name, - const char *load_key); - - // Adds a plug-in id that this preset can be used with. - void(CLAP_ABI *add_plugin_id)(const struct clap_preset_discovery_metadata_receiver *receiver, - const clap_plugin_id_t *plugin_id); - - // Sets the sound pack to which the preset belongs to. - void(CLAP_ABI *set_soundpack_id)(const struct clap_preset_discovery_metadata_receiver *receiver, - const char *soundpack_id); - - // Sets the flags, see clap_preset_discovery_flags. - // If unset, they are then inherited from the location. - void(CLAP_ABI *set_flags)(const struct clap_preset_discovery_metadata_receiver *receiver, - uint32_t flags); - - // Adds a creator name for the preset. - void(CLAP_ABI *add_creator)(const struct clap_preset_discovery_metadata_receiver *receiver, - const char *creator); - - // Sets a description of the preset. - void(CLAP_ABI *set_description)(const struct clap_preset_discovery_metadata_receiver *receiver, - const char *description); - - // Sets the creation time and last modification time of the preset. - // If one of the times isn't known, set it to CLAP_TIMESTAMP_UNKNOWN. - // If this function is not called, then the indexer may look at the file's creation and - // modification time. - void(CLAP_ABI *set_timestamps)(const struct clap_preset_discovery_metadata_receiver *receiver, - clap_timestamp_t creation_time, - clap_timestamp_t modification_time); - - // Adds a feature to the preset. - // - // The feature string is arbitrary, it is the indexer's job to understand it and remap it to its - // internal categorization and tagging system. - // - // However, the strings from plugin-features.h should be understood by the indexer and one of the - // plugin category could be provided to determine if the preset will result into an audio-effect, - // instrument, ... - // - // Examples: - // kick, drum, tom, snare, clap, cymbal, bass, lead, metalic, hardsync, crossmod, acid, - // distorted, drone, pad, dirty, etc... - void(CLAP_ABI *add_feature)(const struct clap_preset_discovery_metadata_receiver *receiver, - const char *feature); - - // Adds extra information to the metadata. - void(CLAP_ABI *add_extra_info)(const struct clap_preset_discovery_metadata_receiver *receiver, - const char *key, - const char *value); -} clap_preset_discovery_metadata_receiver_t; - -typedef struct clap_preset_discovery_filetype { - const char *name; - const char *description; // optional - - // `.' isn't included in the string. - // If empty or NULL then every file should be matched. - const char *file_extension; -} clap_preset_discovery_filetype_t; - -// Defines a place in which to search for presets -typedef struct clap_preset_discovery_location { - uint32_t flags; // see enum clap_preset_discovery_flags - const char *name; // name of this location - uint32_t kind; // See clap_preset_discovery_location_kind - - // Actual location in which to crawl presets. - // For FILE kind, the location can be either a path to a directory or a file. - // For PLUGIN kind, the location must be null. - const char *location; -} clap_preset_discovery_location_t; - -// Describes an installed sound pack. -typedef struct clap_preset_discovery_soundpack { - uint32_t flags; // see enum clap_preset_discovery_flags - const char *id; // sound pack identifier - const char *name; // name of this sound pack - const char *description; // optional, reasonably short description of the sound pack - const char *homepage_url; // optional, url to the pack's homepage - const char *vendor; // optional, sound pack's vendor - const char *image_path; // optional, an image on disk - clap_timestamp_t release_timestamp; // release date, CLAP_TIMESTAMP_UNKNOWN if unavailable -} clap_preset_discovery_soundpack_t; - -// Describes a preset provider -typedef struct clap_preset_discovery_provider_descriptor { - clap_version_t clap_version; // initialized to CLAP_VERSION - const char *id; // see plugin.h for advice on how to choose a good identifier - const char *name; // eg: "Diva's preset provider" - const char *vendor; // optional, eg: u-he -} clap_preset_discovery_provider_descriptor_t; - -// This interface isn't thread-safe. -typedef struct clap_preset_discovery_provider { - const clap_preset_discovery_provider_descriptor_t *desc; - - void *provider_data; // reserved pointer for the provider - - // Initialize the preset provider. - // It should declare all its locations, filetypes and sound packs. - // Returns false if initialization failed. - bool(CLAP_ABI *init)(const struct clap_preset_discovery_provider *provider); - - // Destroys the preset provider - void(CLAP_ABI *destroy)(const struct clap_preset_discovery_provider *provider); - - // reads metadata from the given file and passes them to the metadata receiver - // Returns true on success. - bool(CLAP_ABI *get_metadata)(const struct clap_preset_discovery_provider *provider, - uint32_t location_kind, - const char *location, - const clap_preset_discovery_metadata_receiver_t *metadata_receiver); - - // Query an extension. - // The returned pointer is owned by the provider. - // It is forbidden to call it before provider->init(). - // You can call it within provider->init() call, and after. - const void *(CLAP_ABI *get_extension)(const struct clap_preset_discovery_provider *provider, - const char *extension_id); -} clap_preset_discovery_provider_t; - -// This interface isn't thread-safe -typedef struct clap_preset_discovery_indexer { - clap_version_t clap_version; // initialized to CLAP_VERSION - const char *name; // eg: "Bitwig Studio" - const char *vendor; // optional, eg: "Bitwig GmbH" - const char *url; // optional, eg: "https://bitwig.com" - const char *version; // optional, eg: "4.3", see plugin.h for advice on how to format the version - - void *indexer_data; // reserved pointer for the indexer - - // Declares a preset filetype. - // Don't callback into the provider during this call. - // Returns false if the filetype is invalid. - bool(CLAP_ABI *declare_filetype)(const struct clap_preset_discovery_indexer *indexer, - const clap_preset_discovery_filetype_t *filetype); - - // Declares a preset location. - // Don't callback into the provider during this call. - // Returns false if the location is invalid. - bool(CLAP_ABI *declare_location)(const struct clap_preset_discovery_indexer *indexer, - const clap_preset_discovery_location_t *location); - - // Declares a sound pack. - // Don't callback into the provider during this call. - // Returns false if the sound pack is invalid. - bool(CLAP_ABI *declare_soundpack)(const struct clap_preset_discovery_indexer *indexer, - const clap_preset_discovery_soundpack_t *soundpack); - - // Query an extension. - // The returned pointer is owned by the indexer. - // It is forbidden to call it before provider->init(). - // You can call it within provider->init() call, and after. - const void *(CLAP_ABI *get_extension)(const struct clap_preset_discovery_indexer *indexer, - const char *extension_id); -} clap_preset_discovery_indexer_t; - -// Every methods in this factory must be thread-safe. -// It is encouraged to perform preset indexing in background threads, maybe even in background -// process. -// -// The host may use clap_plugin_invalidation_factory to detect filesystem changes -// which may change the factory's content. -typedef struct clap_preset_discovery_factory { - // Get the number of preset providers available. - // [thread-safe] - uint32_t(CLAP_ABI *count)(const struct clap_preset_discovery_factory *factory); - - // Retrieves a preset provider descriptor by its index. - // Returns null in case of error. - // The descriptor must not be freed. - // [thread-safe] - const clap_preset_discovery_provider_descriptor_t *(CLAP_ABI *get_descriptor)( - const struct clap_preset_discovery_factory *factory, uint32_t index); - - // Create a preset provider by its id. - // The returned pointer must be freed by calling preset_provider->destroy(preset_provider); - // The preset provider is not allowed to use the indexer callbacks in the create method. - // It is forbidden to call back into the indexer before the indexer calls provider->init(). - // Returns null in case of error. - // [thread-safe] - const clap_preset_discovery_provider_t *(CLAP_ABI *create)( - const struct clap_preset_discovery_factory *factory, - const clap_preset_discovery_indexer_t *indexer, - const char *provider_id); -} clap_preset_discovery_factory_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/factory/preset-discovery.h b/include/clap/factory/preset-discovery.h @@ -0,0 +1,327 @@ +/* + Preset Discovery API. + + Preset Discovery enables a plug-in host to identify where presets are found, what + extensions they have, which plug-ins they apply to, and other metadata associated with the + presets so that they can be indexed and searched for quickly within the plug-in host's browser. + + This has a number of advantages for the user: + - it allows them to browse for presets from one central location in a consistent way + - the user can browse for presets without having to commit to a particular plug-in first + + The API works as follow to index presets and presets metadata: + 1. clap_plugin_entry.get_factory(CLAP_PRESET_DISCOVERY_FACTORY_ID) + 2. clap_preset_discovery_factory_t.create(...) + 3. clap_preset_discovery_provider.init() (only necessary the first time, declarations + can be cached) + `-> clap_preset_discovery_indexer.declare_filetype() + `-> clap_preset_discovery_indexer.declare_location() + `-> clap_preset_discovery_indexer.declare_soundpack() (optional) + `-> clap_preset_discovery_indexer.set_invalidation_watch_file() (optional) + 4. crawl the given locations and monitor file system changes + `-> clap_preset_discovery_indexer.get_metadata() for each presets files + + Then to load a preset, use ext/draft/preset-load.h. + TODO: create a dedicated repo for other plugin abi preset-load extension. + + The design of this API deliberately does not define a fixed set tags or categories. It is the + plug-in host's job to try to intelligently map the raw list of features that are found for a + preset and to process this list to generate something that makes sense for the host's tagging and + categorization system. The reason for this is to reduce the work for a plug-in developer to add + Preset Discovery support for their existing preset file format and not have to be concerned with + all the different hosts and how they want to receive the metadata. + + VERY IMPORTANT: + - the whole indexing process has to be **fast** + - clap_preset_provider->get_metadata() has to be fast and avoid unnecessary operations + - the whole indexing process must not be interactive + - don't show dialogs, windows, ... + - don't ask for user input +*/ + +#pragma once + +#include "../private/std.h" +#include "../private/macros.h" +#include "../version.h" + +// Use it to retrieve const clap_preset_discovery_factory_t* from +// clap_plugin_entry.get_factory() +static const CLAP_CONSTEXPR char CLAP_PRESET_DISCOVERY_FACTORY_ID[] = + "clap.preset-discovery-factory/draft-2"; + +#ifdef __cplusplus +extern "C" { +#endif + +enum clap_preset_discovery_location_kind { + // The preset are located in a file on the OS filesystem. + // The location is then a path which works with the OS file system functions (open, stat, ...) + // So both '/' and '\' shall work on Windows as a separator. + CLAP_PRESET_DISCOVERY_LOCATION_FILE = 0, + + // The preset is bundled within the plugin DSO itself. + // The location must then be null, as the preset are within the plugin itself and then the plugin + // will act as a preset container. + CLAP_PRESET_DISCOVERY_LOCATION_PLUGIN = 1, +}; + +enum clap_preset_discovery_flags { + // This is for factory or sound-pack presets. + CLAP_PRESET_DISCOVERY_IS_FACTORY_CONTENT = 1 << 0, + + // This is for user presets. + CLAP_PRESET_DISCOVERY_IS_USER_CONTENT = 1 << 1, + + // This location is meant for demo presets, those are preset which may trigger + // some limitation in the plugin because they require additional features which the user + // needs to purchase or the content itself needs to be bought and is only available in + // demo mode. + CLAP_PRESET_DISCOVERY_IS_DEMO_CONTENT = 1 << 2, + + // This preset is a user's favorite + CLAP_PRESET_DISCOVERY_IS_FAVORITE = 1 << 3, +}; + +// TODO: move clap_timestamp_t, CLAP_TIMESTAMP_UNKNOWN and clap_plugin_id_t to parent files once we +// settle with preset discovery + +// This type defines a timestamp: the number of seconds since UNIX EPOCH. +// See C's time_t time(time_t *). +typedef uint64_t clap_timestamp_t; + +// Value for unknown timestamp. +static const clap_timestamp_t CLAP_TIMESTAMP_UNKNOWN = 0; + +// Pair of plugin ABI and plugin identifier +typedef struct clap_plugin_id { + // The plugin ABI name, in lowercase. + // eg: "clap" + const char *abi; + + // The plugin ID, for example "com.u-he.Diva". + // If the ABI rely upon binary plugin ids, then they shall be hex encoded (lower case). + const char *id; +} clap_plugin_id_t; + +// Receiver that receives the metadata for a single preset file. +// The host would define the various callbacks in this interface and the preset parser function +// would then call them. +// +// This interface isn't thread-safe. +typedef struct clap_preset_discovery_metadata_receiver { + void *receiver_data; // reserved pointer for the metadata receiver + + // If there is an error reading metadata from a file this should be called with an error + // message. + // os_error: the operating system error, if applicable. If not applicable set it to a non-error + // value, eg: 0 on unix and Windows. + void(CLAP_ABI *on_error)(const struct clap_preset_discovery_metadata_receiver *receiver, + int32_t os_error, + const char *error_message); + + // This must be called for every preset in the file and before any preset metadata is + // sent with the calls below. + // + // If the preset file is a preset container then name and load_key are mandatory, otherwise + // they are optional. + // + // The load_key is a machine friendly string used to load the preset inside the container via a + // the preset-load plug-in extension. The load_key can also just be the subpath if that's what + // the plugin wants but it could also be some other unique id like a database primary key or a + // binary offset. It's use is entirely up to the plug-in. + // + // If the function returns false, then the provider must stop calling back into the receiver. + bool(CLAP_ABI *begin_preset)(const struct clap_preset_discovery_metadata_receiver *receiver, + const char *name, + const char *load_key); + + // Adds a plug-in id that this preset can be used with. + void(CLAP_ABI *add_plugin_id)(const struct clap_preset_discovery_metadata_receiver *receiver, + const clap_plugin_id_t *plugin_id); + + // Sets the sound pack to which the preset belongs to. + void(CLAP_ABI *set_soundpack_id)(const struct clap_preset_discovery_metadata_receiver *receiver, + const char *soundpack_id); + + // Sets the flags, see clap_preset_discovery_flags. + // If unset, they are then inherited from the location. + void(CLAP_ABI *set_flags)(const struct clap_preset_discovery_metadata_receiver *receiver, + uint32_t flags); + + // Adds a creator name for the preset. + void(CLAP_ABI *add_creator)(const struct clap_preset_discovery_metadata_receiver *receiver, + const char *creator); + + // Sets a description of the preset. + void(CLAP_ABI *set_description)(const struct clap_preset_discovery_metadata_receiver *receiver, + const char *description); + + // Sets the creation time and last modification time of the preset. + // If one of the times isn't known, set it to CLAP_TIMESTAMP_UNKNOWN. + // If this function is not called, then the indexer may look at the file's creation and + // modification time. + void(CLAP_ABI *set_timestamps)(const struct clap_preset_discovery_metadata_receiver *receiver, + clap_timestamp_t creation_time, + clap_timestamp_t modification_time); + + // Adds a feature to the preset. + // + // The feature string is arbitrary, it is the indexer's job to understand it and remap it to its + // internal categorization and tagging system. + // + // However, the strings from plugin-features.h should be understood by the indexer and one of the + // plugin category could be provided to determine if the preset will result into an audio-effect, + // instrument, ... + // + // Examples: + // kick, drum, tom, snare, clap, cymbal, bass, lead, metalic, hardsync, crossmod, acid, + // distorted, drone, pad, dirty, etc... + void(CLAP_ABI *add_feature)(const struct clap_preset_discovery_metadata_receiver *receiver, + const char *feature); + + // Adds extra information to the metadata. + void(CLAP_ABI *add_extra_info)(const struct clap_preset_discovery_metadata_receiver *receiver, + const char *key, + const char *value); +} clap_preset_discovery_metadata_receiver_t; + +typedef struct clap_preset_discovery_filetype { + const char *name; + const char *description; // optional + + // `.' isn't included in the string. + // If empty or NULL then every file should be matched. + const char *file_extension; +} clap_preset_discovery_filetype_t; + +// Defines a place in which to search for presets +typedef struct clap_preset_discovery_location { + uint32_t flags; // see enum clap_preset_discovery_flags + const char *name; // name of this location + uint32_t kind; // See clap_preset_discovery_location_kind + + // Actual location in which to crawl presets. + // For FILE kind, the location can be either a path to a directory or a file. + // For PLUGIN kind, the location must be null. + const char *location; +} clap_preset_discovery_location_t; + +// Describes an installed sound pack. +typedef struct clap_preset_discovery_soundpack { + uint32_t flags; // see enum clap_preset_discovery_flags + const char *id; // sound pack identifier + const char *name; // name of this sound pack + const char *description; // optional, reasonably short description of the sound pack + const char *homepage_url; // optional, url to the pack's homepage + const char *vendor; // optional, sound pack's vendor + const char *image_path; // optional, an image on disk + clap_timestamp_t release_timestamp; // release date, CLAP_TIMESTAMP_UNKNOWN if unavailable +} clap_preset_discovery_soundpack_t; + +// Describes a preset provider +typedef struct clap_preset_discovery_provider_descriptor { + clap_version_t clap_version; // initialized to CLAP_VERSION + const char *id; // see plugin.h for advice on how to choose a good identifier + const char *name; // eg: "Diva's preset provider" + const char *vendor; // optional, eg: u-he +} clap_preset_discovery_provider_descriptor_t; + +// This interface isn't thread-safe. +typedef struct clap_preset_discovery_provider { + const clap_preset_discovery_provider_descriptor_t *desc; + + void *provider_data; // reserved pointer for the provider + + // Initialize the preset provider. + // It should declare all its locations, filetypes and sound packs. + // Returns false if initialization failed. + bool(CLAP_ABI *init)(const struct clap_preset_discovery_provider *provider); + + // Destroys the preset provider + void(CLAP_ABI *destroy)(const struct clap_preset_discovery_provider *provider); + + // reads metadata from the given file and passes them to the metadata receiver + // Returns true on success. + bool(CLAP_ABI *get_metadata)(const struct clap_preset_discovery_provider *provider, + uint32_t location_kind, + const char *location, + const clap_preset_discovery_metadata_receiver_t *metadata_receiver); + + // Query an extension. + // The returned pointer is owned by the provider. + // It is forbidden to call it before provider->init(). + // You can call it within provider->init() call, and after. + const void *(CLAP_ABI *get_extension)(const struct clap_preset_discovery_provider *provider, + const char *extension_id); +} clap_preset_discovery_provider_t; + +// This interface isn't thread-safe +typedef struct clap_preset_discovery_indexer { + clap_version_t clap_version; // initialized to CLAP_VERSION + const char *name; // eg: "Bitwig Studio" + const char *vendor; // optional, eg: "Bitwig GmbH" + const char *url; // optional, eg: "https://bitwig.com" + const char *version; // optional, eg: "4.3", see plugin.h for advice on how to format the version + + void *indexer_data; // reserved pointer for the indexer + + // Declares a preset filetype. + // Don't callback into the provider during this call. + // Returns false if the filetype is invalid. + bool(CLAP_ABI *declare_filetype)(const struct clap_preset_discovery_indexer *indexer, + const clap_preset_discovery_filetype_t *filetype); + + // Declares a preset location. + // Don't callback into the provider during this call. + // Returns false if the location is invalid. + bool(CLAP_ABI *declare_location)(const struct clap_preset_discovery_indexer *indexer, + const clap_preset_discovery_location_t *location); + + // Declares a sound pack. + // Don't callback into the provider during this call. + // Returns false if the sound pack is invalid. + bool(CLAP_ABI *declare_soundpack)(const struct clap_preset_discovery_indexer *indexer, + const clap_preset_discovery_soundpack_t *soundpack); + + // Query an extension. + // The returned pointer is owned by the indexer. + // It is forbidden to call it before provider->init(). + // You can call it within provider->init() call, and after. + const void *(CLAP_ABI *get_extension)(const struct clap_preset_discovery_indexer *indexer, + const char *extension_id); +} clap_preset_discovery_indexer_t; + +// Every methods in this factory must be thread-safe. +// It is encouraged to perform preset indexing in background threads, maybe even in background +// process. +// +// The host may use clap_plugin_invalidation_factory to detect filesystem changes +// which may change the factory's content. +typedef struct clap_preset_discovery_factory { + // Get the number of preset providers available. + // [thread-safe] + uint32_t(CLAP_ABI *count)(const struct clap_preset_discovery_factory *factory); + + // Retrieves a preset provider descriptor by its index. + // Returns null in case of error. + // The descriptor must not be freed. + // [thread-safe] + const clap_preset_discovery_provider_descriptor_t *(CLAP_ABI *get_descriptor)( + const struct clap_preset_discovery_factory *factory, uint32_t index); + + // Create a preset provider by its id. + // The returned pointer must be freed by calling preset_provider->destroy(preset_provider); + // The preset provider is not allowed to use the indexer callbacks in the create method. + // It is forbidden to call back into the indexer before the indexer calls provider->init(). + // Returns null in case of error. + // [thread-safe] + const clap_preset_discovery_provider_t *(CLAP_ABI *create)( + const struct clap_preset_discovery_factory *factory, + const clap_preset_discovery_indexer_t *indexer, + const char *provider_id); +} clap_preset_discovery_factory_t; + +#ifdef __cplusplus +} +#endif