clap

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

commit d71da736f6f7e08510844d7673b10713fbe88b8a
parent 04547a6731eb24d2aa90385d4cb47d5efe602949
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date:   Tue, 28 Dec 2021 22:24:31 +0100

Merge remote-tracking branch 'origin/ev-rework' into next

Diffstat:
Minclude/clap/clap.h | 1+
Minclude/clap/events.h | 155++++++++++++++++++++++++++++++++++++-------------------------------------------
Minclude/clap/ext/event-filter.h | 2+-
Ainclude/clap/ext/event-registry.h | 27+++++++++++++++++++++++++++
Minclude/clap/ext/note-ports.h | 12++++++++++--
5 files changed, 109 insertions(+), 88 deletions(-)

diff --git a/include/clap/clap.h b/include/clap/clap.h @@ -51,6 +51,7 @@ #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/events.h b/include/clap/events.h @@ -12,6 +12,32 @@ extern "C" { #pragma pack(push, CLAP_ALIGN) +// event header +// must be the first field of the event +typedef struct clap_event_header { + alignas(4) uint32_t time; + alignas(2) uint16_t space_id; + alignas(2) uint16_t event_id; + alignas(2) uint16_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 @@ -44,12 +70,6 @@ enum { // Uses the note_expression attribute. CLAP_EVENT_NOTE_EXPRESSION, - // Sent by the host to the plugin. - // Indicate the current root note, and the set of notes which belongs to the scale or chord. - // - // uses the note_mask attribute - CLAP_EVENT_NOTE_MASK, - // PARAM_VALUE sets the parameter's value; uses param_value attribute // PARAM_MOD sets the parameter's modulation amount; uses param_mod attribute // @@ -61,19 +81,13 @@ enum { 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 + 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; -enum { - // Should be set if the events is external to the host, like a live user input - CLAP_EVENT_FLAG_IS_LIVE = 1 << 0, -}; -typedef int32_t clap_event_flags; - /** * Note on, off, end and choke events. * In the case of note choke or end events: @@ -81,10 +95,12 @@ typedef int32_t clap_event_flags; * - 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 { @@ -109,57 +125,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, @@ -169,10 +177,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 @@ -193,64 +202,40 @@ 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_midi2 { - alignas(4) uint32_t port_index; + alignas(4) clap_event_header_t header; + + alignas(2) uint16_t port_index; alignas(4) uint32_t data[4]; } clap_event_midi2_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 - alignas(4) clap_event_flags flags; // bitset of clap_event_flags - - 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_midi2_t midi2; - }; -} clap_event_t; - typedef struct clap_event_list { void *ctx; // reserved pointer for the list uint32_t (*size)(const struct clap_event_list *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_event_list *list, uint32_t index); - // Makes a copy of the event - void (*push_back)(const struct clap_event_list *list, const clap_event_t *event); + // Pushes a copy of the event + void (*push_back)(const struct clap_event_list *list, + const clap_event_header_t *event, + size_t event_size); } clap_event_list_t; #pragma pack(pop) 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_id); } clap_plugin_event_filter_t; diff --git a/include/clap/ext/event-registry.h b/include/clap/ext/event-registry.h @@ -0,0 +1,27 @@ +#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 first 1024 space_ids are reserved. + // + // Return false and sets *space_id 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/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.