clap

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

commit fc4ba16a4ebcf5d18bbee9efb69a369c854e081f
parent 2b31ad43c20466ab9bd7e91f4ec86771b50c120c
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Wed,  5 Jan 2022 10:34:09 +0100

Merge branch 'next'

Diffstat:
Minclude/clap/chmap.h | 7++-----
Minclude/clap/clap.h | 5+++--
Minclude/clap/color.h | 2+-
Minclude/clap/entry.h | 12++++++++++++
Minclude/clap/events.h | 204++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Ainclude/clap/ext/draft/ambisonic.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/clap/ext/event-filter.h | 2+-
Ainclude/clap/ext/event-registry.h | 26++++++++++++++++++++++++++
Dinclude/clap/ext/fd-support.h | 53-----------------------------------------------------
Minclude/clap/ext/gui.h | 24+++++++++++++++++++-----
Minclude/clap/ext/note-ports.h | 12++++++++++--
Minclude/clap/ext/params.h | 6+++---
Ainclude/clap/ext/posix-fd-support.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Minclude/clap/plugin-factory.h | 2++
Minclude/clap/plugin.h | 74++++++++++++++++++++++++++++++++++----------------------------------------
Minclude/clap/process.h | 25++++++++++++++++++++-----
Minclude/clap/version.h | 22+++++++++++-----------
17 files changed, 363 insertions(+), 208 deletions(-)

