Initial commit

This commit is contained in:
Patrick 2025-10-03 20:16:11 +02:00
commit 56f7cd1875
105 changed files with 22109 additions and 0 deletions

View file

@ -0,0 +1,33 @@
#pragma once
#include "../audio-ports.h"
#ifdef __cplusplus
extern "C" {
#endif
// This extension lets the host add and remove audio ports to the plugin.
static CLAP_CONSTEXPR const char CLAP_EXT_EXTENSIBLE_AUDIO_PORTS[] =
"clap.extensible-audio-ports/1";
typedef struct clap_plugin_extensible_audio_ports {
// Asks the plugin to add a new port (at the end of the list), with the following settings.
// port_type: see clap_audio_port_info.port_type for interpretation.
// port_details: see clap_audio_port_configuration_request.port_details for interpretation.
// Returns true on success.
// [main-thread && !is_active]
bool(CLAP_ABI *add_port)(const clap_plugin_t *plugin,
bool is_input,
uint32_t channel_count,
const char *port_type,
const void *port_details);
// Asks the plugin to remove a port.
// Returns true on success.
// [main-thread && !is_active]
bool(CLAP_ABI *remove_port)(const clap_plugin_t *plugin, bool is_input, uint32_t index);
} clap_plugin_extensible_audio_ports_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,34 @@
#pragma once
#include "../../plugin.h"
// This extension lets the plugin report the current gain adjustment
// (typically, gain reduction) to the host.
static CLAP_CONSTEXPR const char CLAP_EXT_GAIN_ADJUSTMENT_METERING[] = "clap.gain-adjustment-metering/0";
#ifdef __cplusplus
extern "C" {
#endif
typedef struct clap_plugin_gain_adjustment_metering {
// Returns the current gain adjustment in dB. The value is intended
// for informational display, for example in a host meter or tooltip.
// The returned value represents the gain adjustment that the plugin
// applied to the last sample in the most recently processed block.
//
// The returned value is in dB. Zero means the plugin is applying no gain
// reduction, or is not processing. A negative value means the plugin is
// applying gain reduction, as with a compressor or limiter. A positive
// value means the plugin is adding gain, as with an expander. The value
// represents the dynamic gain reduction or expansion applied by the
// plugin, before any make-up gain or other adjustment. A single value is
// returned for all audio channels.
//
// [audio-thread]
double(CLAP_ABI *get)(const clap_plugin_t *plugin);
} clap_plugin_gain_adjustment_metering_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,153 @@
#pragma once
#include "../../plugin.h"
// This extension allows a host to render a small curve provided by the plugin.
// A useful application is to render an EQ frequency response in the DAW mixer view.
static CLAP_CONSTEXPR const char CLAP_EXT_MINI_CURVE_DISPLAY[] = "clap.mini-curve-display/3";
#ifdef __cplusplus
extern "C" {
#endif
enum clap_mini_curve_display_curve_kind {
// If the curve's kind doesn't fit in any proposed kind, use this one
// and perhaps, make a pull request to extend the list.
CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_UNSPECIFIED = 0,
// The mini curve is intended to draw the total gain response of the plugin.
// In this case the y values are in dB and the x values are in Hz (logarithmic).
// This would be useful in for example an equalizer.
CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_GAIN_RESPONSE = 1,
// The mini curve is intended to draw the total phase response of the plugin.
// In this case the y values are in radians and the x values are in Hz (logarithmic).
// This would be useful in for example an equalizer.
CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_PHASE_RESPONSE = 2,
// The mini curve is intended to draw the transfer curve of the plugin.
// In this case the both x and y values are in dB.
// This would be useful in for example a compressor or distortion plugin.
CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_TRANSFER_CURVE = 3,
// This mini curve is intended to draw gain reduction over time. In this case
// x refers to the window in seconds and y refers to level in dB, x_min is
// always 0, and x_max would be the duration of the window.
// This would be useful in for example a compressor or limiter.
CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_GAIN_REDUCTION = 4,
// This curve is intended as a generic time series plot. In this case
// x refers to the window in seconds. x_min is always 0, and x_max would be the duration of the
// window.
// Y is not specified and up to the plugin.
CLAP_MINI_CURVE_DISPLAY_CURVE_KIND_TIME_SERIES = 5,
// Note: more entries could be added here in the future
};
typedef struct clap_mini_curve_display_curve_hints {
// Range for the x axis.
double x_min;
double x_max;
// Range for the y axis.
double y_min;
double y_max;
} clap_mini_curve_display_curve_hints_t;
// A set of points representing the curve to be painted.
typedef struct clap_mini_curve_display_curve_data {
// Indicates the kind of curve those values represent, the host can use this
// information to paint the curve using a meaningful color.
int32_t curve_kind;
// values[0] will be the leftmost value and values[data_size -1] will be the rightmost
// value.
//
// The value 0 and UINT16_MAX won't be painted.
// The value 1 will be at the bottom of the curve and UINT16_MAX - 1 will be at the top.
uint16_t *values;
uint32_t values_count;
} clap_mini_curve_display_curve_data_t;
typedef struct clap_plugin_mini_curve_display {
// Returns the number of curves the plugin wants to paint.
// Be aware that the space to display those curves will be small, and too much data will make
// the output hard to read.
uint32_t(CLAP_ABI *get_curve_count)(const clap_plugin_t *plugin);
// Renders the curve into each the curves buffer.
//
// curves is an array, and each entries (up to curves_size) contains pre-allocated
// values buffer that must be filled by the plugin.
//
// The host will "stack" the curves, from the first one to the last one.
// curves[0] is the first curve to be painted.
// curves[n + 1] will be painted over curves[n].
//
// Returns the number of curves rendered.
// [main-thread]
uint32_t(CLAP_ABI *render)(const clap_plugin_t *plugin,
clap_mini_curve_display_curve_data_t *curves,
uint32_t curves_size);
// Tells the plugin if the curve is currently observed or not.
// When it isn't observed render() can't be called.
//
// When is_obseverd becomes true, the curve content and axis name are implicitly invalidated. So
// the plugin don't need to call host->changed.
//
// [main-thread]
void(CLAP_ABI *set_observed)(const clap_plugin_t *plugin, bool is_observed);
// Retrives the axis name.
// x_name and y_name must not to be null.
// Returns true on success, if the name capacity was sufficient.
// [main-thread]
bool(CLAP_ABI *get_axis_name)(const clap_plugin_t *plugin,
uint32_t curve_index,
char *x_name,
char *y_name,
uint32_t name_capacity);
} clap_plugin_mini_curve_display_t;
enum clap_mini_curve_display_change_flags {
// Informs the host that the curve content changed.
// Can only be called if the curve is observed and is static.
CLAP_MINI_CURVE_DISPLAY_CURVE_CHANGED = 1 << 0,
// Informs the host that the curve axis name changed.
// Can only be called if the curve is observed.
CLAP_MINI_CURVE_DISPLAY_AXIS_NAME_CHANGED = 1 << 1,
};
typedef struct clap_host_mini_curve_display {
// Fills in the given clap_mini_display_curve_hints_t structure and returns
// true if successful. If not, return false.
// [main-thread]
bool(CLAP_ABI *get_hints)(const clap_host_t *host,
uint32_t kind,
clap_mini_curve_display_curve_hints_t *hints);
// Mark the curve as being static or dynamic.
// The curve is initially considered as static, though the plugin should explicitely
// initialize this state.
//
// When static, the curve changes will be notified by calling host->changed().
// When dynamic, the curve is constantly changing and the host is expected to
// periodically re-render.
//
// [main-thread]
void(CLAP_ABI *set_dynamic)(const clap_host_t *host, bool is_dynamic);
// See clap_mini_curve_display_change_flags
// [main-thread]
void(CLAP_ABI *changed)(const clap_host_t *host, uint32_t flags);
} clap_host_mini_curve_display_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,108 @@
#pragma once
#include "../../color.h"
#include "../../plugin.h"
#include "../../string-sizes.h"
// This extension allows a host to tell the plugin more about its position
// within a project or session.
static CLAP_CONSTEXPR const char CLAP_EXT_PROJECT_LOCATION[] = "clap.project-location/2";
#ifdef __cplusplus
extern "C" {
#endif
enum clap_project_location_kind {
// Represents a document/project/session.
CLAP_PROJECT_LOCATION_PROJECT = 1,
// Represents a group of tracks.
// It can contain track groups, tracks, and devices (post processing).
// The first device within a track group has the index of
// the last track or track group within this group + 1.
CLAP_PROJECT_LOCATION_TRACK_GROUP = 2,
// Represents a single track.
// It contains devices (serial).
CLAP_PROJECT_LOCATION_TRACK = 3,
// Represents a single device.
// It can contain other nested device chains.
CLAP_PROJECT_LOCATION_DEVICE = 4,
// Represents a nested device chain (serial).
// Its parent must be a device.
// It contains other devices.
CLAP_PROJECT_LOCATION_NESTED_DEVICE_CHAIN = 5,
};
enum clap_project_location_track_kind {
// This track is an instrument track.
CLAP_PROJECT_LOCATION_INSTUMENT_TRACK = 1,
// This track is an audio track.
CLAP_PROJECT_LOCATION_AUDIO_TRACK = 2,
// This track is both an instrument and audio track.
CLAP_PROJECT_LOCATION_HYBRID_TRACK = 3,
// This track is a return track.
CLAP_PROJECT_LOCATION_RETURN_TRACK = 4,
// This track is a master track.
// Each group have a master track for processing the sum of all its children tracks.
CLAP_PROJECT_LOCATION_MASTER_TRACK = 5,
};
enum clap_project_location_flags {
CLAP_PROJECT_LOCATION_HAS_INDEX = 1 << 0,
CLAP_PROJECT_LOCATION_HAS_COLOR = 1 << 1,
};
typedef struct clap_project_location_element {
// A bit-mask, see clap_project_location_flags.
uint64_t flags;
// Kind of the element, must be one of the CLAP_PROJECT_LOCATION_* values.
uint32_t kind;
// Only relevant if kind is CLAP_PLUGIN_LOCATION_TRACK.
// see enum CLAP_PROJECT_LOCATION_track_kind.
uint32_t track_kind;
// Index within the parent element.
// Only usable if CLAP_PROJECT_LOCATION_HAS_INDEX is set in flags.
uint32_t index;
// Internal ID of the element.
// This is not intended for display to the user,
// but rather to give the host a potential quick way for lookups.
char id[CLAP_PATH_SIZE];
// User friendly name of the element.
char name[CLAP_NAME_SIZE];
// Color for this element.
// Only usable if CLAP_PROJECT_LOCATION_HAS_COLOR is set in flags.
clap_color_t color;
} clap_project_location_element_t;
typedef struct clap_plugin_project_location {
// Called by the host when the location of the plugin instance changes.
//
// The last item in this array always refers to the device itself, and as
// such is expected to be of kind CLAP_PLUGIN_LOCATION_DEVICE.
// The first item in this array always refers to the project this device is in and must be of
// kind CLAP_PROJECT_LOCATION_PROJECT. The path is expected to be something like: PROJECT >
// TRACK_GROUP+ > TRACK > (DEVICE > NESTED_DEVICE_CHAIN)* > DEVICE
//
// [main-thread]
void(CLAP_ABI *set)(const clap_plugin_t *plugin,
const clap_project_location_element_t *path,
uint32_t num_elements);
} clap_plugin_project_location_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,88 @@
#pragma once
#include "../../plugin.h"
static CLAP_CONSTEXPR const char CLAP_EXT_RESOURCE_DIRECTORY[] = "clap.resource-directory/1";
#ifdef __cplusplus
extern "C" {
#endif
/// @page Resource Directory
///
/// This extension provides a way for the plugin to store its resources as file in a directory
/// provided by the host and recover them later on.
///
/// The plugin **must** store relative path in its state toward resource directories.
///
/// Resource sharing:
/// - shared directory is shared among all plugin instances, hence mostly appropriate for read-only
/// content
/// -> suitable for read-only content
/// - exclusive directory is exclusive to the plugin instance
/// -> if the plugin, then its exclusive directory must be duplicated too
/// -> suitable for read-write content
///
/// Keeping the shared directory clean:
/// - to avoid clashes in the shared directory, plugins are encouraged to organize their files in
/// sub-folders, for example create one subdirectory using the vendor name
/// - don't use symbolic links or hard links which points outside of the directory
///
/// Resource life-time:
/// - exclusive folder content is managed by the plugin instance
/// - exclusive folder content is deleted when the plugin instance is removed from the project
/// - shared folder content isn't managed by the host, until all plugins using the shared directory
/// are removed from the project
///
/// Note for the host
/// - try to use the filesystem's copy-on-write feature when possible for reducing exclusive folder
/// space usage on duplication
/// - host can "garbage collect" the files in the shared folder using:
/// clap_plugin_resource_directory.get_files_count()
/// clap_plugin_resource_directory.get_file_path()
/// but be **very** careful before deleting any resources
typedef struct clap_plugin_resource_directory {
// Sets the directory in which the plugin can save its resources.
// The directory remains valid until it is overridden or the plugin is destroyed.
// If path is null or blank, it clears the directory location.
// path must be absolute.
// [main-thread]
void(CLAP_ABI *set_directory)(const clap_plugin_t *plugin, const char *path, bool is_shared);
// Asks the plugin to put its resources into the resource directory.
// It is not necessary to collect files which belongs to the plugin's
// factory content unless the param all is true.
// [main-thread]
void(CLAP_ABI *collect)(const clap_plugin_t *plugin, bool all);
// Returns the number of files used by the plugin in the shared resource folder.
// [main-thread]
uint32_t(CLAP_ABI *get_files_count)(const clap_plugin_t *plugin);
// Retrieves relative file path to the resource directory.
// @param path writable memory to store the path
// @param path_size number of available bytes in path
// Returns the number of bytes in the path, or -1 on error
// [main-thread]
int32_t(CLAP_ABI *get_file_path)(const clap_plugin_t *plugin,
uint32_t index,
char *path,
uint32_t path_size);
} clap_plugin_resource_directory_t;
typedef struct clap_host_resource_directory {
// Request the host to setup a resource directory with the specified sharing.
// Returns true if the host will perform the request.
// [main-thread]
bool(CLAP_ABI *request_directory)(const clap_host_t *host, bool is_shared);
// Tell the host that the resource directory of the specified sharing is no longer required.
// If is_shared = false, then the host may delete the directory content.
// [main-thread]
void(CLAP_ABI *release_directory)(const clap_host_t *host, bool is_shared);
} clap_host_resource_directory_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,90 @@
#pragma once
#include "../../plugin.h"
// This extension lets the plugin request "scratch" memory from the host.
//
// The scratch memory is thread-local, and can be accessed during
// `clap_plugin->process()` and `clap_plugin_thread_pool->exec()`;
// its content is not persistent between callbacks.
//
// The motivation for this extension is to allow the plugin host
// to "share" a single scratch buffer across multiple plugin
// instances.
//
// For example, imagine the host needs to process N plugins
// in sequence, and each plugin requires 10K of scratch memory.
// If each plugin pre-allocates its own scratch memory, then N * 10K
// of memory is being allocated in total. However, if each plugin
// requests 10K of scratch memory from the host, then the host can
// allocate a single 10K scratch buffer, and make it available to all
// plugins.
//
// This optimization may allow for reduced memory usage and improved
// CPU cache usage.
static CLAP_CONSTEXPR const char CLAP_EXT_SCRATCH_MEMORY[] = "clap.scratch-memory/1";
#ifdef __cplusplus
extern "C" {
#endif
typedef struct clap_host_scratch_memory {
// Asks the host to reserve scratch memory.
//
// The plugin may call this method multiple times (for
// example, gradually decreasing the amount of scratch
// being asked for until the host returns true), however,
// the plugin should avoid calling this method un-neccesarily
// since the host implementation may be relatively expensive.
// If the plugin calls `reserve()` multiple times, then the
// last call invalidates all previous calls.
//
// De-activating the plugin releases the scratch memory.
//
// `max_concurrency_hint` is an optional hint which indicates
// the maximum number of threads concurrently accessing the scratch memory.
// Set to 0 if unspecified.
//
// Returns true on success.
//
// [main-thread & being-activated]
bool(CLAP_ABI *reserve)(const clap_host_t *host,
uint32_t scratch_size_bytes,
uint32_t max_concurrency_hint);
// Returns a pointer to the "thread-local" scratch memory.
//
// If the scratch memory wasn't successfully reserved, returns NULL.
//
// If the plugin crosses `max_concurrency_hint`, then the return value
// is either NULL or a valid scratch memory pointer.
//
// This method may only be called by the plugin from the audio thread,
// (i.e. during the process() or thread_pool.exec() callback), and
// the provided memory is only valid until the plugin returns from
// that callback. The plugin must not hold any references to data
// that lives in the scratch memory after returning from the callback,
// as that data will likely be over-written by another plugin using
// the same scratch memory.
//
// The provided memory is not initialized, and may have been used
// by other plugin instances, so the plugin must correctly initialize
// the memory when using it.
//
// The provided memory is owned by the host, so the plugin must not
// free the memory.
//
// If the plugin wants to share the same scratch memory pointer with
// many threads, it must access the the scratch at the beginning of the
// `process()` callback, cache the returned pointer before calling
// `clap_host_thread_pool->request_exec()` and clear the cached pointer
// before returning from `process()`.
//
// [audio-thread]
void *(CLAP_ABI *access)(const clap_host_t *host);
} clap_host_scratch_memory_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,66 @@
#pragma once
#include "../../plugin.h"
// This extension lets the plugin submit transport requests to the host.
// The host has no obligation to execute these requests, so the interface may be
// partially working.
static CLAP_CONSTEXPR const char CLAP_EXT_TRANSPORT_CONTROL[] = "clap.transport-control/1";
#ifdef __cplusplus
extern "C" {
#endif
typedef struct clap_host_transport_control {
// Jumps back to the start point and starts the transport
// [main-thread]
void(CLAP_ABI *request_start)(const clap_host_t *host);
// Stops the transport, and jumps to the start point
// [main-thread]
void(CLAP_ABI *request_stop)(const clap_host_t *host);
// If not playing, starts the transport from its current position
// [main-thread]
void(CLAP_ABI *request_continue)(const clap_host_t *host);
// If playing, stops the transport at the current position
// [main-thread]
void(CLAP_ABI *request_pause)(const clap_host_t *host);
// Equivalent to what "space bar" does with most DAWs
// [main-thread]
void(CLAP_ABI *request_toggle_play)(const clap_host_t *host);
// Jumps the transport to the given position.
// Does not start the transport.
// [main-thread]
void(CLAP_ABI *request_jump)(const clap_host_t *host, clap_beattime position);
// Sets the loop region
// [main-thread]
void(CLAP_ABI *request_loop_region)(const clap_host_t *host,
clap_beattime start,
clap_beattime duration);
// Toggles looping
// [main-thread]
void(CLAP_ABI *request_toggle_loop)(const clap_host_t *host);
// Enables/Disables looping
// [main-thread]
void(CLAP_ABI *request_enable_loop)(const clap_host_t *host, bool is_enabled);
// Enables/Disables recording
// [main-thread]
void(CLAP_ABI *request_record)(const clap_host_t *host, bool is_recording);
// Toggles recording
// [main-thread]
void(CLAP_ABI *request_toggle_record)(const clap_host_t *host);
} clap_host_transport_control_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,144 @@
#pragma once
#include "../../plugin.h"
#include "../../events.h"
#include "../../string-sizes.h"
static CLAP_CONSTEXPR const char CLAP_EXT_TRIGGERS[] = "clap.triggers/1";
#ifdef __cplusplus
extern "C" {
#endif
/// @page Trigger events
///
/// This extension enables the plugin to expose a set of triggers to the host.
///
/// Some examples for triggers:
/// - trigger an envelope which is independent of the notes
/// - trigger a sample-and-hold unit (maybe even per-voice)
enum {
// Does this trigger support per note automations?
CLAP_TRIGGER_IS_AUTOMATABLE_PER_NOTE_ID = 1 << 0,
// Does this trigger support per key automations?
CLAP_TRIGGER_IS_AUTOMATABLE_PER_KEY = 1 << 1,
// Does this trigger support per channel automations?
CLAP_TRIGGER_IS_AUTOMATABLE_PER_CHANNEL = 1 << 2,
// Does this trigger support per port automations?
CLAP_TRIGGER_IS_AUTOMATABLE_PER_PORT = 1 << 3,
};
typedef uint32_t clap_trigger_info_flags;
// Given that this extension is still draft, it'll use the event-registry and its own event
// namespace until we stabilize it.
//
// #include <clap/ext/event-registry.h>
//
// uint16_t CLAP_EXT_TRIGGER_EVENT_SPACE_ID = UINT16_MAX;
// if (host_event_registry->query(host, CLAP_EXT_TRIGGERS, &CLAP_EXT_TRIGGER_EVENT_SPACE_ID)) {
// /* we can use trigger events */
// }
//
// /* later on */
// clap_event_trigger ev;
// ev.header.space_id = CLAP_EXT_TRIGGER_EVENT_SPACE_ID;
// ev.header.type = CLAP_EVENT_TRIGGER;
enum { CLAP_EVENT_TRIGGER = 0 };
typedef struct clap_event_trigger {
clap_event_header_t header;
// target trigger
clap_id trigger_id; // @ref clap_trigger_info.id
void *cookie; // @ref clap_trigger_info.cookie
// target a specific note_id, port, key and channel, -1 for global
int32_t note_id;
int16_t port_index;
int16_t channel;
int16_t key;
} clap_event_trigger_t;
/* This describes a trigger */
typedef struct clap_trigger_info {
// stable trigger identifier, it must never change.
clap_id id;
clap_trigger_info_flags flags;
// in analogy to clap_param_info.cookie
void *cookie;
// displayable name
char name[CLAP_NAME_SIZE];
// the module path containing the trigger, eg:"sequencers/seq1"
// '/' will be used as a separator to show a tree like structure.
char module[CLAP_PATH_SIZE];
} clap_trigger_info_t;
typedef struct clap_plugin_triggers {
// Returns the number of triggers.
// [main-thread]
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin);
// Copies the trigger's info to trigger_info and returns true on success.
// [main-thread]
bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin,
uint32_t index,
clap_trigger_info_t *trigger_info);
} clap_plugin_triggers_t;
enum {
// The trigger info did change, use this flag for:
// - name change
// - module change
// New info takes effect immediately.
CLAP_TRIGGER_RESCAN_INFO = 1 << 0,
// Invalidates everything the host knows about triggers.
// It can only be used while the plugin is deactivated.
// If the plugin is activated use clap_host->restart() and delay any change until the host calls
// clap_plugin->deactivate().
//
// You must use this flag if:
// - some triggers were added or removed.
// - some triggers had critical changes:
// - is_per_note (flag)
// - is_per_key (flag)
// - is_per_channel (flag)
// - is_per_port (flag)
// - cookie
CLAP_TRIGGER_RESCAN_ALL = 1 << 1,
};
typedef uint32_t clap_trigger_rescan_flags;
enum {
// Clears all possible references to a trigger
CLAP_TRIGGER_CLEAR_ALL = 1 << 0,
// Clears all automations to a trigger
CLAP_TRIGGER_CLEAR_AUTOMATIONS = 1 << 1,
};
typedef uint32_t clap_trigger_clear_flags;
typedef struct clap_host_triggers {
// Rescan the full list of triggers according to the flags.
// [main-thread]
void(CLAP_ABI *rescan)(const clap_host_t *host, clap_trigger_rescan_flags flags);
// Clears references to a trigger.
// [main-thread]
void(CLAP_ABI *clear)(const clap_host_t *host,
clap_id trigger_id,
clap_trigger_clear_flags flags);
} clap_host_triggers_t;
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,76 @@
#pragma once
#include "../../plugin.h"
#include "../../events.h"
#include "../../string-sizes.h"
static CLAP_CONSTEXPR const char CLAP_EXT_TUNING[] = "clap.tuning/2";
#ifdef __cplusplus
extern "C" {
#endif
// Use clap_host_event_registry->query(host, CLAP_EXT_TUNING, &space_id) to know the event space.
//
// This event defines the tuning to be used on the given port/channel.
typedef struct clap_event_tuning {
clap_event_header_t header;
int16_t port_index; // -1 global
int16_t channel; // 0..15, -1 global
clap_id tunning_id;
} clap_event_tuning_t;
typedef struct clap_tuning_info {
clap_id tuning_id;
char name[CLAP_NAME_SIZE];
bool is_dynamic; // true if the values may vary with time
} clap_tuning_info_t;
typedef struct clap_plugin_tuning {
// Called when a tuning is added or removed from the pool.
// [main-thread]
void(CLAP_ABI *changed)(const clap_plugin_t *plugin);
} clap_plugin_tuning_t;
// This extension provides a dynamic tuning table to the plugin.
typedef struct clap_host_tuning {
// Gets the relative tuning in semitones against equal temperament with A4=440Hz.
// The plugin may query the tuning at a rate that makes sense for *low* frequency modulations.
//
// If the tuning_id is not found or equals to CLAP_INVALID_ID,
// then the function shall gracefully return a sensible value.
//
// sample_offset is the sample offset from the beginning of the current process block.
//
// should_play(...) should be checked before calling this function.
//
// [audio-thread & in-process]
double(CLAP_ABI *get_relative)(const clap_host_t *host,
clap_id tuning_id,
int32_t channel,
int32_t key,
uint32_t sample_offset);
// Returns true if the note should be played.
// [audio-thread & in-process]
bool(CLAP_ABI *should_play)(const clap_host_t *host,
clap_id tuning_id,
int32_t channel,
int32_t key);
// Returns the number of tunings in the pool.
// [main-thread]
uint32_t(CLAP_ABI *get_tuning_count)(const clap_host_t *host);
// Gets info about a tuning
// Returns true on success and stores the result into info.
// [main-thread]
bool(CLAP_ABI *get_info)(const clap_host_t *host,
uint32_t tuning_index,
clap_tuning_info_t *info);
} clap_host_tuning_t;
#ifdef __cplusplus
}
#endif

201
tests/clap/ext/draft/undo.h Normal file
View file

@ -0,0 +1,201 @@
#pragma once
#include "../../plugin.h"
#include "../../stream.h"
static CLAP_CONSTEXPR const char CLAP_EXT_UNDO[] = "clap.undo/4";
static CLAP_CONSTEXPR const char CLAP_EXT_UNDO_CONTEXT[] = "clap.undo_context/4";
static CLAP_CONSTEXPR const char CLAP_EXT_UNDO_DELTA[] = "clap.undo_delta/4";
#ifdef __cplusplus
extern "C" {
#endif
/// @page Undo
///
/// This extension enables the plugin to merge its undo history with the host.
/// This leads to a single undo history shared by the host and many plugins.
///
/// Calling host->undo() or host->redo() is equivalent to clicking undo/redo within the host's GUI.
///
/// If the plugin uses this interface then its undo and redo should be entirely delegated to
/// the host; clicking in the plugin's UI undo or redo is equivalent to clicking undo or redo in the
/// host's UI.
///
/// Some changes are long running changes, for example a mouse interaction will begin editing some
/// complex data and it may take multiple events and a long duration to complete the change.
/// In such case the plugin will call host->begin_change() to indicate the beginning of a long
/// running change and complete the change by calling host->change_made().
///
/// The host may group changes together:
/// [---------------------------------]
/// ^-T0 ^-T1 ^-T2 ^-T3
/// Here a long running change C0 begin at T0.
/// A instantaneous change C1 at T1, and another one C2 at T2.
/// Then at T3 the long running change is completed.
/// The host will then create a single undo step that will merge all the changes into C0.
///
/// This leads to another important consideration: starting a long running change without
/// terminating is **VERY BAD**, because while a change is running it is impossible to call undo or
/// redo.
///
/// Rationale: multiple designs were considered and this one has the benefit of having a single undo
/// history. This simplifies the host implementation, leading to less bugs, a more robust design
/// and maybe an easier experience for the user because there's a single undo context versus one
/// for the host and one for each plugin instance.
///
/// This extension tries to make it as easy as possible for the plugin to hook into the host undo
/// and make it efficient when possible by using deltas. The plugin interfaces are all optional, and
/// the plugin can for a minimal implementation, just use the host interface and call
/// host->change_made() without providing a delta. This is enough for the host to know that it can
/// capture a plugin state for the undo step.
typedef struct clap_undo_delta_properties {
// If true, then the plugin will provide deltas in host->change_made().
// If false, then all clap_undo_delta_properties's attributes become irrelevant.
bool has_delta;
// If true, then the deltas can be stored on disk and re-used in the future as long as the plugin
// is compatible with the given format_version.
//
// If false, then format_version must be set to CLAP_INVALID_ID.
bool are_deltas_persistent;
// This represents the delta format version that the plugin is currently using.
// Use CLAP_INVALID_ID for invalid value.
clap_id format_version;
} clap_undo_delta_properties_t;
// Use CLAP_EXT_UNDO_DELTA.
// This is an optional interface, using deltas is an optimization versus making a state snapshot.
typedef struct clap_plugin_undo_delta {
// Asks the plugin the delta properties.
// [main-thread]
void(CLAP_ABI *get_delta_properties)(const clap_plugin_t *plugin,
clap_undo_delta_properties_t *properties);
// Asks the plugin if it can apply a delta using the given format version.
// Returns true if it is possible.
// [main-thread]
bool(CLAP_ABI *can_use_delta_format_version)(const clap_plugin_t *plugin,
clap_id format_version);
// Undo using the delta.
// Returns true on success.
//
// [main-thread]
bool(CLAP_ABI *undo)(const clap_plugin_t *plugin,
clap_id format_version,
const void *delta,
size_t delta_size);
// Redo using the delta.
// Returns true on success.
//
// [main-thread]
bool(CLAP_ABI *redo)(const clap_plugin_t *plugin,
clap_id format_version,
const void *delta,
size_t delta_size);
} clap_plugin_undo_delta_t;
// Use CLAP_EXT_UNDO_CONTEXT.
// This is an optional interface, that the plugin can implement in order to know about
// the current undo context.
typedef struct clap_plugin_undo_context {
// Indicate if it is currently possible to perform an undo or redo operation.
// [main-thread & plugin-subscribed-to-undo-context]
void(CLAP_ABI *set_can_undo)(const clap_plugin_t *plugin, bool can_undo);
void(CLAP_ABI *set_can_redo)(const clap_plugin_t *plugin, bool can_redo);
// Sets the name of the next undo or redo step.
// name: null terminated string.
// [main-thread & plugin-subscribed-to-undo-context]
void(CLAP_ABI *set_undo_name)(const clap_plugin_t *plugin, const char *name);
void(CLAP_ABI *set_redo_name)(const clap_plugin_t *plugin, const char *name);
} clap_plugin_undo_context_t;
// Use CLAP_EXT_UNDO.
typedef struct clap_host_undo {
// Begins a long running change.
// The plugin must not call this twice: there must be either a call to cancel_change() or
// change_made() before calling begin_change() again.
// [main-thread]
void(CLAP_ABI *begin_change)(const clap_host_t *host);
// Cancels a long running change.
// cancel_change() must not be called without a preceding begin_change().
// [main-thread]
void(CLAP_ABI *cancel_change)(const clap_host_t *host);
// Completes an undoable change.
// At the moment of this function call, plugin_state->save() would include the current change.
//
// name: mandatory null terminated string describing the change, this is displayed to the user
//
// delta: optional, it is a binary blobs used to perform the undo and redo. When not available
// the host will save the plugin state and use state->load() to perform undo and redo.
// The plugin must be able to perform a redo operation using the delta, though the undo operation
// is only possible if delta_can_undo is true.
//
// Note: the provided delta may be used for incremental state saving and crash recovery. The
// plugin can indicate a format version id and the validity lifetime for the binary blobs.
// The host can use these to verify the compatibility before applying the delta.
// If the plugin is unable to use a delta, a notification should be provided to the user and
// the crash recovery should perform a best effort job, at least restoring the latest saved
// state.
//
// Special case: for objects with shared and synchronized state, changes shouldn't be reported
// as the host already knows about it.
// For example, plugin parameter changes shouldn't produce a call to change_made().
//
// Note: if the plugin asked for this interface, then host_state->mark_dirty() will not create an
// implicit undo step.
//
// Note: if the plugin did load a preset or did something that leads to a large delta,
// it may consider not producing a delta (pass null) and let the host make a state snapshot
// instead.
//
// Note: if a plugin is producing a lot of changes within a small amount of time, the host
// may merge them into a single undo step.
//
// [main-thread]
void(CLAP_ABI *change_made)(const clap_host_t *host,
const char *name,
const void *delta,
size_t delta_size,
bool delta_can_undo);
// Asks the host to perform the next undo or redo step.
//
// Note: this maybe a complex and asynchronous operation, which may complete after
// this function returns.
//
// Note: the host may ignore this request if there is no undo/redo step to perform,
// or if the host is unable to perform undo/redo at the time (eg: a long running
// change is going on).
//
// [main-thread]
void(CLAP_ABI *request_undo)(const clap_host_t *host);
void(CLAP_ABI *request_redo)(const clap_host_t *host);
// Subscribes to or unsubscribes from undo context info.
//
// This method helps reducing the number of calls the host has to perform when updating
// the undo context info. Consider a large project with 1000+ plugins, we don't want to
// call 1000+ times update, while the plugin may only need the context info if its GUI
// is shown and it wants to display undo/redo info.
//
// Initial state is unsubscribed.
//
// is_subscribed: set to true to receive context info
//
// It is mandatory for the plugin to implement CLAP_EXT_UNDO_CONTEXT when using this method.
//
// [main-thread]
void(CLAP_ABI *set_wants_context_updates)(const clap_host_t *host, bool is_subscribed);
} clap_host_undo_t;
#ifdef __cplusplus
}
#endif