clap

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

commit 528a3783b2410a31f6cd270177c42636d38ec7e0
parent bcad926637d8075720ee1777ba95256b6818aa29
Author: trinitou <debuggleburger@gmail.com>
Date:   Fri,  2 Dec 2022 00:16:12 +0100

First draft for actions extension

Diffstat:
Minclude/clap/events.h | 18++++++++++++++++++
Ainclude/clap/ext/draft/actions.h | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 184 insertions(+), 0 deletions(-)

diff --git a/include/clap/events.h b/include/clap/events.h @@ -113,6 +113,10 @@ enum { CLAP_EVENT_MIDI, // raw midi event; clap_event_midi CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; clap_event_midi_sysex CLAP_EVENT_MIDI2, // raw midi 2 event; clap_event_midi2 + + // Represents a trigger action + // Uses clap_event_action_trigger. + CLAP_EVENT_ACTION_TRIGGER, }; // Note on, off, end and choke events. @@ -259,6 +263,20 @@ typedef struct clap_event_midi2 { uint32_t data[4]; } clap_event_midi2_t; +typedef struct clap_event_action_trigger { + clap_event_header_t header; + + // target action + clap_id action_id; // @ref clap_action_info.id + void *cookie; // @ref clap_action_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_action_trigger_t; + // Input event list, events must be sorted by time. typedef struct clap_input_events { void *ctx; // reserved pointer for the list diff --git a/include/clap/ext/draft/actions.h b/include/clap/ext/draft/actions.h @@ -0,0 +1,166 @@ +#pragma once + +#include "../../plugin.h" +#include "../string-sizes.h" + +static CLAP_CONSTEXPR const char CLAP_EXT_ACTIONS[] = "clap.actions.draft/0"; + +#ifdef __cplusplus +extern "C" { +#endif + +/// @page Actions +/// +/// This extension enables the plugin to provide a set of actions. +/// These actions then can be accessed and triggered by the host. +/// +/// Some examples for actions: +/// - randomizing step values of a step sequencer +/// - start recording into an plugin-internal audio/note buffer +/// - trigger an retrospective audio/note looper +/// - init current patch +/// - turn off all effects units (for a synthesizer) +/// - trigger a sample-and-hold unit (maybe even per-voice) + +enum { + // Is this action currently available? + // + // The host can use this to display corresponding action items as enabled/disabled, + // like action buttons or menu entries. + CLAP_ACTION_IS_ENABLED = 1 << 0, + + // When set: + // - action triggers can be recorded + // - action triggers can be played back + // + // The host can send live user triggers for this action regardless of this flag. + // + // If this action affects the internal processing structure of the plugin, ie: max delay, fft + // size, ... and the plugins needs to re-allocate its working buffers, then it should call + // host->request_restart(), and perform the change once the plugin is re-activated. + CLAP_ACTION_IS_AUTOMATABLE = 1 << 1, + + // Does this action support per note automations? + CLAP_ACTION_IS_AUTOMATABLE_PER_NOTE_ID = 1 << 2, + + // Does this action support per key automations? + CLAP_ACTION_IS_AUTOMATABLE_PER_KEY = 1 << 3, + + // Does this action support per channel automations? + CLAP_ACTION_IS_AUTOMATABLE_PER_CHANNEL = 1 << 4, + + // Does this action support per port automations? + CLAP_ACTION_IS_AUTOMATABLE_PER_PORT = 1 << 5, + + // Any trigger of this action will affect the plugin output and requires to be done via + // process() if the plugin is active. + // + // A simple example would be a sample-and-hold action, triggering it will change the output signal and must be + // processed. + CLAP_ACTION_REQUIRES_PROCESS = 1 << 6, +}; +typedef uint32_t clap_action_info_flags; + +/* This describes an action */ +typedef struct clap_action_info { + // stable action identifier, it must never change. + clap_id id; + + clap_action_info_flags flags; + + // in analogy to clap_param_info.cookie + void *cookie; + + // displayable name + char name[CLAP_NAME_SIZE]; + + // the module path containing the action, eg:"sequencers/seq1" + // '/' will be used as a separator to show a tree like structure. + char module[CLAP_PATH_SIZE]; +} clap_action_info_t; + +typedef struct clap_plugin_actions { + // Returns the number of actions. + // [main-thread] + uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); + + // Copies the action's info to action_info and returns true on success. + // Returns true on success. + // [main-thread] + bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin, + uint32_t index, + clap_action_info_t *action_info); + + // Flushes a set of action triggers. + // 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 + // triggers, 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] + void(CLAP_ABI *flush)(const clap_plugin_t *plugin, + const clap_input_events_t *in, + const clap_output_events_t *out); +} clap_plugin_actions_t; + +enum { + // The action info did change, use this flag for: + // - name change + // - module change + // - is_enabled (flag) + // New info takes effect immediately. + CLAP_ACTION_RESCAN_INFO = 1 << 0, + + // Invalidates everything the host knows about actions. + // 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 actions were added or removed. + // - some actions had critical changes: + // - is_per_note (flag) + // - is_per_key (flag) + // - is_per_channel (flag) + // - is_per_port (flag) + // - cookie + CLAP_ACTION_RESCAN_ALL = 1 << 1, +}; +typedef uint32_t clap_action_rescan_flags; + +enum { + // Clears all possible references to an action + CLAP_ACTION_CLEAR_ALL = 1 << 0, + + // Clears all automations to an action + CLAP_ACTION_CLEAR_AUTOMATIONS = 1 << 1, +}; +typedef uint32_t clap_action_clear_flags; + +typedef struct clap_host_actions { + // Rescan the full list of actions according to the flags. + // [main-thread] + void(CLAP_ABI *rescan)(const clap_host_t *host, clap_action_rescan_flags flags); + + // Clears references to an action. + // [main-thread] + void(CLAP_ABI *clear)(const clap_host_t *host, clap_id action_id, clap_action_clear_flags flags); + + // Request an action flush. + // + // The host will then schedule a call to either: + // - clap_plugin.process() + // - clap_plugin_actions.flush() + // + // 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(). + // + // [thread-safe,!audio-thread] + void(CLAP_ABI *request_flush)(const clap_host_t *host); +} clap_host_actions_t; + +#ifdef __cplusplus +} +#endif