Signed-off-by: falkTX <falktx@falktx.com>pull/409/head
@@ -48,16 +48,16 @@ typedef struct clap_plugin_entry { | |||||
// | // | ||||
// If init() returns false, then the host must not call deinit() nor any other clap | // If init() returns false, then the host must not call deinit() nor any other clap | ||||
// related symbols from the DSO. | // related symbols from the DSO. | ||||
bool (*init)(const char *plugin_path); | |||||
bool(CLAP_ABI *init)(const char *plugin_path); | |||||
// No more calls into the DSO must be made after calling deinit(). | // No more calls into the DSO must be made after calling deinit(). | ||||
void (*deinit)(void); | |||||
void(CLAP_ABI *deinit)(void); | |||||
// Get the pointer to a factory. See plugin-factory.h for an example. | // Get the pointer to a factory. See plugin-factory.h for an example. | ||||
// | // | ||||
// Returns null if the factory is not provided. | // Returns null if the factory is not provided. | ||||
// The returned pointer must *not* be freed by the caller. | // The returned pointer must *not* be freed by the caller. | ||||
const void *(*get_factory)(const char *factory_id); | |||||
const void *(CLAP_ABI *get_factory)(const char *factory_id); | |||||
} clap_plugin_entry_t; | } clap_plugin_entry_t; | ||||
/* Entry point */ | /* Entry point */ | ||||
@@ -263,10 +263,11 @@ typedef struct clap_event_midi2 { | |||||
typedef struct clap_input_events { | typedef struct clap_input_events { | ||||
void *ctx; // reserved pointer for the list | void *ctx; // reserved pointer for the list | ||||
uint32_t (*size)(const struct clap_input_events *list); | |||||
// returns the number of events in the list | |||||
uint32_t(CLAP_ABI *size)(const struct clap_input_events *list); | |||||
// Don't free the returned event, it belongs to the list | // Don't free the returned event, it belongs to the list | ||||
const clap_event_header_t *(*get)(const struct clap_input_events *list, uint32_t index); | |||||
const clap_event_header_t *(CLAP_ABI *get)(const struct clap_input_events *list, uint32_t index); | |||||
} clap_input_events_t; | } clap_input_events_t; | ||||
// Output event list, events must be sorted by time. | // Output event list, events must be sorted by time. | ||||
@@ -275,7 +276,8 @@ typedef struct clap_output_events { | |||||
// Pushes a copy of the event | // Pushes a copy of the event | ||||
// returns false if the event could not be pushed to the queue (out of memory?) | // returns false if the event could not be pushed to the queue (out of memory?) | ||||
bool (*try_push)(const struct clap_output_events *list, const clap_event_header_t *event); | |||||
bool(CLAP_ABI *try_push)(const struct clap_output_events *list, | |||||
const clap_event_header_t *event); | |||||
} clap_output_events_t; | } clap_output_events_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -69,14 +69,14 @@ typedef struct clap_audio_port_info { | |||||
typedef struct clap_plugin_audio_ports { | typedef struct clap_plugin_audio_ports { | ||||
// number of ports, for either input or output | // number of ports, for either input or output | ||||
// [main-thread] | // [main-thread] | ||||
uint32_t (*count)(const clap_plugin_t *plugin, bool is_input); | |||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input); | |||||
// get info about about an audio port. | // get info about about an audio port. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*get)(const clap_plugin_t *plugin, | |||||
uint32_t index, | |||||
bool is_input, | |||||
clap_audio_port_info_t *info); | |||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin, | |||||
uint32_t index, | |||||
bool is_input, | |||||
clap_audio_port_info_t *info); | |||||
} clap_plugin_audio_ports_t; | } clap_plugin_audio_ports_t; | ||||
enum { | enum { | ||||
@@ -102,13 +102,13 @@ enum { | |||||
typedef struct clap_host_audio_ports { | typedef struct clap_host_audio_ports { | ||||
// Checks if the host allows a plugin to change a given aspect of the audio ports definition. | // Checks if the host allows a plugin to change a given aspect of the audio ports definition. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*is_rescan_flag_supported)(const clap_host_t *host, uint32_t flag); | |||||
bool(CLAP_ABI *is_rescan_flag_supported)(const clap_host_t *host, uint32_t flag); | |||||
// Rescan the full list of audio ports according to the flags. | // Rescan the full list of audio ports according to the flags. | ||||
// It is illegal to ask the host to rescan with a flag that is not supported. | // It is illegal to ask the host to rescan with a flag that is not supported. | ||||
// Certain flags require the plugin to be de-activated. | // Certain flags require the plugin to be de-activated. | ||||
// [main-thread] | // [main-thread] | ||||
void (*rescan)(const clap_host_t *host, uint32_t flags); | |||||
void(CLAP_ABI *rescan)(const clap_host_t *host, uint32_t flags); | |||||
} clap_host_audio_ports_t; | } clap_host_audio_ports_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -97,12 +97,16 @@ typedef struct clap_gui_resize_hints { | |||||
typedef struct clap_plugin_gui { | typedef struct clap_plugin_gui { | ||||
// Returns true if the requested gui api is supported | // Returns true if the requested gui api is supported | ||||
// [main-thread] | // [main-thread] | ||||
bool (*is_api_supported)(const clap_plugin_t *plugin, const char *api, bool is_floating); | |||||
bool(CLAP_ABI *is_api_supported)(const clap_plugin_t *plugin, const char *api, bool is_floating); | |||||
// Returns true if the plugin has a preferred api. | // Returns true if the plugin has a preferred api. | ||||
// The host has no obligation to honor the plugin preferrence, this is just a hint. | // The host has no obligation to honor the plugin preferrence, this is just a hint. | ||||
// The const char **api variable should be explicitly assigned as a pointer to | |||||
// one of the CLAP_WINDOW_API_ constants defined above, not strcopied. | |||||
// [main-thread] | // [main-thread] | ||||
bool (*get_preferred_api)(const clap_plugin_t *plugin, const char **api, bool *is_floating); | |||||
bool(CLAP_ABI *get_preferred_api)(const clap_plugin_t *plugin, | |||||
const char **api, | |||||
bool *is_floating); | |||||
// Create and allocate all resources necessary for the gui. | // Create and allocate all resources necessary for the gui. | ||||
// | // | ||||
@@ -115,11 +119,11 @@ typedef struct clap_plugin_gui { | |||||
// | // | ||||
// After this call, the GUI may not be visible yet; don't forget to call show(). | // After this call, the GUI may not be visible yet; don't forget to call show(). | ||||
// [main-thread] | // [main-thread] | ||||
bool (*create)(const clap_plugin_t *plugin, const char *api, bool is_floating); | |||||
bool(CLAP_ABI *create)(const clap_plugin_t *plugin, const char *api, bool is_floating); | |||||
// Free all resources associated with the gui. | // Free all resources associated with the gui. | ||||
// [main-thread] | // [main-thread] | ||||
void (*destroy)(const clap_plugin_t *plugin); | |||||
void(CLAP_ABI *destroy)(const clap_plugin_t *plugin); | |||||
// Set the absolute GUI scaling factor, and override any OS info. | // Set the absolute GUI scaling factor, and override any OS info. | ||||
// Should not be used if the windowing api relies upon logical pixels. | // Should not be used if the windowing api relies upon logical pixels. | ||||
@@ -130,21 +134,21 @@ typedef struct clap_plugin_gui { | |||||
// Returns true if the scaling could be applied | // Returns true if the scaling could be applied | ||||
// Returns false if the call was ignored, or the scaling could not be applied. | // Returns false if the call was ignored, or the scaling could not be applied. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*set_scale)(const clap_plugin_t *plugin, double scale); | |||||
bool(CLAP_ABI *set_scale)(const clap_plugin_t *plugin, double scale); | |||||
// Get the current size of the plugin UI. | // Get the current size of the plugin UI. | ||||
// clap_plugin_gui->create() must have been called prior to asking the size. | // clap_plugin_gui->create() must have been called prior to asking the size. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*get_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height); | |||||
bool(CLAP_ABI *get_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height); | |||||
// Returns true if the window is resizeable (mouse drag). | // Returns true if the window is resizeable (mouse drag). | ||||
// Only for embedded windows. | // Only for embedded windows. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*can_resize)(const clap_plugin_t *plugin); | |||||
bool(CLAP_ABI *can_resize)(const clap_plugin_t *plugin); | |||||
// Returns true if the plugin can provide hints on how to resize the window. | // Returns true if the plugin can provide hints on how to resize the window. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*get_resize_hints)(const clap_plugin_t *plugin, clap_gui_resize_hints_t *hints); | |||||
bool(CLAP_ABI *get_resize_hints)(const clap_plugin_t *plugin, clap_gui_resize_hints_t *hints); | |||||
// If the plugin gui is resizable, then the plugin will calculate the closest | // If the plugin gui is resizable, then the plugin will calculate the closest | ||||
// usable size which fits in the given size. | // usable size which fits in the given size. | ||||
@@ -152,38 +156,38 @@ typedef struct clap_plugin_gui { | |||||
// | // | ||||
// Only for embedded windows. | // Only for embedded windows. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*adjust_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height); | |||||
bool(CLAP_ABI *adjust_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height); | |||||
// Sets the window size. Only for embedded windows. | // Sets the window size. Only for embedded windows. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*set_size)(const clap_plugin_t *plugin, uint32_t width, uint32_t height); | |||||
bool(CLAP_ABI *set_size)(const clap_plugin_t *plugin, uint32_t width, uint32_t height); | |||||
// Embbeds the plugin window into the given window. | // Embbeds the plugin window into the given window. | ||||
// [main-thread & !floating] | // [main-thread & !floating] | ||||
bool (*set_parent)(const clap_plugin_t *plugin, const clap_window_t *window); | |||||
bool(CLAP_ABI *set_parent)(const clap_plugin_t *plugin, const clap_window_t *window); | |||||
// Set the plugin floating window to stay above the given window. | // Set the plugin floating window to stay above the given window. | ||||
// [main-thread & floating] | // [main-thread & floating] | ||||
bool (*set_transient)(const clap_plugin_t *plugin, const clap_window_t *window); | |||||
bool(CLAP_ABI *set_transient)(const clap_plugin_t *plugin, const clap_window_t *window); | |||||
// Suggests a window title. Only for floating windows. | // Suggests a window title. Only for floating windows. | ||||
// [main-thread & floating] | // [main-thread & floating] | ||||
void (*suggest_title)(const clap_plugin_t *plugin, const char *title); | |||||
void(CLAP_ABI *suggest_title)(const clap_plugin_t *plugin, const char *title); | |||||
// Show the window. | // Show the window. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*show)(const clap_plugin_t *plugin); | |||||
bool(CLAP_ABI *show)(const clap_plugin_t *plugin); | |||||
// Hide the window, this method does not free the resources, it just hides | // Hide the window, this method does not free the resources, it just hides | ||||
// the window content. Yet it may be a good idea to stop painting timers. | // the window content. Yet it may be a good idea to stop painting timers. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*hide)(const clap_plugin_t *plugin); | |||||
bool(CLAP_ABI *hide)(const clap_plugin_t *plugin); | |||||
} clap_plugin_gui_t; | } clap_plugin_gui_t; | ||||
typedef struct clap_host_gui { | typedef struct clap_host_gui { | ||||
// The host should call get_resize_hints() again. | // The host should call get_resize_hints() again. | ||||
// [thread-safe] | // [thread-safe] | ||||
void (*resize_hints_changed)(const clap_host_t *host); | |||||
void(CLAP_ABI *resize_hints_changed)(const clap_host_t *host); | |||||
/* Request the host to resize the client area to width, height. | /* Request the host to resize the client area to width, height. | ||||
* Return true if the new size is accepted, false otherwise. | * Return true if the new size is accepted, false otherwise. | ||||
@@ -194,24 +198,24 @@ typedef struct clap_host_gui { | |||||
* satisfied then the host will call set_size() to revert the operation. | * satisfied then the host will call set_size() to revert the operation. | ||||
* | * | ||||
* [thread-safe] */ | * [thread-safe] */ | ||||
bool (*request_resize)(const clap_host_t *host, uint32_t width, uint32_t height); | |||||
bool(CLAP_ABI *request_resize)(const clap_host_t *host, uint32_t width, uint32_t height); | |||||
/* Request the host to show the plugin gui. | /* Request the host to show the plugin gui. | ||||
* Return true on success, false otherwise. | * Return true on success, false otherwise. | ||||
* [thread-safe] */ | * [thread-safe] */ | ||||
bool (*request_show)(const clap_host_t *host); | |||||
bool(CLAP_ABI *request_show)(const clap_host_t *host); | |||||
/* Request the host to hide the plugin gui. | /* Request the host to hide the plugin gui. | ||||
* Return true on success, false otherwise. | * Return true on success, false otherwise. | ||||
* [thread-safe] */ | * [thread-safe] */ | ||||
bool (*request_hide)(const clap_host_t *host); | |||||
bool(CLAP_ABI *request_hide)(const clap_host_t *host); | |||||
// The floating window has been closed, or the connection to the gui has been lost. | // The floating window has been closed, or the connection to the gui has been lost. | ||||
// | // | ||||
// If was_destroyed is true, then the host must call clap_plugin_gui->destroy() to acknowledge | // If was_destroyed is true, then the host must call clap_plugin_gui->destroy() to acknowledge | ||||
// the gui destruction. | // the gui destruction. | ||||
// [thread-safe] | // [thread-safe] | ||||
void (*closed)(const clap_host_t *host, bool was_destroyed); | |||||
void(CLAP_ABI *closed)(const clap_host_t *host, bool was_destroyed); | |||||
} clap_host_gui_t; | } clap_host_gui_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -0,0 +1,28 @@ | |||||
#pragma once | |||||
#include "../plugin.h" | |||||
static CLAP_CONSTEXPR const char CLAP_EXT_LATENCY[] = "clap.latency"; | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
// The audio ports scan has to be done while the plugin is deactivated. | |||||
typedef struct clap_plugin_latency { | |||||
// Returns the plugin latency. | |||||
// [main-thread] | |||||
uint32_t(CLAP_ABI *get)(const clap_plugin_t *plugin); | |||||
} clap_plugin_latency_t; | |||||
typedef struct clap_host_latency { | |||||
// Tell the host that the latency changed. | |||||
// The latency is only allowed to change if the plugin is deactivated. | |||||
// If the plugin is activated, call host->request_restart() | |||||
// [main-thread] | |||||
void(CLAP_ABI *changed)(const clap_host_t *host); | |||||
} clap_host_latency_t; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -42,14 +42,14 @@ typedef struct clap_note_port_info { | |||||
typedef struct clap_plugin_note_ports { | typedef struct clap_plugin_note_ports { | ||||
// number of ports, for either input or output | // number of ports, for either input or output | ||||
// [main-thread] | // [main-thread] | ||||
uint32_t (*count)(const clap_plugin_t *plugin, bool is_input); | |||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input); | |||||
// get info about about a note port. | // get info about about a note port. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*get)(const clap_plugin_t *plugin, | |||||
uint32_t index, | |||||
bool is_input, | |||||
clap_note_port_info_t *info); | |||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin, | |||||
uint32_t index, | |||||
bool is_input, | |||||
clap_note_port_info_t *info); | |||||
} clap_plugin_note_ports_t; | } clap_plugin_note_ports_t; | ||||
enum { | enum { | ||||
@@ -66,11 +66,11 @@ enum { | |||||
typedef struct clap_host_note_ports { | typedef struct clap_host_note_ports { | ||||
// Query which dialects the host supports | // Query which dialects the host supports | ||||
// [main-thread] | // [main-thread] | ||||
uint32_t (*supported_dialects)(const clap_host_t *host); | |||||
uint32_t(CLAP_ABI *supported_dialects)(const clap_host_t *host); | |||||
// Rescan the full list of note ports according to the flags. | // Rescan the full list of note ports according to the flags. | ||||
// [main-thread] | // [main-thread] | ||||
void (*rescan)(const clap_host_t *host, uint32_t flags); | |||||
void(CLAP_ABI *rescan)(const clap_host_t *host, uint32_t flags); | |||||
} clap_host_note_ports_t; | } clap_host_note_ports_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -155,16 +155,43 @@ typedef struct clap_param_info { | |||||
clap_param_info_flags flags; | clap_param_info_flags flags; | ||||
// This value is optional and set by the plugin. | |||||
// Its purpose is to provide a fast access to the plugin parameter: | |||||
// This value is optional and set by the plugin. The host will | |||||
// set it on all subsequent events regarding this param_id | |||||
// or set the cookie to nullptr if the host chooses to | |||||
// not implement cookies. | |||||
// | // | ||||
// The plugin must gracefully handle the case of a cookie | |||||
// which is nullptr, but can safely assume any cookie | |||||
// which is not nullptr is the value it issued. | |||||
// | |||||
// It is very strongly recommended that the host implement | |||||
// cookies. Some plugins may have noticably reduced | |||||
// performance when addressing params in hosts without cookies. | |||||
// | |||||
// The cookie's purpose is to provide a fast access to the | |||||
// plugin parameter objects. For instance: | |||||
// | |||||
// in clap_plugin_params.get_info | |||||
// Parameter *p = findParameter(param_id); | // Parameter *p = findParameter(param_id); | ||||
// param_info->cookie = p; | // param_info->cookie = p; | ||||
// | // | ||||
// /* and later on */ | |||||
// Parameter *p = (Parameter *)cookie; | |||||
// later, in clap_plugin.process: | |||||
// | |||||
// Parameter *p{nullptr}; | |||||
// if (evt->cookie) [[likely]] | |||||
// p = (Parameter *)evt->cookie; | |||||
// else | |||||
// p = -- alternate mechanism -- | |||||
// | // | ||||
// It is invalidated on clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL) and when the plugin is | |||||
// where "alternate mechanism" is a mechanism the plugin implements | |||||
// to map parameter ids to internal objects. | |||||
// | |||||
// The host should make no assumption about the | |||||
// value of the cookie other than passing it back to the plugin or | |||||
// replacing it with nullptr. | |||||
// | |||||
// Once set, the cookie is valid until invalidated by a call to | |||||
// clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL) or when the plugin is | |||||
// destroyed. | // destroyed. | ||||
void *cookie; | void *cookie; | ||||
@@ -183,39 +210,44 @@ typedef struct clap_param_info { | |||||
typedef struct clap_plugin_params { | typedef struct clap_plugin_params { | ||||
// Returns the number of parameters. | // Returns the number of parameters. | ||||
// [main-thread] | // [main-thread] | ||||
uint32_t (*count)(const clap_plugin_t *plugin); | |||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); | |||||
// Copies the parameter's info to param_info and returns true on success. | // Copies the parameter's info to param_info and returns true on success. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*get_info)(const clap_plugin_t *plugin, | |||||
uint32_t param_index, | |||||
clap_param_info_t *param_info); | |||||
bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin, | |||||
uint32_t param_index, | |||||
clap_param_info_t *param_info); | |||||
// Gets the parameter plain value. | // Gets the parameter plain value. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*get_value)(const clap_plugin_t *plugin, clap_id param_id, double *value); | |||||
bool(CLAP_ABI *get_value)(const clap_plugin_t *plugin, clap_id param_id, double *value); | |||||
// Formats the display text for the given parameter value. | // Formats the display text for the given parameter value. | ||||
// The host should always format the parameter value to text using this function | // The host should always format the parameter value to text using this function | ||||
// before displaying it to the user. | // before displaying it to the user. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*value_to_text)( | |||||
bool(CLAP_ABI *value_to_text)( | |||||
const clap_plugin_t *plugin, clap_id param_id, double value, char *display, uint32_t size); | const clap_plugin_t *plugin, clap_id param_id, double value, char *display, uint32_t size); | ||||
// Converts the display text to a parameter value. | // Converts the display text to a parameter value. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*text_to_value)(const clap_plugin_t *plugin, | |||||
clap_id param_id, | |||||
const char *display, | |||||
double *value); | |||||
bool(CLAP_ABI *text_to_value)(const clap_plugin_t *plugin, | |||||
clap_id param_id, | |||||
const char *display, | |||||
double *value); | |||||
// Flushes a set of parameter changes. | // Flushes a set of parameter changes. | ||||
// This method must not be called concurrently to clap_plugin->process(). | // This method must not be called concurrently to clap_plugin->process(). | ||||
// | // | ||||
// Note: if the plugin is processing, then the process() call will already achieve the | |||||
// parameter update (bi-directionnal), so a call to flush isn't required, also be aware | |||||
// that the plugin may use the sample offset in process(), while this information would be | |||||
// lost within flush(). | |||||
// | |||||
// [active ? audio-thread : main-thread] | // [active ? audio-thread : main-thread] | ||||
void (*flush)(const clap_plugin_t *plugin, | |||||
const clap_input_events_t *in, | |||||
const clap_output_events_t *out); | |||||
void(CLAP_ABI *flush)(const clap_plugin_t *plugin, | |||||
const clap_input_events_t *in, | |||||
const clap_output_events_t *out); | |||||
} clap_plugin_params_t; | } clap_plugin_params_t; | ||||
enum { | enum { | ||||
@@ -272,23 +304,23 @@ typedef uint32_t clap_param_clear_flags; | |||||
typedef struct clap_host_params { | typedef struct clap_host_params { | ||||
// Rescan the full list of parameters according to the flags. | // Rescan the full list of parameters according to the flags. | ||||
// [main-thread] | // [main-thread] | ||||
void (*rescan)(const clap_host_t *host, clap_param_rescan_flags flags); | |||||
void(CLAP_ABI *rescan)(const clap_host_t *host, clap_param_rescan_flags flags); | |||||
// Clears references to a parameter. | // Clears references to a parameter. | ||||
// [main-thread] | // [main-thread] | ||||
void (*clear)(const clap_host_t *host, clap_id param_id, clap_param_clear_flags flags); | |||||
void(CLAP_ABI *clear)(const clap_host_t *host, clap_id param_id, clap_param_clear_flags flags); | |||||
// Request a parameter flush. | // Request a parameter flush. | ||||
// | // | ||||
// The host will then schedule a call to either: | // The host will then schedule a call to either: | ||||
// - clap_plugin.process() | // - clap_plugin.process() | ||||
// - clap_plugin_params->flush() | |||||
// - clap_plugin_params.flush() | |||||
// | // | ||||
// This function is always safe to use and should not be called from an [audio-thread] as the | // This function is always safe to use and should not be called from an [audio-thread] as the | ||||
// plugin would already be within process() or flush(). | // plugin would already be within process() or flush(). | ||||
// | // | ||||
// [thread-safe,!audio-thread] | // [thread-safe,!audio-thread] | ||||
void (*request_flush)(const clap_host_t *host); | |||||
void(CLAP_ABI *request_flush)(const clap_host_t *host); | |||||
} clap_host_params_t; | } clap_host_params_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -13,19 +13,19 @@ typedef struct clap_plugin_state { | |||||
// Saves the plugin state into stream. | // Saves the plugin state into stream. | ||||
// Returns true if the state was correctly saved. | // Returns true if the state was correctly saved. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*save)(const clap_plugin_t *plugin, const clap_ostream_t *stream); | |||||
bool(CLAP_ABI *save)(const clap_plugin_t *plugin, const clap_ostream_t *stream); | |||||
// Loads the plugin state from stream. | // Loads the plugin state from stream. | ||||
// Returns true if the state was correctly restored. | // Returns true if the state was correctly restored. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*load)(const clap_plugin_t *plugin, const clap_istream_t *stream); | |||||
bool(CLAP_ABI *load)(const clap_plugin_t *plugin, const clap_istream_t *stream); | |||||
} clap_plugin_state_t; | } clap_plugin_state_t; | ||||
typedef struct clap_host_state { | typedef struct clap_host_state { | ||||
// Tell the host that the plugin state has changed and should be saved again. | // Tell the host that the plugin state has changed and should be saved again. | ||||
// If a parameter value changes, then it is implicit that the state is dirty. | // If a parameter value changes, then it is implicit that the state is dirty. | ||||
// [main-thread] | // [main-thread] | ||||
void (*mark_dirty)(const clap_host_t *host); | |||||
void(CLAP_ABI *mark_dirty)(const clap_host_t *host); | |||||
} clap_host_state_t; | } clap_host_state_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -0,0 +1,51 @@ | |||||
#pragma once | |||||
#include "../plugin.h" | |||||
static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_CHECK[] = "clap.thread-check"; | |||||
#ifdef __cplusplus | |||||
extern "C" { | |||||
#endif | |||||
/// @page thread-check | |||||
/// | |||||
/// CLAP defines two symbolic threads: | |||||
/// | |||||
/// main-thread: | |||||
/// This is the thread in which most of the interaction between the plugin and host happens. | |||||
/// It is usually the thread on which the GUI receives its events. | |||||
/// It isn't a realtime thread, yet this thread needs to respond fast enough to user interaction, | |||||
/// so it is recommended to run long and expensive tasks such as preset indexing or asset loading | |||||
/// in dedicated background threads. | |||||
/// | |||||
/// audio-thread: | |||||
/// This thread is used for realtime audio processing. Its execution should be as deterministic | |||||
/// as possible to meet the audio interface's deadline (can be <1ms). In other words, there is a | |||||
/// known set of operations that should be avoided: malloc() and free(), mutexes (spin mutexes | |||||
/// are worse), I/O, waiting, ... | |||||
/// The audio-thread is something symbolic, there isn't one OS thread that remains the | |||||
/// audio-thread for the plugin lifetime. As you may guess, the host is likely to have a | |||||
/// thread pool and the plugin.process() call may be scheduled on different OS threads over time. | |||||
/// The most important thing is that there can't be two audio-threads at the same time. All the | |||||
/// functions marked with [audio-thread] **ARE NOT CONCURRENT**. The host may mark any OS thread, | |||||
/// including the main-thread as the audio-thread, as long as it can guarentee that only one OS | |||||
/// thread is the audio-thread at a time. The audio-thread can be seen as a concurrency guard for | |||||
/// all functions marked with [audio-thread]. | |||||
// This interface is useful to do runtime checks and make | |||||
// sure that the functions are called on the correct threads. | |||||
// It is highly recommended that hosts implement this extension. | |||||
typedef struct clap_host_thread_check { | |||||
// Returns true if "this" thread is the main thread. | |||||
// [thread-safe] | |||||
bool(CLAP_ABI *is_main_thread)(const clap_host_t *host); | |||||
// Returns true if "this" thread is one of the audio threads. | |||||
// [thread-safe] | |||||
bool(CLAP_ABI *is_audio_thread)(const clap_host_t *host); | |||||
} clap_host_thread_check_t; | |||||
#ifdef __cplusplus | |||||
} | |||||
#endif |
@@ -10,7 +10,7 @@ extern "C" { | |||||
typedef struct clap_plugin_timer_support { | typedef struct clap_plugin_timer_support { | ||||
// [main-thread] | // [main-thread] | ||||
void (*on_timer)(const clap_plugin_t *plugin, clap_id timer_id); | |||||
void(CLAP_ABI *on_timer)(const clap_plugin_t *plugin, clap_id timer_id); | |||||
} clap_plugin_timer_support_t; | } clap_plugin_timer_support_t; | ||||
typedef struct clap_host_timer_support { | typedef struct clap_host_timer_support { | ||||
@@ -18,10 +18,10 @@ typedef struct clap_host_timer_support { | |||||
// The host may adjust the period if it is under a certain threshold. | // The host may adjust the period if it is under a certain threshold. | ||||
// 30 Hz should be allowed. | // 30 Hz should be allowed. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*register_timer)(const clap_host_t *host, uint32_t period_ms, clap_id *timer_id); | |||||
bool(CLAP_ABI *register_timer)(const clap_host_t *host, uint32_t period_ms, clap_id *timer_id); | |||||
// [main-thread] | // [main-thread] | ||||
bool (*unregister_timer)(const clap_host_t *host, clap_id timer_id); | |||||
bool(CLAP_ABI *unregister_timer)(const clap_host_t *host, clap_id timer_id); | |||||
} clap_host_timer_support_t; | } clap_host_timer_support_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -19,21 +19,21 @@ typedef struct clap_host { | |||||
// Query an extension. | // Query an extension. | ||||
// [thread-safe] | // [thread-safe] | ||||
const void *(*get_extension)(const struct clap_host *host, const char *extension_id); | |||||
const void *(CLAP_ABI *get_extension)(const struct clap_host *host, const char *extension_id); | |||||
// Request the host to deactivate and then reactivate the plugin. | // Request the host to deactivate and then reactivate the plugin. | ||||
// The operation may be delayed by the host. | // The operation may be delayed by the host. | ||||
// [thread-safe] | // [thread-safe] | ||||
void (*request_restart)(const struct clap_host *host); | |||||
void(CLAP_ABI *request_restart)(const struct clap_host *host); | |||||
// Request the host to activate and start processing the plugin. | // Request the host to activate and start processing the plugin. | ||||
// This is useful if you have external IO and need to wake up the plugin from "sleep". | // This is useful if you have external IO and need to wake up the plugin from "sleep". | ||||
// [thread-safe] | // [thread-safe] | ||||
void (*request_process)(const struct clap_host *host); | |||||
void(CLAP_ABI *request_process)(const struct clap_host *host); | |||||
// Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread. | // Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread. | ||||
// [thread-safe] | // [thread-safe] | ||||
void (*request_callback)(const struct clap_host *host); | |||||
void(CLAP_ABI *request_callback)(const struct clap_host *host); | |||||
} clap_host_t; | } clap_host_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -11,17 +11,18 @@ extern "C" { | |||||
// Every method must be thread-safe. | // Every method must be thread-safe. | ||||
// It is very important to be able to scan the plugin as quickly as possible. | // It is very important to be able to scan the plugin as quickly as possible. | ||||
// | // | ||||
// If the content of the factory may change due to external events, like the user installed | |||||
// The host may use clap_plugin_invalidation_factory to detect filesystem changes | |||||
// which may change the factory's content. | |||||
typedef struct clap_plugin_factory { | typedef struct clap_plugin_factory { | ||||
// Get the number of plugins available. | // Get the number of plugins available. | ||||
// [thread-safe] | // [thread-safe] | ||||
uint32_t (*get_plugin_count)(const struct clap_plugin_factory *factory); | |||||
uint32_t(CLAP_ABI *get_plugin_count)(const struct clap_plugin_factory *factory); | |||||
// Retrieves a plugin descriptor by its index. | // Retrieves a plugin descriptor by its index. | ||||
// Returns null in case of error. | // Returns null in case of error. | ||||
// The descriptor must not be freed. | // The descriptor must not be freed. | ||||
// [thread-safe] | // [thread-safe] | ||||
const clap_plugin_descriptor_t *(*get_plugin_descriptor)( | |||||
const clap_plugin_descriptor_t *(CLAP_ABI *get_plugin_descriptor)( | |||||
const struct clap_plugin_factory *factory, uint32_t index); | const struct clap_plugin_factory *factory, uint32_t index); | ||||
// Create a clap_plugin by its plugin_id. | // Create a clap_plugin by its plugin_id. | ||||
@@ -29,9 +30,9 @@ typedef struct clap_plugin_factory { | |||||
// The plugin is not allowed to use the host callbacks in the create method. | // The plugin is not allowed to use the host callbacks in the create method. | ||||
// Returns null in case of error. | // Returns null in case of error. | ||||
// [thread-safe] | // [thread-safe] | ||||
const clap_plugin_t *(*create_plugin)(const struct clap_plugin_factory *factory, | |||||
const clap_host_t *host, | |||||
const char *plugin_id); | |||||
const clap_plugin_t *(CLAP_ABI *create_plugin)(const struct clap_plugin_factory *factory, | |||||
const clap_host_t *host, | |||||
const char *plugin_id); | |||||
} clap_plugin_factory_t; | } clap_plugin_factory_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -38,12 +38,12 @@ typedef struct clap_plugin { | |||||
// Must be called after creating the plugin. | // Must be called after creating the plugin. | ||||
// If init returns false, the host must destroy the plugin instance. | // If init returns false, the host must destroy the plugin instance. | ||||
// [main-thread] | // [main-thread] | ||||
bool (*init)(const struct clap_plugin *plugin); | |||||
bool(CLAP_ABI *init)(const struct clap_plugin *plugin); | |||||
// Free the plugin and its resources. | // Free the plugin and its resources. | ||||
// It is required to deactivate the plugin prior to this call. | // It is required to deactivate the plugin prior to this call. | ||||
// [main-thread & !active] | // [main-thread & !active] | ||||
void (*destroy)(const struct clap_plugin *plugin); | |||||
void(CLAP_ABI *destroy)(const struct clap_plugin *plugin); | |||||
// Activate and deactivate the plugin. | // Activate and deactivate the plugin. | ||||
// In this call the plugin may allocate memory and prepare everything needed for the process | // In this call the plugin may allocate memory and prepare everything needed for the process | ||||
@@ -52,21 +52,20 @@ typedef struct clap_plugin { | |||||
// Once activated the latency and port configuration must remain constant, until deactivation. | // Once activated the latency and port configuration must remain constant, until deactivation. | ||||
// | // | ||||
// [main-thread & !active_state] | // [main-thread & !active_state] | ||||
bool (*activate)(const struct clap_plugin *plugin, | |||||
double sample_rate, | |||||
uint32_t min_frames_count, | |||||
uint32_t max_frames_count); | |||||
bool(CLAP_ABI *activate)(const struct clap_plugin *plugin, | |||||
double sample_rate, | |||||
uint32_t min_frames_count, | |||||
uint32_t max_frames_count); | |||||
// [main-thread & active_state] | // [main-thread & active_state] | ||||
void (*deactivate)(const struct clap_plugin *plugin); | |||||
void(CLAP_ABI *deactivate)(const struct clap_plugin *plugin); | |||||
// Call start processing before processing. | // Call start processing before processing. | ||||
// [audio-thread & active_state & !processing_state] | // [audio-thread & active_state & !processing_state] | ||||
bool (*start_processing)(const struct clap_plugin *plugin); | |||||
bool(CLAP_ABI *start_processing)(const struct clap_plugin *plugin); | |||||
// Call stop processing before sending the plugin to sleep. | // Call stop processing before sending the plugin to sleep. | ||||
// [audio-thread & active_state & processing_state] | // [audio-thread & active_state & processing_state] | ||||
void (*stop_processing)(const struct clap_plugin *plugin); | |||||
void(CLAP_ABI *stop_processing)(const struct clap_plugin *plugin); | |||||
// - Clears all buffers, performs a full reset of the processing state (filters, oscillators, | // - Clears all buffers, performs a full reset of the processing state (filters, oscillators, | ||||
// enveloppes, lfo, ...) and kills all voices. | // enveloppes, lfo, ...) and kills all voices. | ||||
@@ -74,21 +73,22 @@ typedef struct clap_plugin { | |||||
// - clap_process.steady_time may jump backward. | // - clap_process.steady_time may jump backward. | ||||
// | // | ||||
// [audio-thread & active_state] | // [audio-thread & active_state] | ||||
void (*reset)(const struct clap_plugin *plugin); | |||||
void(CLAP_ABI *reset)(const struct clap_plugin *plugin); | |||||
// process audio, events, ... | // process audio, events, ... | ||||
// [audio-thread & active_state & processing_state] | // [audio-thread & active_state & processing_state] | ||||
clap_process_status (*process)(const struct clap_plugin *plugin, const clap_process_t *process); | |||||
clap_process_status(CLAP_ABI *process)(const struct clap_plugin *plugin, | |||||
const clap_process_t *process); | |||||
// Query an extension. | // Query an extension. | ||||
// The returned pointer is owned by the plugin. | // The returned pointer is owned by the plugin. | ||||
// [thread-safe] | // [thread-safe] | ||||
const void *(*get_extension)(const struct clap_plugin *plugin, const char *id); | |||||
const void *(CLAP_ABI *get_extension)(const struct clap_plugin *plugin, const char *id); | |||||
// Called by the host on the main thread in response to a previous call to: | // Called by the host on the main thread in response to a previous call to: | ||||
// host->request_callback(host); | // host->request_callback(host); | ||||
// [main-thread] | // [main-thread] | ||||
void (*on_main_thread)(const struct clap_plugin *plugin); | |||||
void(CLAP_ABI *on_main_thread)(const struct clap_plugin *plugin); | |||||
} clap_plugin_t; | } clap_plugin_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -17,6 +17,14 @@ | |||||
# endif | # endif | ||||
#endif | #endif | ||||
#if !defined(CLAP_ABI) | |||||
# if defined _WIN32 || defined __CYGWIN__ | |||||
# define CLAP_ABI __cdecl | |||||
# else | |||||
# define CLAP_ABI | |||||
# endif | |||||
#endif | |||||
#if defined(__cplusplus) && __cplusplus >= 201103L | #if defined(__cplusplus) && __cplusplus >= 201103L | ||||
# define CLAP_HAS_CXX11 | # define CLAP_HAS_CXX11 | ||||
# define CLAP_CONSTEXPR constexpr | # define CLAP_CONSTEXPR constexpr | ||||
@@ -45,8 +45,9 @@ typedef struct clap_process { | |||||
const clap_event_transport_t *transport; | const clap_event_transport_t *transport; | ||||
// Audio buffers, they must have the same count as specified | // Audio buffers, they must have the same count as specified | ||||
// by clap_plugin_audio_ports->get_count(). | |||||
// The index maps to clap_plugin_audio_ports->get_info(). | |||||
// by clap_plugin_audio_ports->count(). | |||||
// The index maps to clap_plugin_audio_ports->get(). | |||||
// Input buffer and its contents are read-only. | |||||
const clap_audio_buffer_t *audio_inputs; | const clap_audio_buffer_t *audio_inputs; | ||||
clap_audio_buffer_t *audio_outputs; | clap_audio_buffer_t *audio_outputs; | ||||
uint32_t audio_inputs_count; | uint32_t audio_inputs_count; | ||||
@@ -11,14 +11,14 @@ typedef struct clap_istream { | |||||
void *ctx; // reserved pointer for the stream | void *ctx; // reserved pointer for the stream | ||||
// returns the number of bytes read; 0 indicates end of file and -1 a read error | // returns the number of bytes read; 0 indicates end of file and -1 a read error | ||||
int64_t (*read)(const struct clap_istream *stream, void *buffer, uint64_t size); | |||||
int64_t(CLAP_ABI *read)(const struct clap_istream *stream, void *buffer, uint64_t size); | |||||
} clap_istream_t; | } clap_istream_t; | ||||
typedef struct clap_ostream { | typedef struct clap_ostream { | ||||
void *ctx; // reserved pointer for the stream | void *ctx; // reserved pointer for the stream | ||||
// returns the number of bytes written; -1 on write error | // returns the number of bytes written; -1 on write error | ||||
int64_t (*write)(const struct clap_ostream *stream, const void *buffer, uint64_t size); | |||||
int64_t(CLAP_ABI *write)(const struct clap_ostream *stream, const void *buffer, uint64_t size); | |||||
} clap_ostream_t; | } clap_ostream_t; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||