diff --git a/include/clap/chmap.h b/include/clap/chmap.h @@ -16,11 +16,8 @@ enum { // see clap_plugin_surround to inspect the exact channel layout CLAP_CHMAP_SURROUND = 3, - // FuMa channel ordering - CLAP_CHMAP_AMBISONIC_FUMA = 4, - - // ACN channel ordering - CLAP_CHMAP_AMBISONIC_ACN = 5, + // see clap_plugin_ambisonic to inspect the mapping + CLAP_CHMAP_AMBISONIC = 4, }; typedef int32_t clap_chmap; diff --git a/include/clap/clap.h b/include/clap/clap.h @@ -2,7 +2,7 @@ * CLAP - CLever Audio Plugin * ~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * Copyright (c) 2014...2021 Alexandre BIQUE <bique.alexandre@gmail.com> + * Copyright (c) 2014...2022 Alexandre BIQUE <bique.alexandre@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,11 +46,12 @@ #include "ext/latency.h" #include "ext/thread-check.h" #include "ext/timer-support.h" -#include "ext/fd-support.h" +#include "ext/posix-fd-support.h" #include "ext/note-name.h" #include "ext/note-ports.h" #include "ext/event-filter.h" #include "ext/thread-pool.h" +#include "ext/event-registry.h" #include "ext/draft/preset-load.h" #include "ext/draft/quick-controls.h" diff --git a/include/clap/color.h b/include/clap/color.h @@ -9,10 +9,10 @@ extern "C" { #pragma pack(push, 1) typedef struct clap_color { + uint8_t alpha; uint8_t red; uint8_t green; uint8_t blue; - uint8_t alpha; } clap_color_t; #pragma pack(pop) diff --git a/include/clap/entry.h b/include/clap/entry.h @@ -13,6 +13,18 @@ extern "C" { // This interface is the entry point of the dynamic library. // +// CLAP plugins standard search path: +// +// Linux +// - /usr/lib/clap/ +// - To Be Defined: ~/.clap or ~/.local/lib/clap/ for user location +// +// Windows +// - %CommonFilesFolder%/CLAP/ +// +// MacOS +// - /Library/Audio/Plug-Ins/CLAP +// // Every methods must be thread-safe. typedef struct clap_plugin_entry { clap_version_t clap_version; // initialized to CLAP_VERSION diff --git a/include/clap/events.h b/include/clap/events.h @@ -12,18 +12,80 @@ extern "C" { #pragma pack(push, CLAP_ALIGN) +// event header +// must be the first attribute of the event +typedef struct clap_event_header { + alignas(4) uint32_t size; // event size including this header, eg: sizeof (clap_event_note) + alignas(4) uint32_t time; // time at which the event happens + alignas(2) uint16_t space_id; // event space, see clap_host_event_registry + alignas(2) uint16_t type; // event type + alignas(4) uint32_t flags; // see clap_event_flags +} clap_event_header_t; + +// The clap core event space +static const CLAP_CONSTEXPR uint16_t CLAP_CORE_EVENT_SPACE_ID = 0; + +enum clap_event_flags { + // indicate a live momentary event + CLAP_EVENT_IS_LIVE = 1 << 0, + + // live user adjustment begun + CLAP_EVENT_BEGIN_ADJUST = 1 << 1, + + // live user adjustment ended + CLAP_EVENT_END_ADJUST = 1 << 2, + + // should record this event be recorded? + CLAP_EVENT_SHOULD_RECORD = 1 << 3, +}; + +// Some of the following events overlap, a note on can be expressed with: +// - CLAP_EVENT_NOTE_ON +// - CLAP_EVENT_MIDI +// - CLAP_EVENT_MIDI2 +// +// The preferred way of sending a note event is to use CLAP_EVENT_NOTE_*. +// +// The same event must not be sent twice: it is forbidden to send a the same note on +// encoded with both CLAP_EVENT_NOTE_ON and CLAP_EVENT_MIDI. +// +// The plugins are encouraged to be able to handle note events encoded as raw midi or midi2, +// or implement clap_plugin_event_filter and reject raw midi and midi2 events. enum { - CLAP_EVENT_NOTE_ON, // press a key; note attribute - CLAP_EVENT_NOTE_OFF, // release a key; note attribute - CLAP_EVENT_NOTE_END, // playback of a note is terminated (sent by the plugin); note attribute - CLAP_EVENT_NOTE_CHOKE, // chokes a set of notes; note attribute - CLAP_EVENT_NOTE_EXPRESSION, // plays standard note expression; note_expression attribute - CLAP_EVENT_NOTE_MASK, // current chord/scale; note_mask attribute - CLAP_EVENT_PARAM_VALUE, // sets a parameter value; param_value attribute - CLAP_EVENT_PARAM_MOD, // sets a parameter modulation; param_mod attribute - CLAP_EVENT_TRANSPORT, // update the transport info; transport attribute - CLAP_EVENT_MIDI, // raw midi event; midi attribute - CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; midi_sysex attribute + // NOTE_ON and NOTE_OFF represents a key pressed and key released event. + // + // NOTE_CHOKE is meant to choke the voice(s), like in a drum machine when a closed hihat + // chokes an open hihat. + // + // NOTE_END is sent by the plugin to the host, when a voice terminates. + // When using polyphonic modulations, the host has to start voices for its modulators. + // This message helps the host to track the plugin's voice management. + // + // Those four events use the note attribute. + CLAP_EVENT_NOTE_ON, + CLAP_EVENT_NOTE_OFF, + CLAP_EVENT_NOTE_CHOKE, + CLAP_EVENT_NOTE_END, + + // Represents a note expression. + // Uses the note_expression attribute. + CLAP_EVENT_NOTE_EXPRESSION, + + // PARAM_VALUE sets the parameter's value; uses param_value attribute + // PARAM_MOD sets the parameter's modulation amount; uses param_mod attribute + // + // The value heard is: param_value + param_mod. + // + // In case of a concurrent global value/modulation versus a polyphonic one, + // the voice should only use the polyphonic one and the polyphonic modulation + // amount will already include the monophonic signal. + CLAP_EVENT_PARAM_VALUE, + CLAP_EVENT_PARAM_MOD, + + CLAP_EVENT_TRANSPORT, // update the transport info; transport attribute + CLAP_EVENT_MIDI, // raw midi event; midi attribute + CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; midi_sysex attribute + CLAP_EVENT_MIDI2, // raw midi 2 event; midi2 attribute }; typedef int32_t clap_event_type; @@ -34,10 +96,12 @@ typedef int32_t clap_event_type; * - key and channel are used to match active notes, a value of -1 matches all. */ typedef struct clap_event_note { - int32_t port_index; - int32_t key; // 0..127 - int32_t channel; // 0..15 - double velocity; // 0..1 + alignas(4) clap_event_header_t header; + + alignas(2) int16_t port_index; + alignas(2) int16_t key; // 0..127 + alignas(2) int16_t channel; // 0..15 + alignas(8) double velocity; // 0..1 } clap_event_note_t; enum { @@ -62,57 +126,49 @@ enum { typedef int32_t clap_note_expression; typedef struct clap_event_note_expression { + alignas(4) clap_event_header_t header; + alignas(4) clap_note_expression expression_id; // target a specific port, key and channel, -1 for global - alignas(4) int32_t port_index; - alignas(4) int32_t key; - alignas(4) int32_t channel; + alignas(2) int16_t port_index; + alignas(2) int16_t key; + alignas(2) int16_t channel; alignas(8) double value; // see expression for the range } clap_event_note_expression_t; -enum { - // live user adjustment begun - CLAP_EVENT_PARAM_BEGIN_ADJUST = 1 << 0, - - // live user adjustment ended - CLAP_EVENT_PARAM_END_ADJUST = 1 << 1, - - // should record this parameter change and create an automation point? - CLAP_EVENT_PARAM_SHOULD_RECORD = 1 << 2, -}; -typedef int32_t clap_event_param_flags; - typedef struct clap_event_param_value { + alignas(4) clap_event_header_t header; + // target parameter void *cookie; // @ref clap_param_info.cookie alignas(4) clap_id param_id; // @ref clap_param_info.id // target a specific port, key and channel, -1 for global - alignas(4) int32_t port_index; - alignas(4) int32_t key; - alignas(4) int32_t channel; - - alignas(4) clap_event_param_flags flags; + alignas(2) int16_t port_index; + alignas(2) int16_t key; + alignas(2) int16_t channel; alignas(8) double value; } clap_event_param_value_t; typedef struct clap_event_param_mod { + alignas(4) clap_event_header_t header; + // target parameter - void *cookie; // @ref clap_param_info.cookie alignas(4) clap_id param_id; // @ref clap_param_info.id + void *cookie; // @ref clap_param_info.cookie // target a specific port, key and channel, -1 for global - alignas(4) int32_t port_index; - alignas(4) int32_t key; - alignas(4) int32_t channel; + alignas(2) int16_t port_index; + alignas(2) int16_t key; + alignas(2) int16_t channel; alignas(8) double amount; // modulation amount } clap_event_param_mod_t; -enum { +enum clap_transport_flags { CLAP_TRANSPORT_HAS_TEMPO = 1 << 0, CLAP_TRANSPORT_HAS_BEATS_TIMELINE = 1 << 1, CLAP_TRANSPORT_HAS_SECONDS_TIMELINE = 1 << 2, @@ -122,10 +178,11 @@ enum { CLAP_TRANSPORT_IS_LOOP_ACTIVE = 1 << 6, CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL = 1 << 7, }; -typedef uint32_t clap_transport_flags; typedef struct clap_event_transport { - alignas(4) clap_transport_flags flags; + alignas(4) clap_event_header_t header; + + alignas(4) uint32_t flags; // see clap_transport_flags alignas(8) clap_beattime song_pos_beats; // position in beats alignas(8) clap_sectime song_pos_seconds; // position in seconds @@ -146,58 +203,45 @@ typedef struct clap_event_transport { alignas(2) int16_t tsig_denom; // time signature denominator } clap_event_transport_t; -typedef struct clap_event_note_mask { - uint32_t port_index; - - // bitset of active keys: - // - 11 bits - // - root note is not part of the bitset - // - bit N is: root note + N + 1 - // 000 0100 0100 -> minor chord - // 000 0100 1000 -> major chord - // 010 1011 0101 -> locrian scale - alignas(2) uint16_t note_mask; - alignas(1) uint8_t root_note; // 0..11, 0 for C -} clap_event_note_mask_t; - typedef struct clap_event_midi { - alignas(4) uint32_t port_index; + alignas(4) clap_event_header_t header; + + alignas(2) uint16_t port_index; alignas(1) uint8_t data[3]; } clap_event_midi_t; typedef struct clap_event_midi_sysex { - alignas(4) uint32_t port_index; + alignas(4) clap_event_header_t header; + + alignas(2) uint16_t port_index; const uint8_t *buffer; // midi buffer alignas(4) uint32_t size; } clap_event_midi_sysex_t; -typedef struct clap_event { - alignas(4) clap_event_type type; - alignas(4) uint32_t time; // offset from the first sample in the process block - - union { - clap_event_note_t note; - clap_event_note_expression_t note_expression; - clap_event_param_value_t param_value; - clap_event_param_mod_t param_mod; - clap_event_transport_t time_info; - clap_event_note_mask_t note_mask; - clap_event_midi_t midi; - clap_event_midi_sysex_t midi_sysex; - }; -} clap_event_t; - -typedef struct clap_event_list { +typedef struct clap_event_midi2 { + alignas(4) clap_event_header_t header; + + alignas(2) uint16_t port_index; + alignas(4) uint32_t data[4]; +} clap_event_midi2_t; + +// Input event list, events must be sorted by time. +typedef struct clap_input_events { void *ctx; // reserved pointer for the list - uint32_t (*size)(const struct clap_event_list *list); + uint32_t (*size)(const struct clap_input_events *list); // Don't free the return event, it belongs to the list - const clap_event_t *(*get)(const struct clap_event_list *list, uint32_t index); + const clap_event_header_t *(*get)(const struct clap_input_events *list, uint32_t index); +} clap_input_events_t; + +// Output event list, events must be sorted by time. +typedef struct clap_output_events { + void *ctx; // reserved pointer for the list - // Makes a copy of the event - void (*push_back)(const struct clap_event_list *list, const clap_event_t *event); -} clap_event_list_t; + // Pushes a copy of the event + void (*push_back)(const struct clap_output_events *list, const clap_event_header_t *event); +} clap_output_events_t; #pragma pack(pop) diff --git a/include/clap/ext/draft/ambisonic.h b/include/clap/ext/draft/ambisonic.h @@ -0,0 +1,49 @@ +#pragma once + +#include "../../plugin.h" + +// This extension can be used to specify the channel mapping used by the plugin. + +static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC[] = "clap.ambisonic.draft/0"; + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push, CLAP_ALIGN) + +enum { + // FuMa channel ordering + CLAP_AMBISONIC_FUMA = 0, + + // ACN channel ordering + CLAP_AMBISONIC_ACN = 1, +}; + +typedef struct clap_ambisonic_info { + alignas(4) uint32_t ordering; + alignas(1) bool is_normalized; +} clap_ambisonic_info_t; + +typedef struct clap_plugin_ambisonic { + // Returns true on success + // [main-thread] + bool (*get_info)(const clap_plugin_t *plugin, + bool is_input, + uint32_t port_index, + clap_ambisonic_info_t *info); + +} clap_plugin_ambisonic_t; + +typedef struct clap_host_ambisonic { + // Informs the host that the info have changed. + // The info can only change when the plugin is de-activated. + // [main-thread] + void (*changed)(const clap_host_t *host); +} clap_host_ambisonic_t; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/event-filter.h b/include/clap/ext/event-filter.h @@ -17,7 +17,7 @@ extern "C" { typedef struct clap_plugin_event_filter { // Returns true if the plugin is interested in the given event type. // [main-thread] - bool (*accepts)(const clap_plugin_t *plugin, clap_event_type event_type); + bool (*accepts)(const clap_plugin_t *plugin, uint16_t space_id, uint16_t event_type); } clap_plugin_event_filter_t; diff --git a/include/clap/ext/event-registry.h b/include/clap/ext/event-registry.h @@ -0,0 +1,26 @@ +#pragma once + +#include "../plugin.h" + +static CLAP_CONSTEXPR const char CLAP_EXT_EVENT_REGISTRY[] = "clap.event-registry"; + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push, CLAP_ALIGN) + +typedef struct clap_host_event_registry { + // Queries an event space id. + // The space id 0 is reserved for CLAP's core events. See CLAP_CORE_EVENT_SPACE. + // + // Return false and sets *space to UINT16_MAX if the space name is unknown to the host. + // [main-thread] + bool (*query)(const clap_host_t *host, const char *space_name, uint16_t *space_id); +} clap_host_event_registry_t; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/ext/fd-support.h b/include/clap/ext/fd-support.h @@ -1,52 +0,0 @@ -#pragma once - -#include "../plugin.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_FD_SUPPORT[] = "clap.fd-support"; - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push, CLAP_ALIGN) - -#ifdef _WIN32 -typedef void *clap_fd; -#else -typedef int clap_fd; -#endif - -enum { - // IO events - CLAP_FD_READ = 1 << 0, - CLAP_FD_WRITE = 1 << 1, - CLAP_FD_ERROR = 1 << 2, -}; -typedef uint32_t clap_fd_flags; - -typedef struct clap_plugin_fd_support { - // This callback is "level-triggered". - // It means that a writable fd will continuously produce "on_fd()" events; - // don't forget using modify_fd() to remove the write notification once you're - // done writting. - // - // [main-thread] - void (*on_fd)(const clap_plugin_t *plugin, clap_fd fd, clap_fd_flags flags); -} clap_plugin_fd_support_t; - -typedef struct clap_host_fd_support { - // [main-thread] - bool (*register_fd)(const clap_host_t *host, clap_fd fd, clap_fd_flags flags); - - // [main-thread] - bool (*modify_fd)(const clap_host_t *host, clap_fd fd, clap_fd_flags flags); - - // [main-thread] - bool (*unregister_fd)(const clap_host_t *host, clap_fd fd); -} clap_host_fd_support_t; - -#pragma pack(pop) - -#ifdef __cplusplus -} -#endif -\ No newline at end of file diff --git a/include/clap/ext/gui.h b/include/clap/ext/gui.h @@ -41,9 +41,13 @@ typedef struct clap_plugin_gui { // [main-thread] void (*destroy)(const clap_plugin_t *plugin); - // Set the absolute GUI scaling factor. - // [main-thread] - void (*set_scale)(const clap_plugin_t *plugin, double scale); + // Set the absolute GUI scaling factor, and override any OS info. + // If the plugin does not provide this function, then it should work out the scaling factor + // itself by querying the OS directly. + // + // Return false if the plugin can't apply the scaling; true on success. + // [main-thread,optional] + bool (*set_scale)(const clap_plugin_t *plugin, double scale); // Get the current size of the plugin UI, with the scaling applied. // clap_plugin_gui->create() must have been called prior to asking the size. @@ -79,8 +83,18 @@ typedef struct clap_plugin_gui { typedef struct clap_host_gui { /* Request the host to resize the client area to width, height. * Return true on success, false otherwise. - * [thread-safe] */ - bool (*resize)(const clap_host_t *host, uint32_t width, uint32_t height); + * [main-thread] */ + bool (*request_resize)(const clap_host_t *host, uint32_t width, uint32_t height); + + /* Request the host to show the plugin gui. + * Return true on success, false otherwise. + * [main-thread] */ + bool (*request_show)(const clap_host_t *host); + + /* Request the host to hide the plugin gui. + * Return true on success, false otherwise. + * [main-thread] */ + bool (*request_hide)(const clap_host_t *host); } clap_host_gui_t; #pragma pack(pop) diff --git a/include/clap/ext/note-ports.h b/include/clap/ext/note-ports.h @@ -19,9 +19,17 @@ extern "C" { #pragma pack(push, CLAP_ALIGN) +enum clap_note_dialect { + CLAP_NOTE_DIALECT_CLAP = 1 << 0, + CLAP_NOTE_DIALECT_MIDI = 1 << 1, + CLAP_NOTE_DIALECT_MIDI2 = 1 << 2, +}; + typedef struct clap_note_port_info { - alignas(4) clap_id id; // stable identifier - alignas(1) char name[CLAP_NAME_SIZE]; // displayable name, i18n? + alignas(4) clap_id id; // stable identifier + alignas(4) uint32_t clap_supported_dialects; // bitfield, see clap_note_dialect + alignas(4) uint32_t clap_preferred_dialect; // one value of clap_note_dialect + alignas(1) char name[CLAP_NAME_SIZE]; // displayable name, i18n? } clap_note_port_info_t; // The audio ports scan has to be done while the plugin is deactivated. diff --git a/include/clap/ext/params.h b/include/clap/ext/params.h @@ -189,9 +189,9 @@ typedef struct clap_plugin_params { // // [active && !processing : audio-thread] // [!active : main-thread] - void (*flush)(const clap_plugin_t *plugin, - const clap_event_list_t *input_parameter_changes, - const clap_event_list_t *output_parameter_changes); + void (*flush)(const clap_plugin_t *plugin, + const clap_input_events_t *in, + const clap_output_events_t *out); } clap_plugin_params_t; enum { diff --git a/include/clap/ext/posix-fd-support.h b/include/clap/ext/posix-fd-support.h @@ -0,0 +1,45 @@ +#pragma once + +#include "../plugin.h" + +static CLAP_CONSTEXPR const char CLAP_EXT_POSIX_FD_SUPPORT[] = "clap.posix-fd-support"; + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(push, CLAP_ALIGN) + +enum { + // IO events flags + CLAP_POSIX_FD_READ = 1 << 0, + CLAP_POSIX_FD_WRITE = 1 << 1, + CLAP_POSIX_FD_ERROR = 1 << 2, +}; + +typedef struct clap_plugin_posix_fd_support { + // This callback is "level-triggered". + // It means that a writable fd will continuously produce "on_fd()" events; + // don't forget using modify_fd() to remove the write notification once you're + // done writting. + // + // [main-thread] + void (*on_fd)(const clap_plugin_t *plugin, int fd, int flags); +} clap_plugin_fd_support_t; + +typedef struct clap_host_posix_fd_support { + // [main-thread] + bool (*register_fd)(const clap_host_t *host, int fd, int flags); + + // [main-thread] + bool (*modify_fd)(const clap_host_t *host, int fd, int flags); + + // [main-thread] + bool (*unregister_fd)(const clap_host_t *host, int fd); +} clap_host_posix_fd_support_t; + +#pragma pack(pop) + +#ifdef __cplusplus +} +#endif +\ No newline at end of file diff --git a/include/clap/plugin-factory.h b/include/clap/plugin-factory.h @@ -13,6 +13,8 @@ extern "C" { // Every methods must be thread-safe. // 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 typedef struct clap_plugin_factory { /* Get the number of plugins available. * [thread-safe] */ diff --git a/include/clap/plugin.h b/include/clap/plugin.h @@ -12,27 +12,6 @@ extern "C" { #pragma pack(push, CLAP_ALIGN) -/* bitfield - * This gives an hint to the host what the plugin might do. */ -enum { - /* Instruments can play notes, and generate audio */ - CLAP_PLUGIN_INSTRUMENT = (1 << 0), - - /* Audio effects, process audio input and produces audio. - * Exemple: delay, reverb, compressor. */ - CLAP_PLUGIN_AUDIO_EFFECT = (1 << 1), - - /* Event effects, takes events as input and produces events. - * Exemple: arpegiator */ - CLAP_PLUGIN_EVENT_EFFECT = (1 << 2), // can be seen as midi effect - - // Analyze audio and/or events. - // If this is the only type reported by the plugin, the host can assume that it wont change the - // audio and event signal. - CLAP_PLUGIN_ANALYZER = (1 << 3), -}; -typedef int32_t clap_plugin_type; - typedef struct clap_plugin_descriptor { clap_version_t clap_version; // initialized to CLAP_VERSION @@ -47,16 +26,25 @@ typedef struct clap_plugin_descriptor { // Arbitrary list of keywords, separated by `;' // They can be matched by the host search engine and used to classify the plugin. + // + // Some pre-defined keywords: + // - "instrument", "audio_effect", "note_effect", "analyzer" + // - "mono", "stereo", "surround", "ambisonic" + // - "distortion", "compressor", "limiter", "transient" + // - "equalizer", "filter", "de-esser" + // - "delay", "reverb", "chorus", "flanger" + // - "tool", "utility", "glitch" + // + // - "win32-dpi-aware" informs the host that this plugin is dpi-aware on Windows + // // Some examples: - // "master;eq;spectrum" - // "compressor;analog;character" - // "reverb;plate;cathedral" - // "kick;analog;808;roland" - // "analog;character;roland;moog" - // "chip;chiptune;gameboy;nintendo;sega" - const char *keywords; - - alignas(8) uint64_t plugin_type; // bitfield of clap_plugin_type + // "equalizer;analyzer;stereo;mono" + // "compressor;analog;character;mono" + // "reverb;plate;stereo" + // "reverb;spring;surround" + // "kick;analog;808;roland;drum;mono;instrument" + // "instrument;chiptune;gameboy;nintendo;sega;mono" + const char *features; } clap_plugin_descriptor_t; typedef struct clap_plugin { @@ -66,10 +54,12 @@ typedef struct clap_plugin { // Must be called after creating the plugin. // If init returns false, the host must destroy the plugin instance. + // [main-thread] bool (*init)(const struct clap_plugin *plugin); - /* Free the plugin and its resources. - * It is not required to deactivate the plugin prior to this call. */ + // Free the plugin and its resources. + // It is not required to deactivate the plugin prior to this call. + // [main-thread & !active] void (*destroy)(const struct clap_plugin *plugin); // Activate and deactivate the plugin. @@ -78,25 +68,29 @@ typedef struct clap_plugin { // the [min, max] range, which is bounded by [1, INT32_MAX]. // Once activated the latency and port configuration must remain constant, until deactivation. // - // [main-thread] + // [main-thread & !active_state] bool (*activate)(const struct clap_plugin *plugin, double sample_rate, uint32_t min_frames_count, uint32_t max_frames_count); + // [main-thread & active_state] void (*deactivate)(const struct clap_plugin *plugin); - // Set to true before processing, and to false before sending the plugin to sleep. - // [audio-thread] + // Call start processing before processing. + // [audio-thread & active_state & !processing_state] bool (*start_processing)(const struct clap_plugin *plugin); + + // Call stop processing before sending the plugin to sleep. + // [audio-thread & active_state & processing_state] void (*stop_processing)(const struct clap_plugin *plugin); - /* process audio, events, ... - * [audio-thread] */ + // process audio, events, ... + // [audio-thread & active_state & processing_state] clap_process_status (*process)(const struct clap_plugin *plugin, const clap_process_t *process); - /* Query an extension. - * The returned pointer is owned by the plugin. - * [thread-safe] */ + // Query an extension. + // The returned pointer is owned by the plugin. + // [thread-safe] const void *(*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: diff --git a/include/clap/process.h b/include/clap/process.h @@ -28,8 +28,17 @@ enum { typedef int32_t clap_process_status; typedef struct clap_process { - alignas(8) uint64_t steady_time; // a steady sample time counter, requiered - alignas(4) uint32_t frames_count; // number of frame to process + // A steady sample time counter. + // This field can be used to calculate the sleep duration between two process calls. + // This value may be specific to this plugin instance and have no relation to what + // other plugin instances may receive. + // + // Set to -1 if not available, otherwise the value must be greater or equal to 0, + // and must be increased by at least `frames_count` for the next call to process. + alignas(8) int64_t steady_time; + + // Number of frame to process + alignas(4) uint32_t frames_count; // time info at sample 0 // If null, then this is a free running host, no transport events will be provided @@ -46,9 +55,15 @@ typedef struct clap_process { alignas(4) uint32_t audio_inputs_count; alignas(4) uint32_t audio_outputs_count; - /* events */ - const clap_event_list_t *in_events; - const clap_event_list_t *out_events; + // Input and output events. + // + // Events must be sorted by time. + // The input event list can't be modified. + // + // If a plugin does not implement clap_plugin_note_ports, + // then it gets a default note input and output. + const clap_input_events_t *in_events; + const clap_output_events_t *out_events; } clap_process_t; #pragma pack(pop) diff --git a/include/clap/version.h b/include/clap/version.h @@ -20,19 +20,19 @@ typedef struct clap_version { #pragma pack(pop) -static const uint32_t CLAP_VERSION_MAJOR = 0; -static const uint32_t CLAP_VERSION_MINOR = 16; -static const uint32_t CLAP_VERSION_REVISION = 1; +#ifdef __cplusplus +} +#endif + +static CLAP_CONSTEXPR const uint32_t CLAP_VERSION_MAJOR = 0; +static CLAP_CONSTEXPR const uint32_t CLAP_VERSION_MINOR = 17; +static CLAP_CONSTEXPR const uint32_t CLAP_VERSION_REVISION = 0; -static const clap_version_t CLAP_VERSION = { +static CLAP_CONSTEXPR const clap_version_t CLAP_VERSION = { CLAP_VERSION_MAJOR, CLAP_VERSION_MINOR, CLAP_VERSION_REVISION}; // For version 0, we require the same minor version because // we may still break the ABI at this point -static inline bool clap_version_is_compatible(const clap_version_t v) { +static CLAP_CONSTEXPR inline bool clap_version_is_compatible(const clap_version_t v) { return v.major == CLAP_VERSION_MAJOR && v.minor == CLAP_VERSION_MINOR; -} - -#ifdef __cplusplus -} -#endif -\ No newline at end of file +} +\ No newline at end of file