Initial commit
This commit is contained in:
commit
56f7cd1875
105 changed files with 22109 additions and 0 deletions
17
tests/clap/all.h
Normal file
17
tests/clap/all.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "clap.h"
|
||||
|
||||
#include "factory/draft/plugin-invalidation.h"
|
||||
#include "factory/draft/plugin-state-converter.h"
|
||||
|
||||
#include "ext/draft/extensible-audio-ports.h"
|
||||
#include "ext/draft/gain-adjustment-metering.h"
|
||||
#include "ext/draft/mini-curve-display.h"
|
||||
#include "ext/draft/project-location.h"
|
||||
#include "ext/draft/resource-directory.h"
|
||||
#include "ext/draft/scratch-memory.h"
|
||||
#include "ext/draft/transport-control.h"
|
||||
#include "ext/draft/triggers.h"
|
||||
#include "ext/draft/tuning.h"
|
||||
#include "ext/draft/undo.h"
|
||||
37
tests/clap/audio-buffer.h
Normal file
37
tests/clap/audio-buffer.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Sample code for reading a stereo buffer:
|
||||
//
|
||||
// bool isLeftConstant = (buffer->constant_mask & (1 << 0)) != 0;
|
||||
// bool isRightConstant = (buffer->constant_mask & (1 << 1)) != 0;
|
||||
//
|
||||
// for (int i = 0; i < N; ++i) {
|
||||
// float l = data32[0][isLeftConstant ? 0 : i];
|
||||
// float r = data32[1][isRightConstant ? 0 : i];
|
||||
// }
|
||||
//
|
||||
// Note: checking the constant mask is optional, and this implies that
|
||||
// the buffer must be filled with the constant value.
|
||||
// Rationale: if a buffer reader doesn't check the constant mask, then it may
|
||||
// process garbage samples and in result, garbage samples may be transmitted
|
||||
// to the audio interface with all the bad consequences it can have.
|
||||
//
|
||||
// The constant mask is a hint.
|
||||
typedef struct clap_audio_buffer {
|
||||
// Either data32 or data64 pointer will be set.
|
||||
float **data32;
|
||||
double **data64;
|
||||
uint32_t channel_count;
|
||||
uint32_t latency; // latency from/to the audio interface
|
||||
uint64_t constant_mask;
|
||||
} clap_audio_buffer_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
64
tests/clap/clap.h
Normal file
64
tests/clap/clap.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* CLAP - CLever Audio Plugin
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* 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
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "entry.h"
|
||||
|
||||
#include "factory/plugin-factory.h"
|
||||
#include "factory/preset-discovery.h"
|
||||
|
||||
#include "plugin.h"
|
||||
#include "plugin-features.h"
|
||||
#include "host.h"
|
||||
#include "universal-plugin-id.h"
|
||||
|
||||
#include "ext/ambisonic.h"
|
||||
#include "ext/audio-ports-activation.h"
|
||||
#include "ext/audio-ports-config.h"
|
||||
#include "ext/audio-ports.h"
|
||||
#include "ext/configurable-audio-ports.h"
|
||||
#include "ext/context-menu.h"
|
||||
#include "ext/event-registry.h"
|
||||
#include "ext/gui.h"
|
||||
#include "ext/latency.h"
|
||||
#include "ext/log.h"
|
||||
#include "ext/note-name.h"
|
||||
#include "ext/note-ports.h"
|
||||
#include "ext/param-indication.h"
|
||||
#include "ext/params.h"
|
||||
#include "ext/posix-fd-support.h"
|
||||
#include "ext/preset-load.h"
|
||||
#include "ext/remote-controls.h"
|
||||
#include "ext/render.h"
|
||||
#include "ext/state-context.h"
|
||||
#include "ext/state.h"
|
||||
#include "ext/surround.h"
|
||||
#include "ext/tail.h"
|
||||
#include "ext/thread-check.h"
|
||||
#include "ext/thread-pool.h"
|
||||
#include "ext/timer-support.h"
|
||||
#include "ext/track-info.h"
|
||||
#include "ext/voice-info.h"
|
||||
20
tests/clap/color.h
Normal file
20
tests/clap/color.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_color {
|
||||
uint8_t alpha;
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} clap_color_t;
|
||||
|
||||
static const CLAP_CONSTEXPR clap_color_t CLAP_COLOR_TRANSPARENT = { 0, 0, 0, 0 };
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
136
tests/clap/entry.h
Normal file
136
tests/clap/entry.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#pragma once
|
||||
|
||||
#include "version.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This interface is the entry point of the dynamic library.
|
||||
//
|
||||
// CLAP plugins standard search path:
|
||||
//
|
||||
// Linux
|
||||
// - ~/.clap
|
||||
// - /usr/lib/clap
|
||||
//
|
||||
// Windows
|
||||
// - %COMMONPROGRAMFILES%\CLAP
|
||||
// - %LOCALAPPDATA%\Programs\Common\CLAP
|
||||
//
|
||||
// MacOS
|
||||
// - /Library/Audio/Plug-Ins/CLAP
|
||||
// - ~/Library/Audio/Plug-Ins/CLAP
|
||||
//
|
||||
// In addition to the OS-specific default locations above, a CLAP host must query the environment
|
||||
// for a CLAP_PATH variable, which is a list of directories formatted in the same manner as the host
|
||||
// OS binary search path (PATH on Unix, separated by `:` and Path on Windows, separated by ';', as
|
||||
// of this writing).
|
||||
//
|
||||
// Each directory should be recursively searched for files and/or bundles as appropriate in your OS
|
||||
// ending with the extension `.clap`.
|
||||
//
|
||||
// init and deinit in most cases are called once, in a matched pair, when the dso is loaded / unloaded.
|
||||
// In some rare situations it may be called multiple times in a process, so the functions must be defensive,
|
||||
// mutex locking and counting calls if undertaking non trivial non idempotent actions.
|
||||
//
|
||||
// Rationale:
|
||||
//
|
||||
// The intent of the init() and deinit() functions is to provide a "normal" initialization patterh
|
||||
// which occurs when the shared object is loaded or unloaded. As such, hosts will call each once and
|
||||
// in matched pairs. In CLAP specifications prior to 1.2.0, this single-call was documented as a
|
||||
// requirement.
|
||||
//
|
||||
// We realized, though, that this is not a requirement hosts can meet. If hosts load a plugin
|
||||
// which itself wraps another CLAP for instance, while also loading that same clap in its memory
|
||||
// space, both the host and the wrapper will call init() and deinit() and have no means to communicate
|
||||
// the state.
|
||||
//
|
||||
// With CLAP 1.2.0 and beyond we are changing the spec to indicate that a host should make an
|
||||
// absolute best effort to call init() and deinit() once, and always in matched pairs (for every
|
||||
// init() which returns true, one deinit() should be called).
|
||||
//
|
||||
// This takes the de-facto burden on plugin writers to deal with multiple calls into a hard requirement.
|
||||
//
|
||||
// Most init() / deinit() pairs we have seen are the relatively trivial {return true;} and {}. But
|
||||
// if your init() function does non-trivial one time work, the plugin author must maintain a counter
|
||||
// and must manage a mutex lock. The most obvious implementation will maintain a static counter and a
|
||||
// global mutex, increment the counter on each init, decrement it on each deinit, and only undertake
|
||||
// the init or deinit action when the counter is zero.
|
||||
typedef struct clap_plugin_entry {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
|
||||
// Initializes the DSO.
|
||||
//
|
||||
// This function must be called first, before any-other CLAP-related function or symbol from this
|
||||
// DSO.
|
||||
//
|
||||
// It also must only be called once, until a later call to deinit() is made, after which init()
|
||||
// can be called once more to re-initialize the DSO.
|
||||
// This enables hosts to e.g. quickly load and unload a DSO for scanning its plugins, and then
|
||||
// load it again later to actually use the plugins if needed.
|
||||
//
|
||||
// As stated above, even though hosts are forbidden to do so directly, multiple calls before any
|
||||
// deinit() call may still happen. Implementations *should* take this into account, and *must*
|
||||
// do so as of CLAP 1.2.0.
|
||||
//
|
||||
// It should be as fast as possible, in order to perform a very quick scan of the plugin
|
||||
// descriptors.
|
||||
//
|
||||
// It is forbidden to display graphical user interfaces in this call.
|
||||
// It is forbidden to perform any user interaction in this call.
|
||||
//
|
||||
// If the initialization depends upon expensive computation, maybe try to do them ahead of time
|
||||
// and cache the result.
|
||||
//
|
||||
// Returns true on success. If init() returns false, then the DSO must be considered
|
||||
// uninitialized, and the host must not call deinit() nor any other CLAP-related symbols from the
|
||||
// DSO.
|
||||
// This function also returns true in the case where the DSO is already initialized, and no
|
||||
// actual initialization work is done in this call, as explain above.
|
||||
//
|
||||
// plugin_path is the path to the DSO (Linux, Windows), or the bundle (macOS).
|
||||
//
|
||||
// This function may be called on any thread, including a different one from the one a later call
|
||||
// to deinit() (or a later init()) can be made.
|
||||
// However, it is forbidden to call this function simultaneously from multiple threads.
|
||||
// It is also forbidden to call it simultaneously with *any* other CLAP-related symbols from the
|
||||
// DSO, including (but not limited to) deinit().
|
||||
bool(CLAP_ABI *init)(const char *plugin_path);
|
||||
|
||||
// De-initializes the DSO, freeing any resources allocated or initialized by init().
|
||||
//
|
||||
// After this function is called, no more calls into the DSO must be made, except calling init()
|
||||
// again to re-initialize the DSO.
|
||||
// This means that after deinit() is called, the DSO can be considered to be in the same state
|
||||
// as if init() was never called at all yet, enabling it to be re-initialized as needed.
|
||||
//
|
||||
// As stated above, even though hosts are forbidden to do so directly, multiple calls before any
|
||||
// new init() call may still happen. Implementations *should* take this into account, and *must*
|
||||
// do so as of CLAP 1.2.0.
|
||||
//
|
||||
// Just like init(), this function may be called on any thread, including a different one from
|
||||
// the one init() was called from, or from the one a later init() call can be made.
|
||||
// However, it is forbidden to call this function simultaneously from multiple threads.
|
||||
// It is also forbidden to call it simultaneously with *any* other CLAP-related symbols from the
|
||||
// DSO, including (but not limited to) deinit().
|
||||
void(CLAP_ABI *deinit)(void);
|
||||
|
||||
// Get the pointer to a factory. See factory/plugin-factory.h for an example.
|
||||
//
|
||||
// Returns null if the factory is not provided.
|
||||
// The returned pointer must *not* be freed by the caller.
|
||||
//
|
||||
// Unlike init() and deinit(), this function can be called simultaneously by multiple threads.
|
||||
//
|
||||
// [thread-safe]
|
||||
const void *(CLAP_ABI *get_factory)(const char *factory_id);
|
||||
} clap_plugin_entry_t;
|
||||
|
||||
/* Entry point */
|
||||
CLAP_EXPORT extern const clap_plugin_entry_t clap_entry;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
367
tests/clap/events.h
Normal file
367
tests/clap/events.h
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "fixedpoint.h"
|
||||
#include "id.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// event header
|
||||
// All clap events start with an event header to determine the overall
|
||||
// size of the event and its type and space (a namespacing for types).
|
||||
// clap_event objects are contiguous regions of memory which can be copied
|
||||
// with a memcpy of `size` bytes starting at the top of the header. As
|
||||
// such, be very careful when designing clap events with internal pointers
|
||||
// and other non-value-types to consider the lifetime of those members.
|
||||
typedef struct clap_event_header {
|
||||
uint32_t size; // event size including this header, eg: sizeof (clap_event_note)
|
||||
uint32_t time; // sample offset within the buffer for this event
|
||||
uint16_t space_id; // event space, see clap_host_event_registry
|
||||
uint16_t type; // event type
|
||||
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 user event, for example a user turning a physical knob
|
||||
// or playing a physical key.
|
||||
CLAP_EVENT_IS_LIVE = 1 << 0,
|
||||
|
||||
// Indicate that the event should not be recorded.
|
||||
// For example this is useful when a parameter changes because of a MIDI CC,
|
||||
// because if the host records both the MIDI CC automation and the parameter
|
||||
// automation there will be a conflict.
|
||||
CLAP_EVENT_DONT_RECORD = 1 << 1,
|
||||
};
|
||||
|
||||
// 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 {
|
||||
// NOTE_ON and NOTE_OFF represent a key pressed and key released event, respectively.
|
||||
// A NOTE_ON with a velocity of 0 is valid and should not be interpreted as a NOTE_OFF.
|
||||
//
|
||||
// NOTE_CHOKE is meant to choke the voice(s), like in a drum machine when a closed hihat
|
||||
// chokes an open hihat. This event can be sent by the host to the plugin. Here are two use
|
||||
// cases:
|
||||
// - a plugin is inside a drum pad in Bitwig Studio's drum machine, and this pad is choked by
|
||||
// another one
|
||||
// - the user double-clicks the DAW's stop button in the transport which then stops the sound on
|
||||
// every track
|
||||
//
|
||||
// NOTE_END is sent by the plugin to the host. The port, channel, key and note_id are those given
|
||||
// by the host in the NOTE_ON event. In other words, this event is matched against the
|
||||
// plugin's note input port.
|
||||
// NOTE_END is useful to help the host to match the plugin's voice life time.
|
||||
//
|
||||
// When using polyphonic modulations, the host has to allocate and release voices for its
|
||||
// polyphonic modulator. Yet only the plugin effectively knows when the host should terminate
|
||||
// a voice. NOTE_END solves that issue in a non-intrusive and cooperative way.
|
||||
//
|
||||
// CLAP assumes that the host will allocate a unique voice on NOTE_ON event for a given port,
|
||||
// channel and key. This voice will run until the plugin will instruct the host to terminate
|
||||
// it by sending a NOTE_END event.
|
||||
//
|
||||
// Consider the following sequence:
|
||||
// - process()
|
||||
// Host->Plugin NoteOn(port:0, channel:0, key:16, time:t0)
|
||||
// Host->Plugin NoteOn(port:0, channel:0, key:64, time:t0)
|
||||
// Host->Plugin NoteOff(port:0, channel:0, key:16, t1)
|
||||
// Host->Plugin NoteOff(port:0, channel:0, key:64, t1)
|
||||
// # on t2, both notes did terminate
|
||||
// Host->Plugin NoteOn(port:0, channel:0, key:64, t3)
|
||||
// # Here the plugin finished processing all the frames and will tell the host
|
||||
// # to terminate the voice on key 16 but not 64, because a note has been started at t3
|
||||
// Plugin->Host NoteEnd(port:0, channel:0, key:16, time:ignored)
|
||||
//
|
||||
// These four events use clap_event_note.
|
||||
CLAP_EVENT_NOTE_ON = 0,
|
||||
CLAP_EVENT_NOTE_OFF = 1,
|
||||
CLAP_EVENT_NOTE_CHOKE = 2,
|
||||
CLAP_EVENT_NOTE_END = 3,
|
||||
|
||||
// Represents a note expression.
|
||||
// Uses clap_event_note_expression.
|
||||
CLAP_EVENT_NOTE_EXPRESSION = 4,
|
||||
|
||||
// PARAM_VALUE sets the parameter's value; uses clap_event_param_value.
|
||||
// PARAM_MOD sets the parameter's modulation amount; uses clap_event_param_mod.
|
||||
//
|
||||
// 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 = 5,
|
||||
CLAP_EVENT_PARAM_MOD = 6,
|
||||
|
||||
// Indicates that the user started or finished adjusting a knob.
|
||||
// This is not mandatory to wrap parameter changes with gesture events, but this improves
|
||||
// the user experience a lot when recording automation or overriding automation playback.
|
||||
// Uses clap_event_param_gesture.
|
||||
CLAP_EVENT_PARAM_GESTURE_BEGIN = 7,
|
||||
CLAP_EVENT_PARAM_GESTURE_END = 8,
|
||||
|
||||
CLAP_EVENT_TRANSPORT = 9, // update the transport info; clap_event_transport
|
||||
CLAP_EVENT_MIDI = 10, // raw midi event; clap_event_midi
|
||||
CLAP_EVENT_MIDI_SYSEX = 11, // raw midi sysex event; clap_event_midi_sysex
|
||||
CLAP_EVENT_MIDI2 = 12, // raw midi 2 event; clap_event_midi2
|
||||
};
|
||||
|
||||
// Note on, off, end and choke events.
|
||||
//
|
||||
// Clap addresses notes and voices using the 4-value tuple
|
||||
// (port, channel, key, note_id). Note on/off/end/choke
|
||||
// events and parameter modulation messages are delivered with
|
||||
// these values populated.
|
||||
//
|
||||
// Values in a note and voice address are either >= 0 if they
|
||||
// are specified, or -1 to indicate a wildcard. A wildcard
|
||||
// means a voice with any value in that part of the tuple
|
||||
// matches the message.
|
||||
//
|
||||
// For instance, a (PCKN) of (0, 3, -1, -1) will match all voices
|
||||
// on channel 3 of port 0. And a PCKN of (-1, 0, 60, -1) will match
|
||||
// all channel 0 key 60 voices, independent of port or note id.
|
||||
//
|
||||
// Especially in the case of note-on note-off pairs, and in the
|
||||
// absence of voice stacking or polyphonic modulation, a host may
|
||||
// choose to issue a note id only at note on. So you may see a
|
||||
// message stream like
|
||||
//
|
||||
// CLAP_EVENT_NOTE_ON [0,0,60,184]
|
||||
// CLAP_EVENT_NOTE_OFF [0,0,60,-1]
|
||||
//
|
||||
// and the host will expect the first voice to be released.
|
||||
// Well constructed plugins will search for voices and notes using
|
||||
// the entire tuple.
|
||||
//
|
||||
// In the case of note on events:
|
||||
// - The port, channel and key must be specified with a value >= 0
|
||||
// - A note-on event with a '-1' for port, channel or key is invalid and
|
||||
// can be rejected or ignored by a plugin or host.
|
||||
// - A host which does not support note ids should set the note id to -1.
|
||||
//
|
||||
// In the case of note choke or end events:
|
||||
// - the velocity is ignored.
|
||||
// - key and channel are used to match active notes
|
||||
// - note_id is optionally provided by the host
|
||||
typedef struct clap_event_note {
|
||||
clap_event_header_t header;
|
||||
|
||||
int32_t note_id; // host provided note id >= 0, or -1 if unspecified or wildcard
|
||||
int16_t port_index; // port index from ext/note-ports; -1 for wildcard
|
||||
int16_t channel; // 0..15, same as MIDI1 Channel Number, -1 for wildcard
|
||||
int16_t key; // 0..127, same as MIDI1 Key Number (60==Middle C), -1 for wildcard
|
||||
double velocity; // 0..1
|
||||
} clap_event_note_t;
|
||||
|
||||
// Note Expressions are well named modifications of a voice targeted to
|
||||
// voices using the same wildcard rules described above. Note Expressions are delivered
|
||||
// as sample accurate events and should be applied at the sample when received.
|
||||
//
|
||||
// Note expressions are a statement of value, not cumulative. A PAN event of 0 followed by 1
|
||||
// followed by 0.5 would pan hard left, hard right, and center. They are intended as
|
||||
// an offset from the non-note-expression voice default. A voice which had a volume of
|
||||
// -20db absent note expressions which received a +4db note expression would move the
|
||||
// voice to -16db.
|
||||
//
|
||||
// A plugin which receives a note expression at the same sample as a NOTE_ON event
|
||||
// should apply that expression to all generated samples. A plugin which receives
|
||||
// a note expression after a NOTE_ON event should initiate the voice with default
|
||||
// values and then apply the note expression when received. A plugin may make a choice
|
||||
// to smooth note expression streams.
|
||||
enum {
|
||||
// with 0 < x <= 4, plain = 20 * log(x)
|
||||
CLAP_NOTE_EXPRESSION_VOLUME = 0,
|
||||
|
||||
// pan, 0 left, 0.5 center, 1 right
|
||||
CLAP_NOTE_EXPRESSION_PAN = 1,
|
||||
|
||||
// Relative tuning in semitones, from -120 to +120. Semitones are in
|
||||
// equal temperament and are doubles; the resulting note would be
|
||||
// retuned by `100 * evt->value` cents.
|
||||
CLAP_NOTE_EXPRESSION_TUNING = 2,
|
||||
|
||||
// 0..1
|
||||
CLAP_NOTE_EXPRESSION_VIBRATO = 3,
|
||||
CLAP_NOTE_EXPRESSION_EXPRESSION = 4,
|
||||
CLAP_NOTE_EXPRESSION_BRIGHTNESS = 5,
|
||||
CLAP_NOTE_EXPRESSION_PRESSURE = 6,
|
||||
};
|
||||
typedef int32_t clap_note_expression;
|
||||
|
||||
typedef struct clap_event_note_expression {
|
||||
clap_event_header_t header;
|
||||
|
||||
clap_note_expression expression_id;
|
||||
|
||||
// target a specific note_id, port, key and channel, with
|
||||
// -1 meaning wildcard, per the wildcard discussion above
|
||||
int32_t note_id;
|
||||
int16_t port_index;
|
||||
int16_t channel;
|
||||
int16_t key;
|
||||
|
||||
double value; // see expression for the range
|
||||
} clap_event_note_expression_t;
|
||||
|
||||
typedef struct clap_event_param_value {
|
||||
clap_event_header_t header;
|
||||
|
||||
// target parameter
|
||||
clap_id param_id; // @ref clap_param_info.id
|
||||
void *cookie; // @ref clap_param_info.cookie
|
||||
|
||||
// target a specific note_id, port, key and channel, with
|
||||
// -1 meaning wildcard, per the wildcard discussion above
|
||||
int32_t note_id;
|
||||
int16_t port_index;
|
||||
int16_t channel;
|
||||
int16_t key;
|
||||
|
||||
double value;
|
||||
} clap_event_param_value_t;
|
||||
|
||||
typedef struct clap_event_param_mod {
|
||||
clap_event_header_t header;
|
||||
|
||||
// target parameter
|
||||
clap_id param_id; // @ref clap_param_info.id
|
||||
void *cookie; // @ref clap_param_info.cookie
|
||||
|
||||
// target a specific note_id, port, key and channel, with
|
||||
// -1 meaning wildcard, per the wildcard discussion above
|
||||
int32_t note_id;
|
||||
int16_t port_index;
|
||||
int16_t channel;
|
||||
int16_t key;
|
||||
|
||||
double amount; // modulation amount
|
||||
} clap_event_param_mod_t;
|
||||
|
||||
typedef struct clap_event_param_gesture {
|
||||
clap_event_header_t header;
|
||||
|
||||
// target parameter
|
||||
clap_id param_id; // @ref clap_param_info.id
|
||||
} clap_event_param_gesture_t;
|
||||
|
||||
enum clap_transport_flags {
|
||||
CLAP_TRANSPORT_HAS_TEMPO = 1 << 0,
|
||||
CLAP_TRANSPORT_HAS_BEATS_TIMELINE = 1 << 1,
|
||||
CLAP_TRANSPORT_HAS_SECONDS_TIMELINE = 1 << 2,
|
||||
CLAP_TRANSPORT_HAS_TIME_SIGNATURE = 1 << 3,
|
||||
CLAP_TRANSPORT_IS_PLAYING = 1 << 4,
|
||||
CLAP_TRANSPORT_IS_RECORDING = 1 << 5,
|
||||
CLAP_TRANSPORT_IS_LOOP_ACTIVE = 1 << 6,
|
||||
CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL = 1 << 7,
|
||||
};
|
||||
|
||||
// clap_event_transport provides song position, tempo, and similar information
|
||||
// from the host to the plugin. There are two ways a host communicates these values.
|
||||
// In the `clap_process` structure sent to each processing block, the host may
|
||||
// provide a transport structure which indicates the available information at the
|
||||
// start of the block. If the host provides sample-accurate tempo or transport changes,
|
||||
// it can also provide subsequent inter-block transport updates by delivering a new event.
|
||||
typedef struct clap_event_transport {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint32_t flags; // see clap_transport_flags
|
||||
|
||||
clap_beattime song_pos_beats; // position in beats
|
||||
clap_sectime song_pos_seconds; // position in seconds
|
||||
|
||||
double tempo; // in bpm
|
||||
double tempo_inc; // tempo increment for each sample and until the next
|
||||
// time info event
|
||||
|
||||
clap_beattime loop_start_beats;
|
||||
clap_beattime loop_end_beats;
|
||||
clap_sectime loop_start_seconds;
|
||||
clap_sectime loop_end_seconds;
|
||||
|
||||
clap_beattime bar_start; // start pos of the current bar
|
||||
int32_t bar_number; // bar at song pos 0 has the number 0
|
||||
|
||||
uint16_t tsig_num; // time signature numerator
|
||||
uint16_t tsig_denom; // time signature denominator
|
||||
} clap_event_transport_t;
|
||||
|
||||
typedef struct clap_event_midi {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint16_t port_index;
|
||||
uint8_t data[3];
|
||||
} clap_event_midi_t;
|
||||
|
||||
// clap_event_midi_sysex contains a pointer to a sysex contents buffer.
|
||||
// The lifetime of this buffer is (from host->plugin) only the process
|
||||
// call in which the event is delivered or (from plugin->host) only the
|
||||
// duration of a try_push call.
|
||||
//
|
||||
// Since `clap_output_events.try_push` requires hosts to make a copy of
|
||||
// an event, host implementers receiving sysex messages from plugins need
|
||||
// to take care to both copy the event (so header, size, etc...) but
|
||||
// also memcpy the contents of the sysex pointer to host-owned memory, and
|
||||
// not just copy the data pointer.
|
||||
//
|
||||
// Similarly plugins retaining the sysex outside the lifetime of a single
|
||||
// process call must copy the sysex buffer to plugin-owned memory.
|
||||
//
|
||||
// As a consequence, the data structure pointed to by the sysex buffer
|
||||
// must be contiguous and copyable with `memcpy` of `size` bytes.
|
||||
typedef struct clap_event_midi_sysex {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint16_t port_index;
|
||||
const uint8_t *buffer; // midi buffer. See lifetime comment above.
|
||||
uint32_t size;
|
||||
} clap_event_midi_sysex_t;
|
||||
|
||||
// While it is possible to use a series of midi2 event to send a sysex,
|
||||
// prefer clap_event_midi_sysex if possible for efficiency.
|
||||
typedef struct clap_event_midi2 {
|
||||
clap_event_header_t header;
|
||||
|
||||
uint16_t port_index;
|
||||
uint32_t data[4];
|
||||
} clap_event_midi2_t;
|
||||
|
||||
// Input event list. The host will deliver these sorted in sample order.
|
||||
typedef struct clap_input_events {
|
||||
void *ctx; // reserved pointer for the 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
|
||||
const clap_event_header_t *(CLAP_ABI *get)(const struct clap_input_events *list, uint32_t index);
|
||||
} clap_input_events_t;
|
||||
|
||||
// Output event list. The plugin must insert events in sample sorted order when inserting events
|
||||
typedef struct clap_output_events {
|
||||
void *ctx; // reserved pointer for the list
|
||||
|
||||
// Pushes a copy of the event
|
||||
// returns false if the event could not be pushed to the queue (out of memory?)
|
||||
bool(CLAP_ABI *try_push)(const struct clap_output_events *list,
|
||||
const clap_event_header_t *event);
|
||||
} clap_output_events_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
63
tests/clap/ext/ambisonic.h
Normal file
63
tests/clap/ext/ambisonic.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#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/3";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC_COMPAT[] = "clap.ambisonic.draft/3";
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_AMBISONIC[] = "ambisonic";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum clap_ambisonic_ordering {
|
||||
// FuMa channel ordering
|
||||
CLAP_AMBISONIC_ORDERING_FUMA = 0,
|
||||
|
||||
// ACN channel ordering
|
||||
CLAP_AMBISONIC_ORDERING_ACN = 1,
|
||||
};
|
||||
|
||||
enum clap_ambisonic_normalization {
|
||||
CLAP_AMBISONIC_NORMALIZATION_MAXN = 0,
|
||||
CLAP_AMBISONIC_NORMALIZATION_SN3D = 1,
|
||||
CLAP_AMBISONIC_NORMALIZATION_N3D = 2,
|
||||
CLAP_AMBISONIC_NORMALIZATION_SN2D = 3,
|
||||
CLAP_AMBISONIC_NORMALIZATION_N2D = 4,
|
||||
};
|
||||
|
||||
typedef struct clap_ambisonic_config {
|
||||
uint32_t ordering; // see clap_ambisonic_ordering
|
||||
uint32_t normalization; // see clap_ambisonic_normalization
|
||||
} clap_ambisonic_config_t;
|
||||
|
||||
typedef struct clap_plugin_ambisonic {
|
||||
// Returns true if the given configuration is supported.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *is_config_supported)(const clap_plugin_t *plugin,
|
||||
const clap_ambisonic_config_t *config);
|
||||
|
||||
// Returns true on success
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get_config)(const clap_plugin_t *plugin,
|
||||
bool is_input,
|
||||
uint32_t port_index,
|
||||
clap_ambisonic_config_t *config);
|
||||
|
||||
} clap_plugin_ambisonic_t;
|
||||
|
||||
typedef struct clap_host_ambisonic {
|
||||
// Informs the host that the info has changed.
|
||||
// The info can only change when the plugin is de-activated.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
} clap_host_ambisonic_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
64
tests/clap/ext/audio-ports-activation.h
Normal file
64
tests/clap/ext/audio-ports-activation.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
/// @page Audio Ports Activation
|
||||
///
|
||||
/// This extension provides a way for the host to activate and de-activate audio ports.
|
||||
/// Deactivating a port provides the following benefits:
|
||||
/// - the plugin knows ahead of time that a given input is not present and can choose
|
||||
/// an optimized computation path,
|
||||
/// - the plugin knows that an output is not consumed by the host, and doesn't need to
|
||||
/// compute it.
|
||||
///
|
||||
/// Audio ports can only be activated or deactivated when the plugin is deactivated, unless
|
||||
/// can_activate_while_processing() returns true.
|
||||
///
|
||||
/// Audio buffers must still be provided if the audio port is deactivated.
|
||||
/// In such case, they shall be filled with 0 (or whatever is the neutral value in your context)
|
||||
/// and the constant_mask shall be set.
|
||||
///
|
||||
/// Audio ports are initially in the active state after creating the plugin instance.
|
||||
/// Audio ports state are not saved in the plugin state, so the host must restore the
|
||||
/// audio ports state after creating the plugin instance.
|
||||
///
|
||||
/// Audio ports state is invalidated by clap_plugin_audio_ports_config.select() and
|
||||
/// clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_LIST).
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_ACTIVATION[] =
|
||||
"clap.audio-ports-activation/2";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_ACTIVATION_COMPAT[] =
|
||||
"clap.audio-ports-activation/draft-2";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_audio_ports_activation {
|
||||
// Returns true if the plugin supports activation/deactivation while processing.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *can_activate_while_processing)(const clap_plugin_t *plugin);
|
||||
|
||||
// Activate the given port.
|
||||
//
|
||||
// It is only possible to activate and de-activate on the audio-thread if
|
||||
// can_activate_while_processing() returns true.
|
||||
//
|
||||
// sample_size indicate if the host will provide 32 bit audio buffers or 64 bits one.
|
||||
// Possible values are: 32, 64 or 0 if unspecified.
|
||||
//
|
||||
// returns false if failed, or invalid parameters
|
||||
// [active ? audio-thread : main-thread]
|
||||
bool(CLAP_ABI *set_active)(const clap_plugin_t *plugin,
|
||||
bool is_input,
|
||||
uint32_t port_index,
|
||||
bool is_active,
|
||||
uint32_t sample_size);
|
||||
} clap_plugin_audio_ports_activation_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
109
tests/clap/ext/audio-ports-config.h
Normal file
109
tests/clap/ext/audio-ports-config.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#pragma once
|
||||
|
||||
#include "../string-sizes.h"
|
||||
#include "../plugin.h"
|
||||
#include "audio-ports.h"
|
||||
|
||||
/// @page Audio Ports Config
|
||||
///
|
||||
/// This extension let the plugin provide port configurations presets.
|
||||
/// For example mono, stereo, surround, ambisonic, ...
|
||||
///
|
||||
/// After the plugin initialization, the host may scan the list of configurations and eventually
|
||||
/// select one that fits the plugin context. The host can only select a configuration if the plugin
|
||||
/// is deactivated.
|
||||
///
|
||||
/// A configuration is a very simple description of the audio ports:
|
||||
/// - it describes the main input and output ports
|
||||
/// - it has a name that can be displayed to the user
|
||||
///
|
||||
/// The idea behind the configurations, is to let the user choose one via a menu.
|
||||
///
|
||||
/// Plugins with very complex configuration possibilities should let the user configure the ports
|
||||
/// from the plugin GUI, and call @ref clap_host_audio_ports.rescan(CLAP_AUDIO_PORTS_RESCAN_ALL).
|
||||
///
|
||||
/// To inquire the exact bus layout, the plugin implements the clap_plugin_audio_ports_config_info_t
|
||||
/// extension where all busses can be retrieved in the same way as in the audio-port extension.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG[] = "clap.audio-ports-config";
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG_INFO[] =
|
||||
"clap.audio-ports-config-info/1";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS_CONFIG_INFO_COMPAT[] =
|
||||
"clap.audio-ports-config-info/draft-0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Minimalistic description of ports configuration
|
||||
typedef struct clap_audio_ports_config {
|
||||
clap_id id;
|
||||
char name[CLAP_NAME_SIZE];
|
||||
|
||||
uint32_t input_port_count;
|
||||
uint32_t output_port_count;
|
||||
|
||||
// main input info
|
||||
bool has_main_input;
|
||||
uint32_t main_input_channel_count;
|
||||
const char *main_input_port_type;
|
||||
|
||||
// main output info
|
||||
bool has_main_output;
|
||||
uint32_t main_output_channel_count;
|
||||
const char *main_output_port_type;
|
||||
} clap_audio_ports_config_t;
|
||||
|
||||
// The audio ports config scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_audio_ports_config {
|
||||
// Gets the number of available configurations
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin);
|
||||
|
||||
// Gets information about a configuration
|
||||
// Returns true on success and stores the result into config.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin,
|
||||
uint32_t index,
|
||||
clap_audio_ports_config_t *config);
|
||||
|
||||
// Selects the configuration designated by id
|
||||
// Returns true if the configuration could be applied.
|
||||
// Once applied the host should scan again the audio ports.
|
||||
// [main-thread & plugin-deactivated]
|
||||
bool(CLAP_ABI *select)(const clap_plugin_t *plugin, clap_id config_id);
|
||||
} clap_plugin_audio_ports_config_t;
|
||||
|
||||
// Extended config info
|
||||
typedef struct clap_plugin_audio_ports_config_info {
|
||||
|
||||
// Gets the id of the currently selected config, or CLAP_INVALID_ID if the current port
|
||||
// layout isn't part of the config list.
|
||||
//
|
||||
// [main-thread]
|
||||
clap_id(CLAP_ABI *current_config)(const clap_plugin_t *plugin);
|
||||
|
||||
// Get info about an audio port, for a given config_id.
|
||||
// This is analogous to clap_plugin_audio_ports.get().
|
||||
// Returns true on success and stores the result into info.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin,
|
||||
clap_id config_id,
|
||||
uint32_t port_index,
|
||||
bool is_input,
|
||||
clap_audio_port_info_t *info);
|
||||
} clap_plugin_audio_ports_config_info_t;
|
||||
|
||||
typedef struct clap_host_audio_ports_config {
|
||||
// Rescan the full list of configs.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *rescan)(const clap_host_t *host);
|
||||
} clap_host_audio_ports_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
116
tests/clap/ext/audio-ports.h
Normal file
116
tests/clap/ext/audio-ports.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
/// @page Audio Ports
|
||||
///
|
||||
/// This extension provides a way for the plugin to describe its current audio ports.
|
||||
///
|
||||
/// If the plugin does not implement this extension, it won't have audio ports.
|
||||
///
|
||||
/// 32 bits support is required for both host and plugins. 64 bits audio is optional.
|
||||
///
|
||||
/// The plugin is only allowed to change its ports configuration while it is deactivated.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_AUDIO_PORTS[] = "clap.audio-ports";
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_MONO[] = "mono";
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_STEREO[] = "stereo";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// This port is the main audio input or output.
|
||||
// There can be only one main input and main output.
|
||||
// Main port must be at index 0.
|
||||
CLAP_AUDIO_PORT_IS_MAIN = 1 << 0,
|
||||
|
||||
// This port can be used with 64 bits audio
|
||||
CLAP_AUDIO_PORT_SUPPORTS_64BITS = 1 << 1,
|
||||
|
||||
// 64 bits audio is preferred with this port
|
||||
CLAP_AUDIO_PORT_PREFERS_64BITS = 1 << 2,
|
||||
|
||||
// This port must be used with the same sample size as all the other ports which have this flag.
|
||||
// In other words if all ports have this flag then the plugin may either be used entirely with
|
||||
// 64 bits audio or 32 bits audio, but it can't be mixed.
|
||||
CLAP_AUDIO_PORT_REQUIRES_COMMON_SAMPLE_SIZE = 1 << 3,
|
||||
};
|
||||
|
||||
typedef struct clap_audio_port_info {
|
||||
// id identifies a port and must be stable.
|
||||
// id may overlap between input and output ports.
|
||||
clap_id id;
|
||||
char name[CLAP_NAME_SIZE]; // displayable name
|
||||
|
||||
uint32_t flags;
|
||||
uint32_t channel_count;
|
||||
|
||||
// If null or empty then it is unspecified (arbitrary audio).
|
||||
// This field can be compared against:
|
||||
// - CLAP_PORT_MONO
|
||||
// - CLAP_PORT_STEREO
|
||||
// - CLAP_PORT_SURROUND (defined in the surround extension)
|
||||
// - CLAP_PORT_AMBISONIC (defined in the ambisonic extension)
|
||||
//
|
||||
// An extension can provide its own port type and way to inspect the channels.
|
||||
const char *port_type;
|
||||
|
||||
// in-place processing: allow the host to use the same buffer for input and output
|
||||
// if supported set the pair port id.
|
||||
// if not supported set to CLAP_INVALID_ID
|
||||
clap_id in_place_pair;
|
||||
} clap_audio_port_info_t;
|
||||
|
||||
// The audio ports scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_audio_ports {
|
||||
// Number of ports, for either input or output
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input);
|
||||
|
||||
// Get info about an audio port.
|
||||
// Returns true on success and stores the result into info.
|
||||
// [main-thread]
|
||||
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;
|
||||
|
||||
enum {
|
||||
// The ports name did change, the host can scan them right away.
|
||||
CLAP_AUDIO_PORTS_RESCAN_NAMES = 1 << 0,
|
||||
|
||||
// [!active] The flags did change
|
||||
CLAP_AUDIO_PORTS_RESCAN_FLAGS = 1 << 1,
|
||||
|
||||
// [!active] The channel_count did change
|
||||
CLAP_AUDIO_PORTS_RESCAN_CHANNEL_COUNT = 1 << 2,
|
||||
|
||||
// [!active] The port type did change
|
||||
CLAP_AUDIO_PORTS_RESCAN_PORT_TYPE = 1 << 3,
|
||||
|
||||
// [!active] The in-place pair did change, this requires.
|
||||
CLAP_AUDIO_PORTS_RESCAN_IN_PLACE_PAIR = 1 << 4,
|
||||
|
||||
// [!active] The list of ports have changed: entries have been removed/added.
|
||||
CLAP_AUDIO_PORTS_RESCAN_LIST = 1 << 5,
|
||||
};
|
||||
|
||||
typedef struct clap_host_audio_ports {
|
||||
// Checks if the host allows a plugin to change a given aspect of the audio ports definition.
|
||||
// [main-thread]
|
||||
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.
|
||||
// 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.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *rescan)(const clap_host_t *host, uint32_t flags);
|
||||
} clap_host_audio_ports_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
63
tests/clap/ext/configurable-audio-ports.h
Normal file
63
tests/clap/ext/configurable-audio-ports.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include "audio-ports.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This extension lets the host configure the plugin's input and output audio ports.
|
||||
// This is a "push" approach to audio ports configuration.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_CONFIGURABLE_AUDIO_PORTS[] =
|
||||
"clap.configurable-audio-ports/1";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_CONFIGURABLE_AUDIO_PORTS_COMPAT[] =
|
||||
"clap.configurable-audio-ports.draft1";
|
||||
|
||||
typedef struct clap_audio_port_configuration_request {
|
||||
// Identifies the port by is_input and port_index
|
||||
bool is_input;
|
||||
uint32_t port_index;
|
||||
|
||||
// The requested number of channels.
|
||||
uint32_t channel_count;
|
||||
|
||||
// The port type, see audio-ports.h, clap_audio_port_info.port_type for interpretation.
|
||||
const char *port_type;
|
||||
|
||||
// cast port_details according to port_type:
|
||||
// - CLAP_PORT_MONO: (discard)
|
||||
// - CLAP_PORT_STEREO: (discard)
|
||||
// - CLAP_PORT_SURROUND: const uint8_t *channel_map
|
||||
// - CLAP_PORT_AMBISONIC: const clap_ambisonic_config_t *info
|
||||
const void *port_details;
|
||||
} clap_audio_port_configuration_request_t;
|
||||
|
||||
typedef struct clap_plugin_configurable_audio_ports {
|
||||
// Returns true if the given configurations can be applied using apply_configuration().
|
||||
// [main-thread && !active]
|
||||
bool(CLAP_ABI *can_apply_configuration)(
|
||||
const clap_plugin_t *plugin,
|
||||
const struct clap_audio_port_configuration_request *requests,
|
||||
uint32_t request_count);
|
||||
|
||||
// Submit a bunch of configuration requests which will atomically be applied together,
|
||||
// or discarded together.
|
||||
//
|
||||
// Once the configuration is successfully applied, it isn't necessary for the plugin to call
|
||||
// clap_host_audio_ports->changed(); and it isn't necessary for the host to scan the
|
||||
// audio ports.
|
||||
//
|
||||
// Returns true if applied.
|
||||
// [main-thread && !active]
|
||||
bool(CLAP_ABI *apply_configuration)(const clap_plugin_t *plugin,
|
||||
const struct clap_audio_port_configuration_request *requests,
|
||||
uint32_t request_count);
|
||||
} clap_plugin_configurable_audio_ports_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
167
tests/clap/ext/context-menu.h
Normal file
167
tests/clap/ext/context-menu.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
// This extension lets the host and plugin exchange menu items and let the plugin ask the host to
|
||||
// show its context menu.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_CONTEXT_MENU[] = "clap.context-menu/1";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_CONTEXT_MENU_COMPAT[] = "clap.context-menu.draft/0";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// There can be different target kind for a context menu
|
||||
enum {
|
||||
CLAP_CONTEXT_MENU_TARGET_KIND_GLOBAL = 0,
|
||||
CLAP_CONTEXT_MENU_TARGET_KIND_PARAM = 1,
|
||||
};
|
||||
|
||||
// Describes the context menu target
|
||||
typedef struct clap_context_menu_target {
|
||||
uint32_t kind;
|
||||
clap_id id;
|
||||
} clap_context_menu_target_t;
|
||||
|
||||
enum {
|
||||
// Adds a clickable menu entry.
|
||||
// data: const clap_context_menu_item_entry_t*
|
||||
CLAP_CONTEXT_MENU_ITEM_ENTRY,
|
||||
|
||||
// Adds a clickable menu entry which will feature both a checkmark and a label.
|
||||
// data: const clap_context_menu_item_check_entry_t*
|
||||
CLAP_CONTEXT_MENU_ITEM_CHECK_ENTRY,
|
||||
|
||||
// Adds a separator line.
|
||||
// data: NULL
|
||||
CLAP_CONTEXT_MENU_ITEM_SEPARATOR,
|
||||
|
||||
// Starts a sub menu with the given label.
|
||||
// data: const clap_context_menu_item_begin_submenu_t*
|
||||
CLAP_CONTEXT_MENU_ITEM_BEGIN_SUBMENU,
|
||||
|
||||
// Ends the current sub menu.
|
||||
// data: NULL
|
||||
CLAP_CONTEXT_MENU_ITEM_END_SUBMENU,
|
||||
|
||||
// Adds a title entry
|
||||
// data: const clap_context_menu_item_title_t *
|
||||
CLAP_CONTEXT_MENU_ITEM_TITLE,
|
||||
};
|
||||
typedef uint32_t clap_context_menu_item_kind_t;
|
||||
|
||||
typedef struct clap_context_menu_entry {
|
||||
// text to be displayed
|
||||
const char *label;
|
||||
|
||||
// if false, then the menu entry is greyed out and not clickable
|
||||
bool is_enabled;
|
||||
clap_id action_id;
|
||||
} clap_context_menu_entry_t;
|
||||
|
||||
typedef struct clap_context_menu_check_entry {
|
||||
// text to be displayed
|
||||
const char *label;
|
||||
|
||||
// if false, then the menu entry is greyed out and not clickable
|
||||
bool is_enabled;
|
||||
|
||||
// if true, then the menu entry will be displayed as checked
|
||||
bool is_checked;
|
||||
clap_id action_id;
|
||||
} clap_context_menu_check_entry_t;
|
||||
|
||||
typedef struct clap_context_menu_item_title {
|
||||
// text to be displayed
|
||||
const char *title;
|
||||
|
||||
// if false, then the menu entry is greyed out
|
||||
bool is_enabled;
|
||||
} clap_context_menu_item_title_t;
|
||||
|
||||
typedef struct clap_context_menu_submenu {
|
||||
// text to be displayed
|
||||
const char *label;
|
||||
|
||||
// if false, then the menu entry is greyed out and won't show submenu
|
||||
bool is_enabled;
|
||||
} clap_context_menu_submenu_t;
|
||||
|
||||
// Context menu builder.
|
||||
// This object isn't thread-safe and must be used on the same thread as it was provided.
|
||||
typedef struct clap_context_menu_builder {
|
||||
void *ctx;
|
||||
|
||||
// Adds an entry to the menu.
|
||||
// item_data type is determined by item_kind.
|
||||
// Returns true on success.
|
||||
bool(CLAP_ABI *add_item)(const struct clap_context_menu_builder *builder,
|
||||
clap_context_menu_item_kind_t item_kind,
|
||||
const void *item_data);
|
||||
|
||||
// Returns true if the menu builder supports the given item kind
|
||||
bool(CLAP_ABI *supports)(const struct clap_context_menu_builder *builder,
|
||||
clap_context_menu_item_kind_t item_kind);
|
||||
} clap_context_menu_builder_t;
|
||||
|
||||
typedef struct clap_plugin_context_menu {
|
||||
// Insert plugin's menu items into the menu builder.
|
||||
// If target is null, assume global context.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *populate)(const clap_plugin_t *plugin,
|
||||
const clap_context_menu_target_t *target,
|
||||
const clap_context_menu_builder_t *builder);
|
||||
|
||||
// Performs the given action, which was previously provided to the host via populate().
|
||||
// If target is null, assume global context.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *perform)(const clap_plugin_t *plugin,
|
||||
const clap_context_menu_target_t *target,
|
||||
clap_id action_id);
|
||||
} clap_plugin_context_menu_t;
|
||||
|
||||
typedef struct clap_host_context_menu {
|
||||
// Insert host's menu items into the menu builder.
|
||||
// If target is null, assume global context.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *populate)(const clap_host_t *host,
|
||||
const clap_context_menu_target_t *target,
|
||||
const clap_context_menu_builder_t *builder);
|
||||
|
||||
// Performs the given action, which was previously provided to the plugin via populate().
|
||||
// If target is null, assume global context.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *perform)(const clap_host_t *host,
|
||||
const clap_context_menu_target_t *target,
|
||||
clap_id action_id);
|
||||
|
||||
// Returns true if the host can display a popup menu for the plugin.
|
||||
// This may depend upon the current windowing system used to display the plugin, so the
|
||||
// return value is invalidated after creating the plugin window.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *can_popup)(const clap_host_t *host);
|
||||
|
||||
// Shows the host popup menu for a given parameter.
|
||||
// If the plugin is using embedded GUI, then x and y are relative to the plugin's window,
|
||||
// otherwise they're absolute coordinate, and screen index might be set accordingly.
|
||||
// If target is null, assume global context.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *popup)(const clap_host_t *host,
|
||||
const clap_context_menu_target_t *target,
|
||||
int32_t screen_index,
|
||||
int32_t x,
|
||||
int32_t y);
|
||||
} clap_host_context_menu_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
33
tests/clap/ext/draft/extensible-audio-ports.h
Normal file
33
tests/clap/ext/draft/extensible-audio-ports.h
Normal 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
|
||||
34
tests/clap/ext/draft/gain-adjustment-metering.h
Normal file
34
tests/clap/ext/draft/gain-adjustment-metering.h
Normal 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
|
||||
153
tests/clap/ext/draft/mini-curve-display.h
Normal file
153
tests/clap/ext/draft/mini-curve-display.h
Normal 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
|
||||
108
tests/clap/ext/draft/project-location.h
Normal file
108
tests/clap/ext/draft/project-location.h
Normal 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
|
||||
88
tests/clap/ext/draft/resource-directory.h
Normal file
88
tests/clap/ext/draft/resource-directory.h
Normal 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
|
||||
90
tests/clap/ext/draft/scratch-memory.h
Normal file
90
tests/clap/ext/draft/scratch-memory.h
Normal 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
|
||||
66
tests/clap/ext/draft/transport-control.h
Normal file
66
tests/clap/ext/draft/transport-control.h
Normal 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
|
||||
144
tests/clap/ext/draft/triggers.h
Normal file
144
tests/clap/ext/draft/triggers.h
Normal 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
|
||||
76
tests/clap/ext/draft/tuning.h
Normal file
76
tests/clap/ext/draft/tuning.h
Normal 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
201
tests/clap/ext/draft/undo.h
Normal 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
|
||||
22
tests/clap/ext/event-registry.h
Normal file
22
tests/clap/ext/event-registry.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_EVENT_REGISTRY[] = "clap.event-registry";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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_id to UINT16_MAX if the space name is unknown to the host.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *query)(const clap_host_t *host, const char *space_name, uint16_t *space_id);
|
||||
} clap_host_event_registry_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
244
tests/clap/ext/gui.h
Normal file
244
tests/clap/ext/gui.h
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
/// @page GUI
|
||||
///
|
||||
/// This extension defines how the plugin will present its GUI.
|
||||
///
|
||||
/// There are two approaches:
|
||||
/// 1. the plugin creates a window and embeds it into the host's window
|
||||
/// 2. the plugin creates a floating window
|
||||
///
|
||||
/// Embedding the window gives more control to the host, and feels more integrated.
|
||||
/// Floating window are sometimes the only option due to technical limitations.
|
||||
///
|
||||
/// The Embedding protocol is by far the most common, supported by all hosts to date,
|
||||
/// and a plugin author should support at least that case.
|
||||
///
|
||||
/// Showing the GUI works as follow:
|
||||
/// 1. clap_plugin_gui->is_api_supported(), check what can work
|
||||
/// 2. clap_plugin_gui->create(), allocates gui resources
|
||||
/// 3. if the plugin window is floating
|
||||
/// 4. -> clap_plugin_gui->set_transient()
|
||||
/// 5. -> clap_plugin_gui->suggest_title()
|
||||
/// 6. else
|
||||
/// 7. -> clap_plugin_gui->set_scale()
|
||||
/// 8. -> clap_plugin_gui->can_resize()
|
||||
/// 9. -> if resizable and has known size from previous session, clap_plugin_gui->set_size()
|
||||
/// 10. -> else clap_plugin_gui->get_size(), gets initial size
|
||||
/// 11. -> clap_plugin_gui->set_parent()
|
||||
/// 12. clap_plugin_gui->show()
|
||||
/// 13. clap_plugin_gui->hide()/show() ...
|
||||
/// 14. clap_plugin_gui->destroy() when done with the gui
|
||||
///
|
||||
/// Resizing the window (initiated by the plugin, if embedded):
|
||||
/// 1. Plugins calls clap_host_gui->request_resize()
|
||||
/// 2. If the host returns true the new size is accepted,
|
||||
/// the host doesn't have to call clap_plugin_gui->set_size().
|
||||
/// If the host returns false, the new size is rejected.
|
||||
///
|
||||
/// Resizing the window (drag, if embedded)):
|
||||
/// 1. Only possible if clap_plugin_gui->can_resize() returns true
|
||||
/// 2. Mouse drag -> new_size
|
||||
/// 3. clap_plugin_gui->adjust_size(new_size) -> working_size
|
||||
/// 4. clap_plugin_gui->set_size(working_size)
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_GUI[] = "clap.gui";
|
||||
|
||||
// If your windowing API is not listed here, please open an issue and we'll figure it out.
|
||||
// https://github.com/free-audio/clap/issues/new
|
||||
|
||||
// uses physical size
|
||||
// embed using https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setparent
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_WIN32[] = "win32";
|
||||
|
||||
// uses logical size, don't call clap_plugin_gui->set_scale()
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_COCOA[] = "cocoa";
|
||||
|
||||
// uses physical size
|
||||
// embed using https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_X11[] = "x11";
|
||||
|
||||
// uses physical size
|
||||
// embed is currently not supported, use floating windows
|
||||
static const CLAP_CONSTEXPR char CLAP_WINDOW_API_WAYLAND[] = "wayland";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *clap_hwnd;
|
||||
typedef void *clap_nsview;
|
||||
typedef unsigned long clap_xwnd;
|
||||
|
||||
// Represent a window reference.
|
||||
typedef struct clap_window {
|
||||
const char *api; // one of CLAP_WINDOW_API_XXX
|
||||
union {
|
||||
clap_nsview cocoa;
|
||||
clap_xwnd x11;
|
||||
clap_hwnd win32;
|
||||
void *ptr; // for anything defined outside of clap
|
||||
};
|
||||
} clap_window_t;
|
||||
|
||||
// Information to improve window resizing when initiated by the host or window manager.
|
||||
typedef struct clap_gui_resize_hints {
|
||||
bool can_resize_horizontally;
|
||||
bool can_resize_vertically;
|
||||
|
||||
// if both horizontal and vertical resize are available, do we preserve the
|
||||
// aspect ratio, and if so, what is the width x height aspect ratio to preserve.
|
||||
// These flags are unused if can_resize_horizontally or vertically are false,
|
||||
// and ratios are unused if preserve is false.
|
||||
bool preserve_aspect_ratio;
|
||||
uint32_t aspect_ratio_width;
|
||||
uint32_t aspect_ratio_height;
|
||||
} clap_gui_resize_hints_t;
|
||||
|
||||
// Size (width, height) is in pixels; the corresponding windowing system extension is
|
||||
// responsible for defining if it is physical pixels or logical pixels.
|
||||
typedef struct clap_plugin_gui {
|
||||
// Returns true if the requested gui api is supported, either in floating (plugin-created)
|
||||
// or non-floating (embedded) mode.
|
||||
// [main-thread]
|
||||
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.
|
||||
// The host has no obligation to honor the plugin preference, 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]
|
||||
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.
|
||||
//
|
||||
// If is_floating is true, then the window will not be managed by the host. The plugin
|
||||
// can set its window to stays above the parent window, see set_transient().
|
||||
// api may be null or blank for floating window.
|
||||
//
|
||||
// If is_floating is false, then the plugin has to embed its window into the parent window, see
|
||||
// set_parent().
|
||||
//
|
||||
// After this call, the GUI may not be visible yet; don't forget to call show().
|
||||
//
|
||||
// Returns true if the GUI is successfully created.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *create)(const clap_plugin_t *plugin, const char *api, bool is_floating);
|
||||
|
||||
// Free all resources associated with the gui.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *destroy)(const clap_plugin_t *plugin);
|
||||
|
||||
// Set the absolute GUI scaling factor, and override any OS info.
|
||||
// Should not be used if the windowing api relies upon logical pixels.
|
||||
//
|
||||
// If the plugin prefers to work out the scaling factor itself by querying the OS directly,
|
||||
// then ignore the call.
|
||||
//
|
||||
// scale = 2 means 200% scaling.
|
||||
//
|
||||
// Returns true if the scaling could be applied
|
||||
// Returns false if the call was ignored, or the scaling could not be applied.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *set_scale)(const clap_plugin_t *plugin, double scale);
|
||||
|
||||
// Get the current size of the plugin UI.
|
||||
// clap_plugin_gui->create() must have been called prior to asking the size.
|
||||
//
|
||||
// Returns true if the plugin could get the size.
|
||||
// [main-thread]
|
||||
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).
|
||||
// [main-thread & !floating]
|
||||
bool(CLAP_ABI *can_resize)(const clap_plugin_t *plugin);
|
||||
|
||||
// Returns true if the plugin can provide hints on how to resize the window.
|
||||
// [main-thread & !floating]
|
||||
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
|
||||
// usable size which fits in the given size.
|
||||
// This method does not change the size.
|
||||
//
|
||||
// Returns true if the plugin could adjust the given size.
|
||||
// [main-thread & !floating]
|
||||
bool(CLAP_ABI *adjust_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height);
|
||||
|
||||
// Sets the window size.
|
||||
//
|
||||
// Returns true if the plugin could resize its window to the given size.
|
||||
// [main-thread & !floating]
|
||||
bool(CLAP_ABI *set_size)(const clap_plugin_t *plugin, uint32_t width, uint32_t height);
|
||||
|
||||
// Embeds the plugin window into the given window.
|
||||
//
|
||||
// Returns true on success.
|
||||
// [main-thread & !floating]
|
||||
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.
|
||||
//
|
||||
// Returns true on success.
|
||||
// [main-thread & floating]
|
||||
bool(CLAP_ABI *set_transient)(const clap_plugin_t *plugin, const clap_window_t *window);
|
||||
|
||||
// Suggests a window title. Only for floating windows.
|
||||
//
|
||||
// [main-thread & floating]
|
||||
void(CLAP_ABI *suggest_title)(const clap_plugin_t *plugin, const char *title);
|
||||
|
||||
// Show the window.
|
||||
//
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *show)(const clap_plugin_t *plugin);
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *hide)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_gui_t;
|
||||
|
||||
typedef struct clap_host_gui {
|
||||
// The host should call get_resize_hints() again.
|
||||
// [thread-safe & !floating]
|
||||
void(CLAP_ABI *resize_hints_changed)(const clap_host_t *host);
|
||||
|
||||
// Request the host to resize the client area to width, height.
|
||||
// Return true if the new size is accepted, false otherwise.
|
||||
// The host doesn't have to call set_size().
|
||||
//
|
||||
// Note: if not called from the main thread, then a return value simply means that the host
|
||||
// acknowledged the request and will process it asynchronously. If the request then can't be
|
||||
// satisfied then the host will call set_size() to revert the operation.
|
||||
// [thread-safe & !floating]
|
||||
bool(CLAP_ABI *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.
|
||||
// [thread-safe]
|
||||
bool(CLAP_ABI *request_show)(const clap_host_t *host);
|
||||
|
||||
// Request the host to hide the plugin gui.
|
||||
// Return true on success, false otherwise.
|
||||
// [thread-safe]
|
||||
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.
|
||||
//
|
||||
// If was_destroyed is true, then the host must call clap_plugin_gui->destroy() to acknowledge
|
||||
// the gui destruction.
|
||||
// [thread-safe]
|
||||
void(CLAP_ABI *closed)(const clap_host_t *host, bool was_destroyed);
|
||||
} clap_host_gui_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
27
tests/clap/ext/latency.h
Normal file
27
tests/clap/ext/latency.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_LATENCY[] = "clap.latency";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_latency {
|
||||
// Returns the plugin latency in samples.
|
||||
// [main-thread & (being-activated | active)]
|
||||
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 during plugin->activate.
|
||||
// If the plugin is activated, call host->request_restart()
|
||||
// [main-thread & being-activated]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
} clap_host_latency_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
33
tests/clap/ext/log.h
Normal file
33
tests/clap/ext/log.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_LOG[] = "clap.log";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CLAP_LOG_DEBUG = 0,
|
||||
CLAP_LOG_INFO = 1,
|
||||
CLAP_LOG_WARNING = 2,
|
||||
CLAP_LOG_ERROR = 3,
|
||||
CLAP_LOG_FATAL = 4,
|
||||
|
||||
// These severities should be used to report misbehaviour.
|
||||
// The plugin one can be used by a layer between the plugin and the host.
|
||||
CLAP_LOG_HOST_MISBEHAVING = 5,
|
||||
CLAP_LOG_PLUGIN_MISBEHAVING = 6,
|
||||
};
|
||||
typedef int32_t clap_log_severity;
|
||||
|
||||
typedef struct clap_host_log {
|
||||
// Log a message through the host.
|
||||
// [thread-safe]
|
||||
void(CLAP_ABI *log)(const clap_host_t *host, clap_log_severity severity, const char *msg);
|
||||
} clap_host_log_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
37
tests/clap/ext/note-name.h
Normal file
37
tests/clap/ext/note-name.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_NOTE_NAME[] = "clap.note-name";
|
||||
|
||||
typedef struct clap_note_name {
|
||||
char name[CLAP_NAME_SIZE];
|
||||
int16_t port; // -1 for every port
|
||||
int16_t key; // -1 for every key
|
||||
int16_t channel; // -1 for every channel
|
||||
} clap_note_name_t;
|
||||
|
||||
typedef struct clap_plugin_note_name {
|
||||
// Return the number of note names
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin);
|
||||
|
||||
// Returns true on success and stores the result into note_name
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin, uint32_t index, clap_note_name_t *note_name);
|
||||
} clap_plugin_note_name_t;
|
||||
|
||||
typedef struct clap_host_note_name {
|
||||
// Informs the host that the note names have changed.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
} clap_host_note_name_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
79
tests/clap/ext/note-ports.h
Normal file
79
tests/clap/ext/note-ports.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
/// @page Note Ports
|
||||
///
|
||||
/// This extension provides a way for the plugin to describe its current note ports.
|
||||
/// If the plugin does not implement this extension, it won't have note input or output.
|
||||
/// The plugin is only allowed to change its note ports configuration while it is deactivated.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_NOTE_PORTS[] = "clap.note-ports";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum clap_note_dialect {
|
||||
// Uses clap_event_note and clap_event_note_expression.
|
||||
CLAP_NOTE_DIALECT_CLAP = 1 << 0,
|
||||
|
||||
// Uses clap_event_midi, no polyphonic expression
|
||||
CLAP_NOTE_DIALECT_MIDI = 1 << 1,
|
||||
|
||||
// Uses clap_event_midi, with polyphonic expression (MPE)
|
||||
CLAP_NOTE_DIALECT_MIDI_MPE = 1 << 2,
|
||||
|
||||
// Uses clap_event_midi2
|
||||
CLAP_NOTE_DIALECT_MIDI2 = 1 << 3,
|
||||
};
|
||||
|
||||
typedef struct clap_note_port_info {
|
||||
// id identifies a port and must be stable.
|
||||
// id may overlap between input and output ports.
|
||||
clap_id id;
|
||||
uint32_t supported_dialects; // bitfield, see clap_note_dialect
|
||||
uint32_t preferred_dialect; // one value of clap_note_dialect
|
||||
char name[CLAP_NAME_SIZE]; // displayable name, i18n?
|
||||
} clap_note_port_info_t;
|
||||
|
||||
// The note ports scan has to be done while the plugin is deactivated.
|
||||
typedef struct clap_plugin_note_ports {
|
||||
// Number of ports, for either input or output.
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin, bool is_input);
|
||||
|
||||
// Get info about a note port.
|
||||
// Returns true on success and stores the result into info.
|
||||
// [main-thread]
|
||||
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;
|
||||
|
||||
enum {
|
||||
// The ports have changed, the host shall perform a full scan of the ports.
|
||||
// This flag can only be used if the plugin is not active.
|
||||
// If the plugin active, call host->request_restart() and then call rescan()
|
||||
// when the host calls deactivate()
|
||||
CLAP_NOTE_PORTS_RESCAN_ALL = 1 << 0,
|
||||
|
||||
// The ports name did change, the host can scan them right away.
|
||||
CLAP_NOTE_PORTS_RESCAN_NAMES = 1 << 1,
|
||||
};
|
||||
|
||||
typedef struct clap_host_note_ports {
|
||||
// Query which dialects the host supports
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *supported_dialects)(const clap_host_t *host);
|
||||
|
||||
// Rescan the full list of note ports according to the flags.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *rescan)(const clap_host_t *host, uint32_t flags);
|
||||
} clap_host_note_ports_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
77
tests/clap/ext/param-indication.h
Normal file
77
tests/clap/ext/param-indication.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#pragma once
|
||||
|
||||
#include "params.h"
|
||||
#include "../color.h"
|
||||
|
||||
// This extension lets the host tell the plugin to display a little color based indication on the
|
||||
// parameter. This can be used to indicate:
|
||||
// - a physical controller is mapped to a parameter
|
||||
// - the parameter is current playing an automation
|
||||
// - the parameter is overriding the automation
|
||||
// - etc...
|
||||
//
|
||||
// The color semantic depends upon the host here and the goal is to have a consistent experience
|
||||
// across all plugins.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_PARAM_INDICATION[] = "clap.param-indication/4";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_PARAM_INDICATION_COMPAT[] = "clap.param-indication.draft/4";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// The host doesn't have an automation for this parameter
|
||||
CLAP_PARAM_INDICATION_AUTOMATION_NONE = 0,
|
||||
|
||||
// The host has an automation for this parameter, but it isn't playing it
|
||||
CLAP_PARAM_INDICATION_AUTOMATION_PRESENT = 1,
|
||||
|
||||
// The host is playing an automation for this parameter
|
||||
CLAP_PARAM_INDICATION_AUTOMATION_PLAYING = 2,
|
||||
|
||||
// The host is recording an automation on this parameter
|
||||
CLAP_PARAM_INDICATION_AUTOMATION_RECORDING = 3,
|
||||
|
||||
// The host should play an automation for this parameter, but the user has started to adjust this
|
||||
// parameter and is overriding the automation playback
|
||||
CLAP_PARAM_INDICATION_AUTOMATION_OVERRIDING = 4,
|
||||
};
|
||||
|
||||
typedef struct clap_plugin_param_indication {
|
||||
// Sets or clears a mapping indication.
|
||||
//
|
||||
// has_mapping: does the parameter currently has a mapping?
|
||||
// color: if set, the color to use to highlight the control in the plugin GUI
|
||||
// label: if set, a small string to display on top of the knob which identifies the hardware
|
||||
// controller description: if set, a string which can be used in a tooltip, which describes the
|
||||
// current mapping
|
||||
//
|
||||
// Parameter indications should not be saved in the plugin context, and are off by default.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *set_mapping)(const clap_plugin_t *plugin,
|
||||
clap_id param_id,
|
||||
bool has_mapping,
|
||||
const clap_color_t *color,
|
||||
const char *label,
|
||||
const char *description);
|
||||
|
||||
// Sets or clears an automation indication.
|
||||
//
|
||||
// automation_state: current automation state for the given parameter
|
||||
// color: if set, the color to use to display the automation indication in the plugin GUI
|
||||
//
|
||||
// Parameter indications should not be saved in the plugin context, and are off by default.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *set_automation)(const clap_plugin_t *plugin,
|
||||
clap_id param_id,
|
||||
uint32_t automation_state,
|
||||
const clap_color_t *color);
|
||||
} clap_plugin_param_indication_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
382
tests/clap/ext/params.h
Normal file
382
tests/clap/ext/params.h
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
/// @page Parameters
|
||||
/// @brief parameters management
|
||||
///
|
||||
/// Main idea:
|
||||
///
|
||||
/// The host sees the plugin as an atomic entity; and acts as a controller on top of its parameters.
|
||||
/// The plugin is responsible for keeping its audio processor and its GUI in sync.
|
||||
///
|
||||
/// The host can at any time read parameters' value on the [main-thread] using
|
||||
/// @ref clap_plugin_params.get_value().
|
||||
///
|
||||
/// There are two options to communicate parameter value changes, and they are not concurrent.
|
||||
/// - send automation points during clap_plugin.process()
|
||||
/// - send automation points during clap_plugin_params.flush(), for parameter changes
|
||||
/// without processing audio
|
||||
///
|
||||
/// When the plugin changes a parameter value, it must inform the host.
|
||||
/// It will send @ref CLAP_EVENT_PARAM_VALUE event during process() or flush().
|
||||
/// If the user is adjusting the value, don't forget to mark the beginning and end
|
||||
/// of the gesture by sending CLAP_EVENT_PARAM_GESTURE_BEGIN and CLAP_EVENT_PARAM_GESTURE_END
|
||||
/// events.
|
||||
///
|
||||
/// @note MIDI CCs are tricky because you may not know when the parameter adjustment ends.
|
||||
/// Also if the host records incoming MIDI CC and parameter change automation at the same time,
|
||||
/// there will be a conflict at playback: MIDI CC vs Automation.
|
||||
/// The parameter automation will always target the same parameter because the param_id is stable.
|
||||
/// The MIDI CC may have a different mapping in the future and may result in a different playback.
|
||||
///
|
||||
/// When a MIDI CC changes a parameter's value, set the flag CLAP_EVENT_DONT_RECORD in
|
||||
/// clap_event_param.header.flags. That way the host may record the MIDI CC automation, but not the
|
||||
/// parameter change and there won't be conflict at playback.
|
||||
///
|
||||
/// Scenarios:
|
||||
///
|
||||
/// I. Loading a preset
|
||||
/// - load the preset in a temporary state
|
||||
/// - call @ref clap_host_params.rescan() if anything changed
|
||||
/// - call @ref clap_host_latency.changed() if latency changed
|
||||
/// - invalidate any other info that may be cached by the host
|
||||
/// - if the plugin is activated and the preset will introduce breaking changes
|
||||
/// (latency, audio ports, new parameters, ...) be sure to wait for the host
|
||||
/// to deactivate the plugin to apply those changes.
|
||||
/// If there are no breaking changes, the plugin can apply them them right away.
|
||||
/// The plugin is responsible for updating both its audio processor and its gui.
|
||||
///
|
||||
/// II. Turning a knob on the DAW interface
|
||||
/// - the host will send an automation event to the plugin via a process() or flush()
|
||||
///
|
||||
/// III. Turning a knob on the Plugin interface
|
||||
/// - the plugin is responsible for sending the parameter value to its audio processor
|
||||
/// - call clap_host_params->request_flush() or clap_host->request_process().
|
||||
/// - when the host calls either clap_plugin->process() or clap_plugin_params->flush(),
|
||||
/// send an automation event and don't forget to wrap the parameter change(s)
|
||||
/// with CLAP_EVENT_PARAM_GESTURE_BEGIN and CLAP_EVENT_PARAM_GESTURE_END to define the
|
||||
/// beginning and end of the gesture.
|
||||
///
|
||||
/// IV. Turning a knob via automation
|
||||
/// - host sends an automation point during clap_plugin->process() or clap_plugin_params->flush().
|
||||
/// - the plugin is responsible for updating its GUI
|
||||
///
|
||||
/// V. Turning a knob via plugin's internal MIDI mapping
|
||||
/// - the plugin sends a CLAP_EVENT_PARAM_VALUE output event, set should_record to false
|
||||
/// - the plugin is responsible for updating its GUI
|
||||
///
|
||||
/// VI. Adding or removing parameters
|
||||
/// - if the plugin is activated call clap_host->restart()
|
||||
/// - once the plugin isn't active:
|
||||
/// - apply the new state
|
||||
/// - if a parameter is gone or is created with an id that may have been used before,
|
||||
/// call clap_host_params.clear(host, param_id, CLAP_PARAM_CLEAR_ALL)
|
||||
/// - call clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL)
|
||||
///
|
||||
/// CLAP allows the plugin to change the parameter range, yet the plugin developer
|
||||
/// should be aware that doing so isn't without risk, especially if you made the
|
||||
/// promise to never change the sound. If you want to be 100% certain that the
|
||||
/// sound will not change with all host, then simply never change the range.
|
||||
///
|
||||
/// There are two approaches to automations, either you automate the plain value,
|
||||
/// or you automate the knob position. The first option will be robust to a range
|
||||
/// increase, while the second won't be.
|
||||
///
|
||||
/// If the host goes with the second approach (automating the knob position), it means
|
||||
/// that the plugin is hosted in a relaxed environment regarding sound changes (they are
|
||||
/// accepted, and not a concern as long as they are reasonable). Though, stepped parameters
|
||||
/// should be stored as plain value in the document.
|
||||
///
|
||||
/// If the host goes with the first approach, there will still be situation where the
|
||||
/// sound may inevitably change. For example, if the plugin increase the range, there
|
||||
/// is an automation playing at the max value and on top of that an LFO is applied.
|
||||
/// See the following curve:
|
||||
/// .
|
||||
/// . .
|
||||
/// ..... . .
|
||||
/// before: . . and after: . .
|
||||
///
|
||||
/// Persisting parameter values:
|
||||
///
|
||||
/// Plugins are responsible for persisting their parameter's values between
|
||||
/// sessions by implementing the state extension. Otherwise parameter value will
|
||||
/// not be recalled when reloading a project. Hosts should _not_ try to save and
|
||||
/// restore parameter values for plugins that don't implement the state
|
||||
/// extension.
|
||||
///
|
||||
/// Advice for the host:
|
||||
///
|
||||
/// - store plain values in the document (automation)
|
||||
/// - store modulation amount in plain value delta, not in percentage
|
||||
/// - when you apply a CC mapping, remember the min/max plain values so you can adjust
|
||||
/// - do not implement a parameter saving fall back for plugins that don't
|
||||
/// implement the state extension
|
||||
///
|
||||
/// Advice for the plugin:
|
||||
///
|
||||
/// - think carefully about your parameter range when designing your DSP
|
||||
/// - avoid shrinking parameter ranges, they are very likely to change the sound
|
||||
/// - consider changing the parameter range as a tradeoff: what you improve vs what you break
|
||||
/// - make sure to implement saving and loading the parameter values using the
|
||||
/// state extension
|
||||
/// - if you plan to use adapters for other plugin formats, then you need to pay extra
|
||||
/// attention to the adapter requirements
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_PARAMS[] = "clap.params";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Is this param stepped? (integer values only)
|
||||
// if so the double value is converted to integer using a cast (equivalent to trunc).
|
||||
CLAP_PARAM_IS_STEPPED = 1 << 0,
|
||||
|
||||
// Useful for periodic parameters like a phase
|
||||
CLAP_PARAM_IS_PERIODIC = 1 << 1,
|
||||
|
||||
// The parameter should not be shown to the user, because it is currently not used.
|
||||
// It is not necessary to process automation for this parameter.
|
||||
CLAP_PARAM_IS_HIDDEN = 1 << 2,
|
||||
|
||||
// The parameter can't be changed by the host.
|
||||
CLAP_PARAM_IS_READONLY = 1 << 3,
|
||||
|
||||
// This parameter is used to merge the plugin and host bypass button.
|
||||
// It implies that the parameter is stepped.
|
||||
// min: 0 -> bypass off
|
||||
// max: 1 -> bypass on
|
||||
CLAP_PARAM_IS_BYPASS = 1 << 4,
|
||||
|
||||
// When set:
|
||||
// - automation can be recorded
|
||||
// - automation can be played back
|
||||
//
|
||||
// The host can send live user changes for this parameter regardless of this flag.
|
||||
//
|
||||
// If this parameter 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_PARAM_IS_AUTOMATABLE = 1 << 5,
|
||||
|
||||
// Does this parameter support per note automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_NOTE_ID = 1 << 6,
|
||||
|
||||
// Does this parameter support per key automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_KEY = 1 << 7,
|
||||
|
||||
// Does this parameter support per channel automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_CHANNEL = 1 << 8,
|
||||
|
||||
// Does this parameter support per port automations?
|
||||
CLAP_PARAM_IS_AUTOMATABLE_PER_PORT = 1 << 9,
|
||||
|
||||
// Does this parameter support the modulation signal?
|
||||
CLAP_PARAM_IS_MODULATABLE = 1 << 10,
|
||||
|
||||
// Does this parameter support per note modulations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_NOTE_ID = 1 << 11,
|
||||
|
||||
// Does this parameter support per key modulations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_KEY = 1 << 12,
|
||||
|
||||
// Does this parameter support per channel modulations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_CHANNEL = 1 << 13,
|
||||
|
||||
// Does this parameter support per port modulations?
|
||||
CLAP_PARAM_IS_MODULATABLE_PER_PORT = 1 << 14,
|
||||
|
||||
// Any change to this parameter will affect the plugin output and requires to be done via
|
||||
// process() if the plugin is active.
|
||||
//
|
||||
// A simple example would be a DC Offset, changing it will change the output signal and must be
|
||||
// processed.
|
||||
CLAP_PARAM_REQUIRES_PROCESS = 1 << 15,
|
||||
|
||||
// This parameter represents an enumerated value.
|
||||
// If you set this flag, then you must set CLAP_PARAM_IS_STEPPED too.
|
||||
// All values from min to max must not have a blank value_to_text().
|
||||
CLAP_PARAM_IS_ENUM = 1 << 16,
|
||||
};
|
||||
typedef uint32_t clap_param_info_flags;
|
||||
|
||||
/* This describes a parameter */
|
||||
typedef struct clap_param_info {
|
||||
// Stable parameter identifier, it must never change.
|
||||
clap_id id;
|
||||
|
||||
clap_param_info_flags flags;
|
||||
|
||||
// This value is optional and set by the plugin.
|
||||
// Its purpose is to provide fast access to the plugin parameter object by caching its pointer.
|
||||
// For instance:
|
||||
//
|
||||
// in clap_plugin_params.get_info():
|
||||
// Parameter *p = findParameter(param_id);
|
||||
// param_info->cookie = p;
|
||||
//
|
||||
// later, in clap_plugin.process():
|
||||
//
|
||||
// Parameter *p = (Parameter *)event->cookie;
|
||||
// if (!p) [[unlikely]]
|
||||
// p = findParameter(event->param_id);
|
||||
//
|
||||
// where findParameter() is a function the plugin implements to map parameter ids to internal
|
||||
// objects.
|
||||
//
|
||||
// Important:
|
||||
// - The cookie is invalidated by a call to clap_host_params->rescan(CLAP_PARAM_RESCAN_ALL) or
|
||||
// when the plugin is destroyed.
|
||||
// - The host will either provide the cookie as issued or nullptr in events addressing
|
||||
// parameters.
|
||||
// - The plugin must gracefully handle the case of a cookie which is nullptr.
|
||||
// - Many plugins will process the parameter events more quickly if the host can provide the
|
||||
// cookie in a faster time than a hashmap lookup per param per event.
|
||||
void *cookie;
|
||||
|
||||
// The display name. eg: "Volume". This does not need to be unique. Do not include the module
|
||||
// text in this. The host should concatenate/format the module + name in the case where showing
|
||||
// the name alone would be too vague.
|
||||
char name[CLAP_NAME_SIZE];
|
||||
|
||||
// The module path containing the param, eg: "Oscillators/Wavetable 1".
|
||||
// '/' will be used as a separator to show a tree-like structure.
|
||||
char module[CLAP_PATH_SIZE];
|
||||
|
||||
double min_value; // Minimum plain value. Must be finite (`std::isfinite` true)
|
||||
double max_value; // Maximum plain value. Must be finite
|
||||
double default_value; // Default plain value. Must be in [min, max] range.
|
||||
} clap_param_info_t;
|
||||
|
||||
typedef struct clap_plugin_params {
|
||||
// Returns the number of parameters.
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin);
|
||||
|
||||
// Copies the parameter's info to param_info.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin,
|
||||
uint32_t param_index,
|
||||
clap_param_info_t *param_info);
|
||||
|
||||
// Writes the parameter's current value to out_value.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get_value)(const clap_plugin_t *plugin, clap_id param_id, double *out_value);
|
||||
|
||||
// Fills out_buffer with a null-terminated UTF-8 string that represents the parameter at the
|
||||
// given 'value' argument. eg: "2.3 kHz". The host should always use this to format parameter
|
||||
// values before displaying it to the user.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *value_to_text)(const clap_plugin_t *plugin,
|
||||
clap_id param_id,
|
||||
double value,
|
||||
char *out_buffer,
|
||||
uint32_t out_buffer_capacity);
|
||||
|
||||
// Converts the null-terminated UTF-8 param_value_text into a double and writes it to out_value.
|
||||
// The host can use this to convert user input into a parameter value.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *text_to_value)(const clap_plugin_t *plugin,
|
||||
clap_id param_id,
|
||||
const char *param_value_text,
|
||||
double *out_value);
|
||||
|
||||
// Flushes a set of parameter changes.
|
||||
// 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-directional), 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_params_t;
|
||||
|
||||
enum {
|
||||
// The parameter values did change, eg. after loading a preset.
|
||||
// The host will scan all the parameters value.
|
||||
// The host will not record those changes as automation points.
|
||||
// New values takes effect immediately.
|
||||
CLAP_PARAM_RESCAN_VALUES = 1 << 0,
|
||||
|
||||
// The value to text conversion changed, and the text needs to be rendered again.
|
||||
CLAP_PARAM_RESCAN_TEXT = 1 << 1,
|
||||
|
||||
// The parameter info did change, use this flag for:
|
||||
// - name change
|
||||
// - module change
|
||||
// - is_periodic (flag)
|
||||
// - is_hidden (flag)
|
||||
// New info takes effect immediately.
|
||||
CLAP_PARAM_RESCAN_INFO = 1 << 2,
|
||||
|
||||
// Invalidates everything the host knows about parameters.
|
||||
// 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 parameters were added or removed.
|
||||
// - some parameters had critical changes:
|
||||
// - is_per_note (flag)
|
||||
// - is_per_key (flag)
|
||||
// - is_per_channel (flag)
|
||||
// - is_per_port (flag)
|
||||
// - is_readonly (flag)
|
||||
// - is_bypass (flag)
|
||||
// - is_stepped (flag)
|
||||
// - is_modulatable (flag)
|
||||
// - min_value
|
||||
// - max_value
|
||||
// - cookie
|
||||
CLAP_PARAM_RESCAN_ALL = 1 << 3,
|
||||
};
|
||||
typedef uint32_t clap_param_rescan_flags;
|
||||
|
||||
enum {
|
||||
// Clears all possible references to a parameter
|
||||
CLAP_PARAM_CLEAR_ALL = 1 << 0,
|
||||
|
||||
// Clears all automations to a parameter
|
||||
CLAP_PARAM_CLEAR_AUTOMATIONS = 1 << 1,
|
||||
|
||||
// Clears all modulations to a parameter
|
||||
CLAP_PARAM_CLEAR_MODULATIONS = 1 << 2,
|
||||
};
|
||||
typedef uint32_t clap_param_clear_flags;
|
||||
|
||||
typedef struct clap_host_params {
|
||||
// Rescan the full list of parameters according to the flags.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *rescan)(const clap_host_t *host, clap_param_rescan_flags flags);
|
||||
|
||||
// Clears references to a parameter.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *clear)(const clap_host_t *host, clap_id param_id, clap_param_clear_flags flags);
|
||||
|
||||
// Request a parameter flush.
|
||||
//
|
||||
// The host will then schedule a call to either:
|
||||
// - clap_plugin.process()
|
||||
// - clap_plugin_params.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_params_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
49
tests/clap/ext/posix-fd-support.h
Normal file
49
tests/clap/ext/posix-fd-support.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
// This extension let your plugin hook itself into the host select/poll/epoll/kqueue reactor.
|
||||
// This is useful to handle asynchronous I/O on the main thread.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_POSIX_FD_SUPPORT[] = "clap.posix-fd-support";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// IO events flags, they can be used to form a mask which describes:
|
||||
// - which events you are interested in (register_fd/modify_fd)
|
||||
// - which events happened (on_fd)
|
||||
CLAP_POSIX_FD_READ = 1 << 0,
|
||||
CLAP_POSIX_FD_WRITE = 1 << 1,
|
||||
CLAP_POSIX_FD_ERROR = 1 << 2,
|
||||
};
|
||||
typedef uint32_t clap_posix_fd_flags_t;
|
||||
|
||||
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 writing.
|
||||
//
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *on_fd)(const clap_plugin_t *plugin, int fd, clap_posix_fd_flags_t flags);
|
||||
} clap_plugin_posix_fd_support_t;
|
||||
|
||||
typedef struct clap_host_posix_fd_support {
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *register_fd)(const clap_host_t *host, int fd, clap_posix_fd_flags_t flags);
|
||||
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *modify_fd)(const clap_host_t *host, int fd, clap_posix_fd_flags_t flags);
|
||||
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *unregister_fd)(const clap_host_t *host, int fd);
|
||||
} clap_host_posix_fd_support_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
53
tests/clap/ext/preset-load.h
Normal file
53
tests/clap/ext/preset-load.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_PRESET_LOAD[] = "clap.preset-load/2";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_PRESET_LOAD_COMPAT[] = "clap.preset-load.draft/2";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_preset_load {
|
||||
// Loads a preset in the plugin native preset file format from a location.
|
||||
// The preset discovery provider defines the location and load_key to be passed to this function.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *from_location)(const clap_plugin_t *plugin,
|
||||
uint32_t location_kind,
|
||||
const char *location,
|
||||
const char *load_key);
|
||||
} clap_plugin_preset_load_t;
|
||||
|
||||
typedef struct clap_host_preset_load {
|
||||
// Called if clap_plugin_preset_load.load() failed.
|
||||
// os_error: the operating system error, if applicable. If not applicable set it to a non-error
|
||||
// value, eg: 0 on unix and Windows.
|
||||
//
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *on_error)(const clap_host_t *host,
|
||||
uint32_t location_kind,
|
||||
const char *location,
|
||||
const char *load_key,
|
||||
int32_t os_error,
|
||||
const char *msg);
|
||||
|
||||
// Informs the host that the following preset has been loaded.
|
||||
// This contributes to keep in sync the host preset browser and plugin preset browser.
|
||||
// If the preset was loaded from a container file, then the load_key must be set, otherwise it
|
||||
// must be null.
|
||||
//
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *loaded)(const clap_host_t *host,
|
||||
uint32_t location_kind,
|
||||
const char *location,
|
||||
const char *load_key);
|
||||
} clap_host_preset_load_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
83
tests/clap/ext/remote-controls.h
Normal file
83
tests/clap/ext/remote-controls.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
// This extension let the plugin provide a structured way of mapping parameters to an hardware
|
||||
// controller.
|
||||
//
|
||||
// This is done by providing a set of remote control pages organized by section.
|
||||
// A page contains up to 8 controls, which references parameters using param_id.
|
||||
//
|
||||
// |`- [section:main]
|
||||
// | `- [name:main] performance controls
|
||||
// |`- [section:osc]
|
||||
// | |`- [name:osc1] osc1 page
|
||||
// | |`- [name:osc2] osc2 page
|
||||
// | |`- [name:osc-sync] osc sync page
|
||||
// | `- [name:osc-noise] osc noise page
|
||||
// |`- [section:filter]
|
||||
// | |`- [name:flt1] filter 1 page
|
||||
// | `- [name:flt2] filter 2 page
|
||||
// |`- [section:env]
|
||||
// | |`- [name:env1] env1 page
|
||||
// | `- [name:env2] env2 page
|
||||
// |`- [section:lfo]
|
||||
// | |`- [name:lfo1] env1 page
|
||||
// | `- [name:lfo2] env2 page
|
||||
// `- etc...
|
||||
//
|
||||
// One possible workflow is to have a set of buttons, which correspond to a section.
|
||||
// Pressing that button once gets you to the first page of the section.
|
||||
// Press it again to cycle through the section's pages.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_REMOTE_CONTROLS[] = "clap.remote-controls/2";
|
||||
|
||||
// The latest draft is 100% compatible
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_REMOTE_CONTROLS_COMPAT[] = "clap.remote-controls.draft/2";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum { CLAP_REMOTE_CONTROLS_COUNT = 8 };
|
||||
|
||||
typedef struct clap_remote_controls_page {
|
||||
char section_name[CLAP_NAME_SIZE];
|
||||
clap_id page_id;
|
||||
char page_name[CLAP_NAME_SIZE];
|
||||
clap_id param_ids[CLAP_REMOTE_CONTROLS_COUNT];
|
||||
|
||||
// This is used to separate device pages versus preset pages.
|
||||
// If true, then this page is specific to this preset.
|
||||
bool is_for_preset;
|
||||
} clap_remote_controls_page_t;
|
||||
|
||||
typedef struct clap_plugin_remote_controls {
|
||||
// Returns the number of pages.
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin);
|
||||
|
||||
// Get a page by index.
|
||||
// Returns true on success and stores the result into page.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin,
|
||||
uint32_t page_index,
|
||||
clap_remote_controls_page_t *page);
|
||||
} clap_plugin_remote_controls_t;
|
||||
|
||||
typedef struct clap_host_remote_controls {
|
||||
// Informs the host that the remote controls have changed.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
|
||||
// Suggest a page to the host because it corresponds to what the user is currently editing in the
|
||||
// plugin's GUI.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *suggest_page)(const clap_host_t *host, clap_id page_id);
|
||||
} clap_host_remote_controls_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
39
tests/clap/ext/render.h
Normal file
39
tests/clap/ext/render.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_RENDER[] = "clap.render";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Default setting, for "realtime" processing
|
||||
CLAP_RENDER_REALTIME = 0,
|
||||
|
||||
// For processing without realtime pressure
|
||||
// The plugin may use more expensive algorithms for higher sound quality.
|
||||
CLAP_RENDER_OFFLINE = 1,
|
||||
};
|
||||
typedef int32_t clap_plugin_render_mode;
|
||||
|
||||
// The render extension is used to let the plugin know if it has "realtime"
|
||||
// pressure to process.
|
||||
//
|
||||
// If this information does not influence your rendering code, then don't
|
||||
// implement this extension.
|
||||
typedef struct clap_plugin_render {
|
||||
// Returns true if the plugin has a hard requirement to process in real-time.
|
||||
// This is especially useful for plugin acting as a proxy to an hardware device.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *has_hard_realtime_requirement)(const clap_plugin_t *plugin);
|
||||
|
||||
// Returns true if the rendering mode could be applied.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *set)(const clap_plugin_t *plugin, clap_plugin_render_mode mode);
|
||||
} clap_plugin_render_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
72
tests/clap/ext/state-context.h
Normal file
72
tests/clap/ext/state-context.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../stream.h"
|
||||
|
||||
/// @page state-context extension
|
||||
/// @brief extended state handling
|
||||
///
|
||||
/// This extension lets the host save and load the plugin state with different semantics depending
|
||||
/// on the context.
|
||||
///
|
||||
/// Briefly, when loading a preset or duplicating a device, the plugin may want to partially load
|
||||
/// the state and initialize certain things differently, like handling limited resources or fixed
|
||||
/// connections to external hardware resources.
|
||||
///
|
||||
/// Save and Load operations may have a different context.
|
||||
/// All three operations should be equivalent:
|
||||
/// 1. clap_plugin_state_context.load(clap_plugin_state.save(), CLAP_STATE_CONTEXT_FOR_PRESET)
|
||||
/// 2. clap_plugin_state.load(clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET))
|
||||
/// 3. clap_plugin_state_context.load(
|
||||
/// clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET),
|
||||
/// CLAP_STATE_CONTEXT_FOR_PRESET)
|
||||
///
|
||||
/// If in doubt, fallback to clap_plugin_state.
|
||||
///
|
||||
/// If the plugin implements CLAP_EXT_STATE_CONTEXT then it is mandatory to also implement
|
||||
/// CLAP_EXT_STATE.
|
||||
///
|
||||
/// It is unspecified which context is equivalent to clap_plugin_state.{save,load}()
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context/2";
|
||||
|
||||
enum clap_plugin_state_context_type {
|
||||
// suitable for storing and loading a state as a preset
|
||||
CLAP_STATE_CONTEXT_FOR_PRESET = 1,
|
||||
|
||||
// suitable for duplicating a plugin instance
|
||||
CLAP_STATE_CONTEXT_FOR_DUPLICATE = 2,
|
||||
|
||||
// suitable for storing and loading a state within a project/song
|
||||
CLAP_STATE_CONTEXT_FOR_PROJECT = 3,
|
||||
};
|
||||
|
||||
typedef struct clap_plugin_state_context {
|
||||
// Saves the plugin state into stream, according to context_type.
|
||||
// Returns true if the state was correctly saved.
|
||||
//
|
||||
// Note that the result may be loaded by both clap_plugin_state.load() and
|
||||
// clap_plugin_state_context.load().
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *save)(const clap_plugin_t *plugin,
|
||||
const clap_ostream_t *stream,
|
||||
uint32_t context_type);
|
||||
|
||||
// Loads the plugin state from stream, according to context_type.
|
||||
// Returns true if the state was correctly restored.
|
||||
//
|
||||
// Note that the state may have been saved by clap_plugin_state.save() or
|
||||
// clap_plugin_state_context.save() with a different context_type.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *load)(const clap_plugin_t *plugin,
|
||||
const clap_istream_t *stream,
|
||||
uint32_t context_type);
|
||||
} clap_plugin_state_context_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
45
tests/clap/ext/state.h
Normal file
45
tests/clap/ext/state.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../stream.h"
|
||||
|
||||
/// @page State
|
||||
/// @brief state management
|
||||
///
|
||||
/// Plugins can implement this extension to save and restore both parameter
|
||||
/// values and non-parameter state. This is used to persist a plugin's state
|
||||
/// between project reloads, when duplicating and copying plugin instances, and
|
||||
/// for host-side preset management.
|
||||
///
|
||||
/// If you need to know if the save/load operation is meant for duplicating a plugin
|
||||
/// instance, for saving/loading a plugin preset or while saving/loading the project
|
||||
/// then consider implementing CLAP_EXT_STATE_CONTEXT in addition to CLAP_EXT_STATE.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_STATE[] = "clap.state";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_state {
|
||||
// Saves the plugin state into stream.
|
||||
// Returns true if the state was correctly saved.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *save)(const clap_plugin_t *plugin, const clap_ostream_t *stream);
|
||||
|
||||
// Loads the plugin state from stream.
|
||||
// Returns true if the state was correctly restored.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *load)(const clap_plugin_t *plugin, const clap_istream_t *stream);
|
||||
} clap_plugin_state_t;
|
||||
|
||||
typedef struct clap_host_state {
|
||||
// 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.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *mark_dirty)(const clap_host_t *host);
|
||||
} clap_host_state_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
89
tests/clap/ext/surround.h
Normal file
89
tests/clap/ext/surround.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
// This extension can be used to specify the channel mapping used by the plugin.
|
||||
//
|
||||
// To have consistent surround features across all the plugin instances,
|
||||
// here is the proposed workflow:
|
||||
// 1. the plugin queries the host preferred channel mapping and
|
||||
// adjusts its configuration to match it.
|
||||
// 2. the host checks how the plugin is effectively configured and honors it.
|
||||
//
|
||||
// If the host decides to change the project's surround setup:
|
||||
// 1. deactivate the plugin
|
||||
// 2. host calls clap_plugin_surround->changed()
|
||||
// 3. plugin calls clap_host_surround->get_preferred_channel_map()
|
||||
// 4. plugin eventually calls clap_host_surround->changed()
|
||||
// 5. host calls clap_plugin_surround->get_channel_map() if changed
|
||||
// 6. host activates the plugin and can start processing audio
|
||||
//
|
||||
// If the plugin wants to change its surround setup:
|
||||
// 1. call host->request_restart() if the plugin is active
|
||||
// 2. once deactivated plugin calls clap_host_surround->changed()
|
||||
// 3. host calls clap_plugin_surround->get_channel_map()
|
||||
// 4. host activates the plugin and can start processing audio
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND[] = "clap.surround/4";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND_COMPAT[] = "clap.surround.draft/4";
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_PORT_SURROUND[] = "surround";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CLAP_SURROUND_FL = 0, // Front Left
|
||||
CLAP_SURROUND_FR = 1, // Front Right
|
||||
CLAP_SURROUND_FC = 2, // Front Center
|
||||
CLAP_SURROUND_LFE = 3, // Low Frequency
|
||||
CLAP_SURROUND_BL = 4, // Back (Rear) Left
|
||||
CLAP_SURROUND_BR = 5, // Back (Rear) Right
|
||||
CLAP_SURROUND_FLC = 6, // Front Left of Center
|
||||
CLAP_SURROUND_FRC = 7, // Front Right of Center
|
||||
CLAP_SURROUND_BC = 8, // Back (Rear) Center
|
||||
CLAP_SURROUND_SL = 9, // Side Left
|
||||
CLAP_SURROUND_SR = 10, // Side Right
|
||||
CLAP_SURROUND_TC = 11, // Top (Height) Center
|
||||
CLAP_SURROUND_TFL = 12, // Top (Height) Front Left
|
||||
CLAP_SURROUND_TFC = 13, // Top (Height) Front Center
|
||||
CLAP_SURROUND_TFR = 14, // Top (Height) Front Right
|
||||
CLAP_SURROUND_TBL = 15, // Top (Height) Back (Rear) Left
|
||||
CLAP_SURROUND_TBC = 16, // Top (Height) Back (Rear) Center
|
||||
CLAP_SURROUND_TBR = 17, // Top (Height) Back (Rear) Right
|
||||
CLAP_SURROUND_TSL = 18, // Top (Height) Side Left
|
||||
CLAP_SURROUND_TSR = 19, // Top (Height) Side Right
|
||||
};
|
||||
|
||||
typedef struct clap_plugin_surround {
|
||||
// Checks if a given channel mask is supported.
|
||||
// The channel mask is a bitmask, for example:
|
||||
// (1 << CLAP_SURROUND_FL) | (1 << CLAP_SURROUND_FR) | ...
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *is_channel_mask_supported)(const clap_plugin_t *plugin, uint64_t channel_mask);
|
||||
|
||||
// Stores the surround identifier of each channel into the channel_map array.
|
||||
// Returns the number of elements stored in channel_map.
|
||||
// channel_map_capacity must be greater or equal to the channel count of the given port.
|
||||
// [main-thread]
|
||||
uint32_t(CLAP_ABI *get_channel_map)(const clap_plugin_t *plugin,
|
||||
bool is_input,
|
||||
uint32_t port_index,
|
||||
uint8_t *channel_map,
|
||||
uint32_t channel_map_capacity);
|
||||
} clap_plugin_surround_t;
|
||||
|
||||
typedef struct clap_host_surround {
|
||||
// Informs the host that the channel map has changed.
|
||||
// The channel map can only change when the plugin is de-activated.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
} clap_host_surround_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
26
tests/clap/ext/tail.h
Normal file
26
tests/clap/ext/tail.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TAIL[] = "clap.tail";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_tail {
|
||||
// Returns tail length in samples.
|
||||
// Any value greater or equal to INT32_MAX implies infinite tail.
|
||||
// [main-thread,audio-thread]
|
||||
uint32_t(CLAP_ABI *get)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_tail_t;
|
||||
|
||||
typedef struct clap_host_tail {
|
||||
// Tell the host that the tail has changed.
|
||||
// [audio-thread]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
} clap_host_tail_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
72
tests/clap/ext/thread-check.h
Normal file
72
tests/clap/ext/thread-check.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#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.
|
||||
/// This will be the same OS thread throughout the lifetime of the plug-in.
|
||||
/// On macOS and Windows, this must be the thread on which gui and timer events are received
|
||||
/// (i.e., the main thread of the program).
|
||||
/// It isn't a realtime thread, yet this thread needs to respond fast enough to allow responsive
|
||||
/// user interaction, so it is strongly recommended plugins run long,and expensive or blocking
|
||||
/// tasks such as preset indexing or asset loading in dedicated background threads started by the
|
||||
/// plugin.
|
||||
///
|
||||
/// audio-thread:
|
||||
/// This thread can be used for realtime audio processing. Its execution should be as
|
||||
/// deterministic as possible to meet the audio interface's deadline (can be <1ms). There are a
|
||||
/// known set of operations that should be avoided: malloc() and free(), contended locks and
|
||||
/// mutexes, I/O, waiting, and so forth.
|
||||
///
|
||||
/// The audio-thread is symbolic, there isn't one OS thread that remains the
|
||||
/// audio-thread for the plugin lifetime. A host is may opt to have a
|
||||
/// thread pool and the plugin.process() call may be scheduled on different OS threads over time.
|
||||
/// However, the host must guarantee that single plugin instance will not be two audio-threads
|
||||
/// at the same time.
|
||||
///
|
||||
/// 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 guarantee that only one OS
|
||||
/// thread is the audio-thread at a time in a plugin instance. The audio-thread can be seen as a
|
||||
/// concurrency guard for all functions marked with [audio-thread].
|
||||
///
|
||||
/// The real-time constraint on the [audio-thread] interacts closely with the render extension.
|
||||
/// If a plugin doesn't implement render, then that plugin must have all [audio-thread] functions
|
||||
/// meet the real time standard. If the plugin does implement render, and returns true when
|
||||
/// render mode is set to real-time or if the plugin advertises a hard realtime requirement, it
|
||||
/// must implement realtime constraints. Hosts also provide functions marked [audio-thread].
|
||||
/// These can be safely called by a plugin in the audio thread. Therefore hosts must either (1)
|
||||
/// implement those functions meeting the real-time constraints or (2) not process plugins which
|
||||
/// advertise a hard realtime constraint or don't implement the render extension. Hosts which
|
||||
/// provide [audio-thread] functions outside these conditions may experience inconsistent or
|
||||
/// inaccurate rendering.
|
||||
///
|
||||
/// Clap also tags some functions as [thread-safe]. Functions tagged as [thread-safe] can be called
|
||||
/// from any thread unless explicitly counter-indicated (for instance [thread-safe, !audio-thread])
|
||||
/// and may be called concurrently.
|
||||
|
||||
// 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
|
||||
66
tests/clap/ext/thread-pool.h
Normal file
66
tests/clap/ext/thread-pool.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
/// @page
|
||||
///
|
||||
/// This extension lets the plugin use the host's thread pool.
|
||||
///
|
||||
/// The plugin must provide @ref clap_plugin_thread_pool, and the host may provide @ref
|
||||
/// clap_host_thread_pool. If it doesn't, the plugin should process its data by its own means. In
|
||||
/// the worst case, a single threaded for-loop.
|
||||
///
|
||||
/// Simple example with N voices to process
|
||||
///
|
||||
/// @code
|
||||
/// void myplug_thread_pool_exec(const clap_plugin *plugin, uint32_t voice_index)
|
||||
/// {
|
||||
/// compute_voice(plugin, voice_index);
|
||||
/// }
|
||||
///
|
||||
/// void myplug_process(const clap_plugin *plugin, const clap_process *process)
|
||||
/// {
|
||||
/// ...
|
||||
/// bool didComputeVoices = false;
|
||||
/// if (host_thread_pool && host_thread_pool.exec)
|
||||
/// didComputeVoices = host_thread_pool.request_exec(host, plugin, N);
|
||||
///
|
||||
/// if (!didComputeVoices)
|
||||
/// for (uint32_t i = 0; i < N; ++i)
|
||||
/// myplug_thread_pool_exec(plugin, i);
|
||||
/// ...
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// Be aware that using a thread pool may break hard real-time rules due to the thread
|
||||
/// synchronization involved.
|
||||
///
|
||||
/// If the host knows that it is running under hard real-time pressure it may decide to not
|
||||
/// provide this interface.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_THREAD_POOL[] = "clap.thread-pool";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_thread_pool {
|
||||
// Called by the thread pool
|
||||
void(CLAP_ABI *exec)(const clap_plugin_t *plugin, uint32_t task_index);
|
||||
} clap_plugin_thread_pool_t;
|
||||
|
||||
typedef struct clap_host_thread_pool {
|
||||
// Schedule num_tasks jobs in the host thread pool.
|
||||
// It can't be called concurrently or from the thread pool.
|
||||
// Will block until all the tasks are processed.
|
||||
// This must be used exclusively for realtime processing within the process call.
|
||||
// Returns true if the host did execute all the tasks, false if it rejected the request.
|
||||
// The host should check that the plugin is within the process call, and if not, reject the exec
|
||||
// request.
|
||||
// [audio-thread]
|
||||
bool(CLAP_ABI *request_exec)(const clap_host_t *host, uint32_t num_tasks);
|
||||
} clap_host_thread_pool_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
31
tests/clap/ext/timer-support.h
Normal file
31
tests/clap/ext/timer-support.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TIMER_SUPPORT[] = "clap.timer-support";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_timer_support {
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *on_timer)(const clap_plugin_t *plugin, clap_id timer_id);
|
||||
} clap_plugin_timer_support_t;
|
||||
|
||||
typedef struct clap_host_timer_support {
|
||||
// Registers a periodic timer.
|
||||
// The host may adjust the period if it is under a certain threshold.
|
||||
// 30 Hz should be allowed.
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *register_timer)(const clap_host_t *host, uint32_t period_ms, clap_id *timer_id);
|
||||
|
||||
// Returns true on success.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *unregister_timer)(const clap_host_t *host, clap_id timer_id);
|
||||
} clap_host_timer_support_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
66
tests/clap/ext/track-info.h
Normal file
66
tests/clap/ext/track-info.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
#include "../color.h"
|
||||
#include "../string-sizes.h"
|
||||
|
||||
// This extension let the plugin query info about the track it's in.
|
||||
// It is useful when the plugin is created, to initialize some parameters (mix, dry, wet)
|
||||
// and pick a suitable configuration regarding audio port type and channel count.
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO[] = "clap.track-info/1";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_TRACK_INFO_COMPAT[] = "clap.track-info.draft/1";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CLAP_TRACK_INFO_HAS_TRACK_NAME = (1 << 0),
|
||||
CLAP_TRACK_INFO_HAS_TRACK_COLOR = (1 << 1),
|
||||
CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL = (1 << 2),
|
||||
|
||||
// This plugin is on a return track, initialize with wet 100%
|
||||
CLAP_TRACK_INFO_IS_FOR_RETURN_TRACK = (1 << 3),
|
||||
|
||||
// This plugin is on a bus track, initialize with appropriate settings for bus processing
|
||||
CLAP_TRACK_INFO_IS_FOR_BUS = (1 << 4),
|
||||
|
||||
// This plugin is on the master, initialize with appropriate settings for channel processing
|
||||
CLAP_TRACK_INFO_IS_FOR_MASTER = (1 << 5),
|
||||
};
|
||||
|
||||
typedef struct clap_track_info {
|
||||
uint64_t flags; // see the flags above
|
||||
|
||||
// track name, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_NAME
|
||||
char name[CLAP_NAME_SIZE];
|
||||
|
||||
// track color, available if flags contain CLAP_TRACK_INFO_HAS_TRACK_COLOR
|
||||
clap_color_t color;
|
||||
|
||||
// available if flags contain CLAP_TRACK_INFO_HAS_AUDIO_CHANNEL
|
||||
// see audio-ports.h, struct clap_audio_port_info to learn how to use channel count and port type
|
||||
int32_t audio_channel_count;
|
||||
const char *audio_port_type;
|
||||
} clap_track_info_t;
|
||||
|
||||
typedef struct clap_plugin_track_info {
|
||||
// Called when the info changes.
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *changed)(const clap_plugin_t *plugin);
|
||||
} clap_plugin_track_info_t;
|
||||
|
||||
typedef struct clap_host_track_info {
|
||||
// Get info about the track the plugin belongs to.
|
||||
// Returns true on success and stores the result into info.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *get)(const clap_host_t *host, clap_track_info_t *info);
|
||||
} clap_host_track_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
56
tests/clap/ext/voice-info.h
Normal file
56
tests/clap/ext/voice-info.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
// This extension indicates the number of voices the synthesizer has.
|
||||
// It is useful for the host when performing polyphonic modulations,
|
||||
// because the host needs its own voice management and should try to follow
|
||||
// what the plugin is doing:
|
||||
// - make the host's voice pool coherent with what the plugin has
|
||||
// - turn the host's voice management to mono when the plugin is mono
|
||||
|
||||
static CLAP_CONSTEXPR const char CLAP_EXT_VOICE_INFO[] = "clap.voice-info";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Allows the host to send overlapping NOTE_ON events.
|
||||
// The plugin will then rely upon the note_id to distinguish between them.
|
||||
CLAP_VOICE_INFO_SUPPORTS_OVERLAPPING_NOTES = 1 << 0,
|
||||
};
|
||||
|
||||
typedef struct clap_voice_info {
|
||||
// voice_count is the current number of voices that the patch can use
|
||||
// voice_capacity is the number of voices allocated voices
|
||||
// voice_count should not be confused with the number of active voices.
|
||||
//
|
||||
// 1 <= voice_count <= voice_capacity
|
||||
//
|
||||
// For example, a synth can have a capacity of 8 voices, but be configured
|
||||
// to only use 4 voices: {count: 4, capacity: 8}.
|
||||
//
|
||||
// If the voice_count is 1, then the synth is working in mono and the host
|
||||
// can decide to only use global modulation mapping.
|
||||
uint32_t voice_count;
|
||||
uint32_t voice_capacity;
|
||||
|
||||
uint64_t flags;
|
||||
} clap_voice_info_t;
|
||||
|
||||
typedef struct clap_plugin_voice_info {
|
||||
// gets the voice info, returns true on success
|
||||
// [main-thread && active]
|
||||
bool(CLAP_ABI *get)(const clap_plugin_t *plugin, clap_voice_info_t *info);
|
||||
} clap_plugin_voice_info_t;
|
||||
|
||||
typedef struct clap_host_voice_info {
|
||||
// informs the host that the voice info has changed
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *changed)(const clap_host_t *host);
|
||||
} clap_host_voice_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
47
tests/clap/factory/draft/plugin-invalidation.h
Normal file
47
tests/clap/factory/draft/plugin-invalidation.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../private/std.h"
|
||||
#include "../../private/macros.h"
|
||||
|
||||
// Use it to retrieve const clap_plugin_invalidation_factory_t* from
|
||||
// clap_plugin_entry.get_factory()
|
||||
static const CLAP_CONSTEXPR char CLAP_PLUGIN_INVALIDATION_FACTORY_ID[] =
|
||||
"clap.plugin-invalidation-factory/1";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_invalidation_source {
|
||||
// Directory containing the file(s) to scan, must be absolute
|
||||
const char *directory;
|
||||
|
||||
// globing pattern, in the form *.dll
|
||||
const char *filename_glob;
|
||||
|
||||
// should the directory be scanned recursively?
|
||||
bool recursive_scan;
|
||||
} clap_plugin_invalidation_source_t;
|
||||
|
||||
// Used to figure out when a plugin needs to be scanned again.
|
||||
// Imagine a situation with a single entry point: my-plugin.clap which then scans itself
|
||||
// a set of "sub-plugins". New plugin may be available even if my-plugin.clap file doesn't change.
|
||||
// This interfaces solves this issue and gives a way to the host to monitor additional files.
|
||||
typedef struct clap_plugin_invalidation_factory {
|
||||
// Get the number of invalidation source.
|
||||
uint32_t(CLAP_ABI *count)(const struct clap_plugin_invalidation_factory *factory);
|
||||
|
||||
// Get the invalidation source by its index.
|
||||
// [thread-safe]
|
||||
const clap_plugin_invalidation_source_t *(CLAP_ABI *get)(
|
||||
const struct clap_plugin_invalidation_factory *factory, uint32_t index);
|
||||
|
||||
// In case the host detected a invalidation event, it can call refresh() to let the
|
||||
// plugin_entry update the set of plugins available.
|
||||
// If the function returned false, then the plugin needs to be reloaded.
|
||||
bool(CLAP_ABI *refresh)(const struct clap_plugin_invalidation_factory *factory);
|
||||
} clap_plugin_invalidation_factory_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
99
tests/clap/factory/draft/plugin-state-converter.h
Normal file
99
tests/clap/factory/draft/plugin-state-converter.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../id.h"
|
||||
#include "../../universal-plugin-id.h"
|
||||
#include "../../stream.h"
|
||||
#include "../../version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_state_converter_descriptor {
|
||||
clap_version_t clap_version;
|
||||
|
||||
clap_universal_plugin_id_t src_plugin_id;
|
||||
clap_universal_plugin_id_t dst_plugin_id;
|
||||
|
||||
const char *id; // eg: "com.u-he.diva-converter", mandatory
|
||||
const char *name; // eg: "Diva Converter", mandatory
|
||||
const char *vendor; // eg: "u-he"
|
||||
const char *version; // eg: 1.1.5
|
||||
const char *description; // eg: "Official state converter for u-he Diva."
|
||||
} clap_plugin_state_converter_descriptor_t;
|
||||
|
||||
// This interface provides a mechanism for the host to convert a plugin state and its automation
|
||||
// points to a new plugin.
|
||||
//
|
||||
// This is useful to convert from one plugin ABI to another one.
|
||||
// This is also useful to offer an upgrade path: from EQ version 1 to EQ version 2.
|
||||
// This can also be used to convert the state of a plugin that isn't maintained anymore into
|
||||
// another plugin that would be similar.
|
||||
typedef struct clap_plugin_state_converter {
|
||||
const clap_plugin_state_converter_descriptor_t *desc;
|
||||
|
||||
void *converter_data;
|
||||
|
||||
// Destroy the converter.
|
||||
void (*destroy)(struct clap_plugin_state_converter *converter);
|
||||
|
||||
// Converts the input state to a state usable by the destination plugin.
|
||||
//
|
||||
// error_buffer is a place holder of error_buffer_size bytes for storing a null-terminated
|
||||
// error message in case of failure, which can be displayed to the user.
|
||||
//
|
||||
// Returns true on success.
|
||||
// [thread-safe]
|
||||
bool (*convert_state)(struct clap_plugin_state_converter *converter,
|
||||
const clap_istream_t *src,
|
||||
const clap_ostream_t *dst,
|
||||
char *error_buffer,
|
||||
size_t error_buffer_size);
|
||||
|
||||
// Converts a normalized value.
|
||||
// Returns true on success.
|
||||
// [thread-safe]
|
||||
bool (*convert_normalized_value)(struct clap_plugin_state_converter *converter,
|
||||
clap_id src_param_id,
|
||||
double src_normalized_value,
|
||||
clap_id *dst_param_id,
|
||||
double *dst_normalized_value);
|
||||
|
||||
// Converts a plain value.
|
||||
// Returns true on success.
|
||||
// [thread-safe]
|
||||
bool (*convert_plain_value)(struct clap_plugin_state_converter *converter,
|
||||
clap_id src_param_id,
|
||||
double src_plain_value,
|
||||
clap_id *dst_param_id,
|
||||
double *dst_plain_value);
|
||||
} clap_plugin_state_converter_t;
|
||||
|
||||
// Factory identifier
|
||||
static CLAP_CONSTEXPR const char CLAP_PLUGIN_STATE_CONVERTER_FACTORY_ID[] =
|
||||
"clap.plugin-state-converter-factory/1";
|
||||
|
||||
// List all the plugin state converters available in the current DSO.
|
||||
typedef struct clap_plugin_state_converter_factory {
|
||||
// Get the number of converters.
|
||||
// [thread-safe]
|
||||
uint32_t (*count)(const struct clap_plugin_state_converter_factory *factory);
|
||||
|
||||
// Retrieves a plugin state converter descriptor by its index.
|
||||
// Returns null in case of error.
|
||||
// The descriptor must not be freed.
|
||||
// [thread-safe]
|
||||
const clap_plugin_state_converter_descriptor_t *(*get_descriptor)(
|
||||
const struct clap_plugin_state_converter_factory *factory, uint32_t index);
|
||||
|
||||
// Create a plugin state converter by its converter_id.
|
||||
// The returned pointer must be freed by calling converter->destroy(converter);
|
||||
// Returns null in case of error.
|
||||
// [thread-safe]
|
||||
clap_plugin_state_converter_t *(*create)(
|
||||
const struct clap_plugin_state_converter_factory *factory, const char *converter_id);
|
||||
} clap_plugin_state_converter_factory_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
42
tests/clap/factory/plugin-factory.h
Normal file
42
tests/clap/factory/plugin-factory.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "../plugin.h"
|
||||
|
||||
// Use it to retrieve const clap_plugin_factory_t* from
|
||||
// clap_plugin_entry.get_factory()
|
||||
static const CLAP_CONSTEXPR char CLAP_PLUGIN_FACTORY_ID[] = "clap.plugin-factory";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Every method must be thread-safe.
|
||||
// It is very important to be able to scan the plugin as quickly as possible.
|
||||
//
|
||||
// The host may use clap_plugin_invalidation_factory to detect filesystem changes
|
||||
// which may change the factory's content.
|
||||
typedef struct clap_plugin_factory {
|
||||
// Get the number of plugins available.
|
||||
// [thread-safe]
|
||||
uint32_t(CLAP_ABI *get_plugin_count)(const struct clap_plugin_factory *factory);
|
||||
|
||||
// Retrieves a plugin descriptor by its index.
|
||||
// Returns null in case of error.
|
||||
// The descriptor must not be freed.
|
||||
// [thread-safe]
|
||||
const clap_plugin_descriptor_t *(CLAP_ABI *get_plugin_descriptor)(
|
||||
const struct clap_plugin_factory *factory, uint32_t index);
|
||||
|
||||
// Create a clap_plugin by its plugin_id.
|
||||
// The returned pointer must be freed by calling plugin->destroy(plugin);
|
||||
// The plugin is not allowed to use the host callbacks in the create method.
|
||||
// Returns null in case of error.
|
||||
// [thread-safe]
|
||||
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;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
313
tests/clap/factory/preset-discovery.h
Normal file
313
tests/clap/factory/preset-discovery.h
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
Preset Discovery API.
|
||||
|
||||
Preset Discovery enables a plug-in host to identify where presets are found, what
|
||||
extensions they have, which plug-ins they apply to, and other metadata associated with the
|
||||
presets so that they can be indexed and searched for quickly within the plug-in host's browser.
|
||||
|
||||
This has a number of advantages for the user:
|
||||
- it allows them to browse for presets from one central location in a consistent way
|
||||
- the user can browse for presets without having to commit to a particular plug-in first
|
||||
|
||||
The API works as follow to index presets and presets metadata:
|
||||
1. clap_plugin_entry.get_factory(CLAP_PRESET_DISCOVERY_FACTORY_ID)
|
||||
2. clap_preset_discovery_factory_t.create(...)
|
||||
3. clap_preset_discovery_provider.init() (only necessary the first time, declarations
|
||||
can be cached)
|
||||
`-> clap_preset_discovery_indexer.declare_filetype()
|
||||
`-> clap_preset_discovery_indexer.declare_location()
|
||||
`-> clap_preset_discovery_indexer.declare_soundpack() (optional)
|
||||
`-> clap_preset_discovery_indexer.set_invalidation_watch_file() (optional)
|
||||
4. crawl the given locations and monitor file system changes
|
||||
`-> clap_preset_discovery_indexer.get_metadata() for each presets files
|
||||
|
||||
Then to load a preset, use ext/draft/preset-load.h.
|
||||
TODO: create a dedicated repo for other plugin abi preset-load extension.
|
||||
|
||||
The design of this API deliberately does not define a fixed set tags or categories. It is the
|
||||
plug-in host's job to try to intelligently map the raw list of features that are found for a
|
||||
preset and to process this list to generate something that makes sense for the host's tagging and
|
||||
categorization system. The reason for this is to reduce the work for a plug-in developer to add
|
||||
Preset Discovery support for their existing preset file format and not have to be concerned with
|
||||
all the different hosts and how they want to receive the metadata.
|
||||
|
||||
VERY IMPORTANT:
|
||||
- the whole indexing process has to be **fast**
|
||||
- clap_preset_provider->get_metadata() has to be fast and avoid unnecessary operations
|
||||
- the whole indexing process must not be interactive
|
||||
- don't show dialogs, windows, ...
|
||||
- don't ask for user input
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../private/std.h"
|
||||
#include "../private/macros.h"
|
||||
#include "../timestamp.h"
|
||||
#include "../version.h"
|
||||
#include "../universal-plugin-id.h"
|
||||
|
||||
// Use it to retrieve const clap_preset_discovery_factory_t* from
|
||||
// clap_plugin_entry.get_factory()
|
||||
static const CLAP_CONSTEXPR char CLAP_PRESET_DISCOVERY_FACTORY_ID[] =
|
||||
"clap.preset-discovery-factory/2";
|
||||
|
||||
// The latest draft is 100% compatible.
|
||||
// This compat ID may be removed in 2026.
|
||||
static const CLAP_CONSTEXPR char CLAP_PRESET_DISCOVERY_FACTORY_ID_COMPAT[] =
|
||||
"clap.preset-discovery-factory/draft-2";
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum clap_preset_discovery_location_kind {
|
||||
// The preset are located in a file on the OS filesystem.
|
||||
// The location is then a path which works with the OS file system functions (open, stat, ...)
|
||||
// So both '/' and '\' shall work on Windows as a separator.
|
||||
CLAP_PRESET_DISCOVERY_LOCATION_FILE = 0,
|
||||
|
||||
// The preset is bundled within the plugin DSO itself.
|
||||
// The location must then be null, as the preset are within the plugin itself and then the plugin
|
||||
// will act as a preset container.
|
||||
CLAP_PRESET_DISCOVERY_LOCATION_PLUGIN = 1,
|
||||
};
|
||||
|
||||
enum clap_preset_discovery_flags {
|
||||
// This is for factory or sound-pack presets.
|
||||
CLAP_PRESET_DISCOVERY_IS_FACTORY_CONTENT = 1 << 0,
|
||||
|
||||
// This is for user presets.
|
||||
CLAP_PRESET_DISCOVERY_IS_USER_CONTENT = 1 << 1,
|
||||
|
||||
// This location is meant for demo presets, those are preset which may trigger
|
||||
// some limitation in the plugin because they require additional features which the user
|
||||
// needs to purchase or the content itself needs to be bought and is only available in
|
||||
// demo mode.
|
||||
CLAP_PRESET_DISCOVERY_IS_DEMO_CONTENT = 1 << 2,
|
||||
|
||||
// This preset is a user's favorite
|
||||
CLAP_PRESET_DISCOVERY_IS_FAVORITE = 1 << 3,
|
||||
};
|
||||
|
||||
// Receiver that receives the metadata for a single preset file.
|
||||
// The host would define the various callbacks in this interface and the preset parser function
|
||||
// would then call them.
|
||||
//
|
||||
// This interface isn't thread-safe.
|
||||
typedef struct clap_preset_discovery_metadata_receiver {
|
||||
void *receiver_data; // reserved pointer for the metadata receiver
|
||||
|
||||
// If there is an error reading metadata from a file this should be called with an error
|
||||
// message.
|
||||
// os_error: the operating system error, if applicable. If not applicable set it to a non-error
|
||||
// value, eg: 0 on unix and Windows.
|
||||
void(CLAP_ABI *on_error)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
int32_t os_error,
|
||||
const char *error_message);
|
||||
|
||||
// This must be called for every preset in the file and before any preset metadata is
|
||||
// sent with the calls below.
|
||||
//
|
||||
// If the preset file is a preset container then name and load_key are mandatory, otherwise
|
||||
// they are optional.
|
||||
//
|
||||
// The load_key is a machine friendly string used to load the preset inside the container via a
|
||||
// the preset-load plug-in extension. The load_key can also just be the subpath if that's what
|
||||
// the plugin wants but it could also be some other unique id like a database primary key or a
|
||||
// binary offset. It's use is entirely up to the plug-in.
|
||||
//
|
||||
// If the function returns false, then the provider must stop calling back into the receiver.
|
||||
bool(CLAP_ABI *begin_preset)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const char *name,
|
||||
const char *load_key);
|
||||
|
||||
// Adds a plug-in id that this preset can be used with.
|
||||
void(CLAP_ABI *add_plugin_id)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const clap_universal_plugin_id_t *plugin_id);
|
||||
|
||||
// Sets the sound pack to which the preset belongs to.
|
||||
void(CLAP_ABI *set_soundpack_id)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const char *soundpack_id);
|
||||
|
||||
// Sets the flags, see clap_preset_discovery_flags.
|
||||
// If unset, they are then inherited from the location.
|
||||
void(CLAP_ABI *set_flags)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
uint32_t flags);
|
||||
|
||||
// Adds a creator name for the preset.
|
||||
void(CLAP_ABI *add_creator)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const char *creator);
|
||||
|
||||
// Sets a description of the preset.
|
||||
void(CLAP_ABI *set_description)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const char *description);
|
||||
|
||||
// Sets the creation time and last modification time of the preset.
|
||||
// If one of the times isn't known, set it to CLAP_TIMESTAMP_UNKNOWN.
|
||||
// If this function is not called, then the indexer may look at the file's creation and
|
||||
// modification time.
|
||||
void(CLAP_ABI *set_timestamps)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
clap_timestamp creation_time,
|
||||
clap_timestamp modification_time);
|
||||
|
||||
// Adds a feature to the preset.
|
||||
//
|
||||
// The feature string is arbitrary, it is the indexer's job to understand it and remap it to its
|
||||
// internal categorization and tagging system.
|
||||
//
|
||||
// However, the strings from plugin-features.h should be understood by the indexer and one of the
|
||||
// plugin category could be provided to determine if the preset will result into an audio-effect,
|
||||
// instrument, ...
|
||||
//
|
||||
// Examples:
|
||||
// kick, drum, tom, snare, clap, cymbal, bass, lead, metalic, hardsync, crossmod, acid,
|
||||
// distorted, drone, pad, dirty, etc...
|
||||
void(CLAP_ABI *add_feature)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const char *feature);
|
||||
|
||||
// Adds extra information to the metadata.
|
||||
void(CLAP_ABI *add_extra_info)(const struct clap_preset_discovery_metadata_receiver *receiver,
|
||||
const char *key,
|
||||
const char *value);
|
||||
} clap_preset_discovery_metadata_receiver_t;
|
||||
|
||||
typedef struct clap_preset_discovery_filetype {
|
||||
const char *name;
|
||||
const char *description; // optional
|
||||
|
||||
// `.' isn't included in the string.
|
||||
// If empty or NULL then every file should be matched.
|
||||
const char *file_extension;
|
||||
} clap_preset_discovery_filetype_t;
|
||||
|
||||
// Defines a place in which to search for presets
|
||||
typedef struct clap_preset_discovery_location {
|
||||
uint32_t flags; // see enum clap_preset_discovery_flags
|
||||
const char *name; // name of this location
|
||||
uint32_t kind; // See clap_preset_discovery_location_kind
|
||||
|
||||
// Actual location in which to crawl presets.
|
||||
// For FILE kind, the location can be either a path to a directory or a file.
|
||||
// For PLUGIN kind, the location must be null.
|
||||
const char *location;
|
||||
} clap_preset_discovery_location_t;
|
||||
|
||||
// Describes an installed sound pack.
|
||||
typedef struct clap_preset_discovery_soundpack {
|
||||
uint32_t flags; // see enum clap_preset_discovery_flags
|
||||
const char *id; // sound pack identifier
|
||||
const char *name; // name of this sound pack
|
||||
const char *description; // optional, reasonably short description of the sound pack
|
||||
const char *homepage_url; // optional, url to the pack's homepage
|
||||
const char *vendor; // optional, sound pack's vendor
|
||||
const char *image_path; // optional, an image on disk
|
||||
clap_timestamp release_timestamp; // release date, CLAP_TIMESTAMP_UNKNOWN if unavailable
|
||||
} clap_preset_discovery_soundpack_t;
|
||||
|
||||
// Describes a preset provider
|
||||
typedef struct clap_preset_discovery_provider_descriptor {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
const char *id; // see plugin.h for advice on how to choose a good identifier
|
||||
const char *name; // eg: "Diva's preset provider"
|
||||
const char *vendor; // optional, eg: u-he
|
||||
} clap_preset_discovery_provider_descriptor_t;
|
||||
|
||||
// This interface isn't thread-safe.
|
||||
typedef struct clap_preset_discovery_provider {
|
||||
const clap_preset_discovery_provider_descriptor_t *desc;
|
||||
|
||||
void *provider_data; // reserved pointer for the provider
|
||||
|
||||
// Initialize the preset provider.
|
||||
// It should declare all its locations, filetypes and sound packs.
|
||||
// Returns false if initialization failed.
|
||||
bool(CLAP_ABI *init)(const struct clap_preset_discovery_provider *provider);
|
||||
|
||||
// Destroys the preset provider
|
||||
void(CLAP_ABI *destroy)(const struct clap_preset_discovery_provider *provider);
|
||||
|
||||
// reads metadata from the given file and passes them to the metadata receiver
|
||||
// Returns true on success.
|
||||
bool(CLAP_ABI *get_metadata)(const struct clap_preset_discovery_provider *provider,
|
||||
uint32_t location_kind,
|
||||
const char *location,
|
||||
const clap_preset_discovery_metadata_receiver_t *metadata_receiver);
|
||||
|
||||
// Query an extension.
|
||||
// The returned pointer is owned by the provider.
|
||||
// It is forbidden to call it before provider->init().
|
||||
// You can call it within provider->init() call, and after.
|
||||
const void *(CLAP_ABI *get_extension)(const struct clap_preset_discovery_provider *provider,
|
||||
const char *extension_id);
|
||||
} clap_preset_discovery_provider_t;
|
||||
|
||||
// This interface isn't thread-safe
|
||||
typedef struct clap_preset_discovery_indexer {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
const char *name; // eg: "Bitwig Studio"
|
||||
const char *vendor; // optional, eg: "Bitwig GmbH"
|
||||
const char *url; // optional, eg: "https://bitwig.com"
|
||||
const char *version; // optional, eg: "4.3", see plugin.h for advice on how to format the version
|
||||
|
||||
void *indexer_data; // reserved pointer for the indexer
|
||||
|
||||
// Declares a preset filetype.
|
||||
// Don't callback into the provider during this call.
|
||||
// Returns false if the filetype is invalid.
|
||||
bool(CLAP_ABI *declare_filetype)(const struct clap_preset_discovery_indexer *indexer,
|
||||
const clap_preset_discovery_filetype_t *filetype);
|
||||
|
||||
// Declares a preset location.
|
||||
// Don't callback into the provider during this call.
|
||||
// Returns false if the location is invalid.
|
||||
bool(CLAP_ABI *declare_location)(const struct clap_preset_discovery_indexer *indexer,
|
||||
const clap_preset_discovery_location_t *location);
|
||||
|
||||
// Declares a sound pack.
|
||||
// Don't callback into the provider during this call.
|
||||
// Returns false if the sound pack is invalid.
|
||||
bool(CLAP_ABI *declare_soundpack)(const struct clap_preset_discovery_indexer *indexer,
|
||||
const clap_preset_discovery_soundpack_t *soundpack);
|
||||
|
||||
// Query an extension.
|
||||
// The returned pointer is owned by the indexer.
|
||||
// It is forbidden to call it before provider->init().
|
||||
// You can call it within provider->init() call, and after.
|
||||
const void *(CLAP_ABI *get_extension)(const struct clap_preset_discovery_indexer *indexer,
|
||||
const char *extension_id);
|
||||
} clap_preset_discovery_indexer_t;
|
||||
|
||||
// Every methods in this factory must be thread-safe.
|
||||
// It is encouraged to perform preset indexing in background threads, maybe even in background
|
||||
// process.
|
||||
//
|
||||
// The host may use clap_plugin_invalidation_factory to detect filesystem changes
|
||||
// which may change the factory's content.
|
||||
typedef struct clap_preset_discovery_factory {
|
||||
// Get the number of preset providers available.
|
||||
// [thread-safe]
|
||||
uint32_t(CLAP_ABI *count)(const struct clap_preset_discovery_factory *factory);
|
||||
|
||||
// Retrieves a preset provider descriptor by its index.
|
||||
// Returns null in case of error.
|
||||
// The descriptor must not be freed.
|
||||
// [thread-safe]
|
||||
const clap_preset_discovery_provider_descriptor_t *(CLAP_ABI *get_descriptor)(
|
||||
const struct clap_preset_discovery_factory *factory, uint32_t index);
|
||||
|
||||
// Create a preset provider by its id.
|
||||
// The returned pointer must be freed by calling preset_provider->destroy(preset_provider);
|
||||
// The preset provider is not allowed to use the indexer callbacks in the create method.
|
||||
// It is forbidden to call back into the indexer before the indexer calls provider->init().
|
||||
// Returns null in case of error.
|
||||
// [thread-safe]
|
||||
const clap_preset_discovery_provider_t *(CLAP_ABI *create)(
|
||||
const struct clap_preset_discovery_factory *factory,
|
||||
const clap_preset_discovery_indexer_t *indexer,
|
||||
const char *provider_id);
|
||||
} clap_preset_discovery_factory_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
16
tests/clap/fixedpoint.h
Normal file
16
tests/clap/fixedpoint.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
/// We use fixed point representation of beat time and seconds time
|
||||
/// Usage:
|
||||
/// double x = ...; // in beats
|
||||
/// clap_beattime y = round(CLAP_BEATTIME_FACTOR * x);
|
||||
|
||||
// This will never change
|
||||
static const CLAP_CONSTEXPR int64_t CLAP_BEATTIME_FACTOR = 1LL << 31;
|
||||
static const CLAP_CONSTEXPR int64_t CLAP_SECTIME_FACTOR = 1LL << 31;
|
||||
|
||||
typedef int64_t clap_beattime;
|
||||
typedef int64_t clap_sectime;
|
||||
51
tests/clap/host.h
Normal file
51
tests/clap/host.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_host {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
|
||||
void *host_data; // reserved pointer for the host
|
||||
|
||||
// name and version are mandatory.
|
||||
const char *name; // eg: "Bitwig Studio"
|
||||
const char *vendor; // eg: "Bitwig GmbH"
|
||||
const char *url; // eg: "https://bitwig.com"
|
||||
const char *version; // eg: "4.3", see plugin.h for advice on how to format the version
|
||||
|
||||
// Query an extension.
|
||||
// The returned pointer is owned by the host.
|
||||
// It is forbidden to call it before plugin->init().
|
||||
// You can call it within plugin->init() call, and after.
|
||||
// [thread-safe]
|
||||
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.
|
||||
// The operation may be delayed by the host.
|
||||
// [thread-safe]
|
||||
void(CLAP_ABI *request_restart)(const struct clap_host *host);
|
||||
|
||||
// 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".
|
||||
// [thread-safe]
|
||||
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.
|
||||
// This callback should be called as soon as practicable, usually in the host application's next
|
||||
// available main thread time slice. Typically callbacks occur within 33ms / 30hz.
|
||||
// Despite this guidance, plugins should not make assumptions about the exactness of timing for
|
||||
// a main thread callback, but hosts should endeavour to be prompt. For example, in high load
|
||||
// situations the environment may starve the gui/main thread in favor of audio processing,
|
||||
// leading to substantially longer latencies for the callback than the indicative times given
|
||||
// here.
|
||||
// [thread-safe]
|
||||
void(CLAP_ABI *request_callback)(const struct clap_host *host);
|
||||
} clap_host_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
8
tests/clap/id.h
Normal file
8
tests/clap/id.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
typedef uint32_t clap_id;
|
||||
|
||||
static const CLAP_CONSTEXPR clap_id CLAP_INVALID_ID = UINT32_MAX;
|
||||
79
tests/clap/plugin-features.h
Normal file
79
tests/clap/plugin-features.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
|
||||
// This file provides a set of standard plugin features meant to be used
|
||||
// within clap_plugin_descriptor.features.
|
||||
//
|
||||
// For practical reasons we'll avoid spaces and use `-` instead to facilitate
|
||||
// scripts that generate the feature array.
|
||||
//
|
||||
// Non-standard features should be formatted as follow: "$namespace:$feature"
|
||||
|
||||
/////////////////////
|
||||
// Plugin category //
|
||||
/////////////////////
|
||||
|
||||
// Add this feature if your plugin can process note events and then produce audio
|
||||
#define CLAP_PLUGIN_FEATURE_INSTRUMENT "instrument"
|
||||
|
||||
// Add this feature if your plugin is an audio effect
|
||||
#define CLAP_PLUGIN_FEATURE_AUDIO_EFFECT "audio-effect"
|
||||
|
||||
// Add this feature if your plugin is a note effect or a note generator/sequencer
|
||||
#define CLAP_PLUGIN_FEATURE_NOTE_EFFECT "note-effect"
|
||||
|
||||
// Add this feature if your plugin converts audio to notes
|
||||
#define CLAP_PLUGIN_FEATURE_NOTE_DETECTOR "note-detector"
|
||||
|
||||
// Add this feature if your plugin is an analyzer
|
||||
#define CLAP_PLUGIN_FEATURE_ANALYZER "analyzer"
|
||||
|
||||
/////////////////////////
|
||||
// Plugin sub-category //
|
||||
/////////////////////////
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_SYNTHESIZER "synthesizer"
|
||||
#define CLAP_PLUGIN_FEATURE_SAMPLER "sampler"
|
||||
#define CLAP_PLUGIN_FEATURE_DRUM "drum" // For single drum
|
||||
#define CLAP_PLUGIN_FEATURE_DRUM_MACHINE "drum-machine"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_FILTER "filter"
|
||||
#define CLAP_PLUGIN_FEATURE_PHASER "phaser"
|
||||
#define CLAP_PLUGIN_FEATURE_EQUALIZER "equalizer"
|
||||
#define CLAP_PLUGIN_FEATURE_DEESSER "de-esser"
|
||||
#define CLAP_PLUGIN_FEATURE_PHASE_VOCODER "phase-vocoder"
|
||||
#define CLAP_PLUGIN_FEATURE_GRANULAR "granular"
|
||||
#define CLAP_PLUGIN_FEATURE_FREQUENCY_SHIFTER "frequency-shifter"
|
||||
#define CLAP_PLUGIN_FEATURE_PITCH_SHIFTER "pitch-shifter"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_DISTORTION "distortion"
|
||||
#define CLAP_PLUGIN_FEATURE_TRANSIENT_SHAPER "transient-shaper"
|
||||
#define CLAP_PLUGIN_FEATURE_COMPRESSOR "compressor"
|
||||
#define CLAP_PLUGIN_FEATURE_EXPANDER "expander"
|
||||
#define CLAP_PLUGIN_FEATURE_GATE "gate"
|
||||
#define CLAP_PLUGIN_FEATURE_LIMITER "limiter"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_FLANGER "flanger"
|
||||
#define CLAP_PLUGIN_FEATURE_CHORUS "chorus"
|
||||
#define CLAP_PLUGIN_FEATURE_DELAY "delay"
|
||||
#define CLAP_PLUGIN_FEATURE_REVERB "reverb"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_TREMOLO "tremolo"
|
||||
#define CLAP_PLUGIN_FEATURE_GLITCH "glitch"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_UTILITY "utility"
|
||||
#define CLAP_PLUGIN_FEATURE_PITCH_CORRECTION "pitch-correction"
|
||||
#define CLAP_PLUGIN_FEATURE_RESTORATION "restoration" // repair the sound
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_MULTI_EFFECTS "multi-effects"
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_MIXING "mixing"
|
||||
#define CLAP_PLUGIN_FEATURE_MASTERING "mastering"
|
||||
|
||||
////////////////////////
|
||||
// Audio Capabilities //
|
||||
////////////////////////
|
||||
|
||||
#define CLAP_PLUGIN_FEATURE_MONO "mono"
|
||||
#define CLAP_PLUGIN_FEATURE_STEREO "stereo"
|
||||
#define CLAP_PLUGIN_FEATURE_SURROUND "surround"
|
||||
#define CLAP_PLUGIN_FEATURE_AMBISONIC "ambisonic"
|
||||
114
tests/clap/plugin.h
Normal file
114
tests/clap/plugin.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/macros.h"
|
||||
#include "host.h"
|
||||
#include "process.h"
|
||||
#include "plugin-features.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_plugin_descriptor {
|
||||
clap_version_t clap_version; // initialized to CLAP_VERSION
|
||||
|
||||
// Mandatory fields must be set and must not be blank.
|
||||
// Otherwise the fields can be null or blank, though it is safer to make them blank.
|
||||
//
|
||||
// Some indications regarding id and version
|
||||
// - id is an arbitrary string which should be unique to your plugin,
|
||||
// we encourage you to use a reverse URI eg: "com.u-he.diva"
|
||||
// - version is an arbitrary string which describes a plugin,
|
||||
// it is useful for the host to understand and be able to compare two different
|
||||
// version strings, so here is a regex like expression which is likely to be
|
||||
// understood by most hosts: MAJOR(.MINOR(.REVISION)?)?( (Alpha|Beta) XREV)?
|
||||
const char *id; // eg: "com.u-he.diva", mandatory
|
||||
const char *name; // eg: "Diva", mandatory
|
||||
const char *vendor; // eg: "u-he"
|
||||
const char *url; // eg: "https://u-he.com/products/diva/"
|
||||
const char *manual_url; // eg: "https://dl.u-he.com/manuals/plugins/diva/Diva-user-guide.pdf"
|
||||
const char *support_url; // eg: "https://u-he.com/support/"
|
||||
const char *version; // eg: "1.4.4"
|
||||
const char *description; // eg: "The spirit of analogue"
|
||||
|
||||
// Arbitrary list of keywords.
|
||||
// They can be matched by the host indexer and used to classify the plugin.
|
||||
// The array of pointers must be null terminated.
|
||||
// For some standard features see plugin-features.h
|
||||
const char *const *features;
|
||||
} clap_plugin_descriptor_t;
|
||||
|
||||
typedef struct clap_plugin {
|
||||
const clap_plugin_descriptor_t *desc;
|
||||
|
||||
void *plugin_data; // reserved pointer for the plugin
|
||||
|
||||
// Must be called after creating the plugin.
|
||||
// If init returns false, the host must destroy the plugin instance.
|
||||
// If init returns true, then the plugin is initialized and in the deactivated state.
|
||||
// Unlike in `plugin-factory::create_plugin`, in init you have complete access to the host
|
||||
// and host extensions, so clap related setup activities should be done here rather than in
|
||||
// create_plugin.
|
||||
// [main-thread]
|
||||
bool(CLAP_ABI *init)(const struct clap_plugin *plugin);
|
||||
|
||||
// Free the plugin and its resources.
|
||||
// It is required to deactivate the plugin prior to this call.
|
||||
// [main-thread & !active]
|
||||
void(CLAP_ABI *destroy)(const struct clap_plugin *plugin);
|
||||
|
||||
// Activate and deactivate the plugin.
|
||||
// In this call the plugin may allocate memory and prepare everything needed for the process
|
||||
// call. The process's sample rate will be constant and process's frame count will included in
|
||||
// the [min, max] range, which is bounded by [1, INT32_MAX].
|
||||
// In this call the plugin may call host-provided methods marked [being-activated].
|
||||
// Once activated the latency and port configuration must remain constant, until deactivation.
|
||||
// Returns true on success.
|
||||
// [main-thread & !active]
|
||||
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]
|
||||
void(CLAP_ABI *deactivate)(const struct clap_plugin *plugin);
|
||||
|
||||
// Call start processing before processing.
|
||||
// Returns true on success.
|
||||
// [audio-thread & active & !processing]
|
||||
bool(CLAP_ABI *start_processing)(const struct clap_plugin *plugin);
|
||||
|
||||
// Call stop processing before sending the plugin to sleep.
|
||||
// [audio-thread & active & processing]
|
||||
void(CLAP_ABI *stop_processing)(const struct clap_plugin *plugin);
|
||||
|
||||
// - Clears all buffers, performs a full reset of the processing state (filters, oscillators,
|
||||
// envelopes, lfo, ...) and kills all voices.
|
||||
// - The parameter's value remain unchanged.
|
||||
// - clap_process.steady_time may jump backward.
|
||||
//
|
||||
// [audio-thread & active]
|
||||
void(CLAP_ABI *reset)(const struct clap_plugin *plugin);
|
||||
|
||||
// process audio, events, ...
|
||||
// All the pointers coming from clap_process_t and its nested attributes,
|
||||
// are valid until process() returns.
|
||||
// [audio-thread & active & processing]
|
||||
clap_process_status(CLAP_ABI *process)(const struct clap_plugin *plugin,
|
||||
const clap_process_t *process);
|
||||
|
||||
// Query an extension.
|
||||
// The returned pointer is owned by the plugin.
|
||||
// It is forbidden to call it before plugin->init().
|
||||
// You can call it within plugin->init() call, and after.
|
||||
// [thread-safe]
|
||||
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:
|
||||
// host->request_callback(host);
|
||||
// [main-thread]
|
||||
void(CLAP_ABI *on_main_thread)(const struct clap_plugin *plugin);
|
||||
} clap_plugin_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
50
tests/clap/private/macros.h
Normal file
50
tests/clap/private/macros.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
// Define CLAP_EXPORT
|
||||
#if !defined(CLAP_EXPORT)
|
||||
# if defined _WIN32 || defined __CYGWIN__
|
||||
# ifdef __GNUC__
|
||||
# define CLAP_EXPORT __attribute__((dllexport))
|
||||
# else
|
||||
# define CLAP_EXPORT __declspec(dllexport)
|
||||
# endif
|
||||
# else
|
||||
# if __GNUC__ >= 4 || defined(__clang__)
|
||||
# define CLAP_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
# define CLAP_EXPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(CLAP_ABI)
|
||||
# if defined _WIN32 || defined __CYGWIN__
|
||||
# define CLAP_ABI __cdecl
|
||||
# else
|
||||
# define CLAP_ABI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSVC_LANG)
|
||||
# define CLAP_CPLUSPLUS _MSVC_LANG
|
||||
#elif defined(__cplusplus)
|
||||
# define CLAP_CPLUSPLUS __cplusplus
|
||||
#endif
|
||||
|
||||
#if defined(CLAP_CPLUSPLUS) && CLAP_CPLUSPLUS >= 201103L
|
||||
# define CLAP_HAS_CXX11
|
||||
# define CLAP_CONSTEXPR constexpr
|
||||
#else
|
||||
# define CLAP_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#if defined(CLAP_CPLUSPLUS) && CLAP_CPLUSPLUS >= 201703L
|
||||
# define CLAP_HAS_CXX17
|
||||
# define CLAP_NODISCARD [[nodiscard]]
|
||||
#else
|
||||
# define CLAP_NODISCARD
|
||||
#endif
|
||||
|
||||
#if defined(CLAP_CPLUSPLUS) && CLAP_CPLUSPLUS >= 202002L
|
||||
# define CLAP_HAS_CXX20
|
||||
#endif
|
||||
16
tests/clap/private/std.h
Normal file
16
tests/clap/private/std.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
#ifdef CLAP_HAS_CXX11
|
||||
# include <cstdint>
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <cstddef>
|
||||
#else
|
||||
# include <stddef.h>
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
66
tests/clap/process.h
Normal file
66
tests/clap/process.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "events.h"
|
||||
#include "audio-buffer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// Processing failed. The output buffer must be discarded.
|
||||
CLAP_PROCESS_ERROR = 0,
|
||||
|
||||
// Processing succeeded, keep processing.
|
||||
CLAP_PROCESS_CONTINUE = 1,
|
||||
|
||||
// Processing succeeded, keep processing if the output is not quiet.
|
||||
CLAP_PROCESS_CONTINUE_IF_NOT_QUIET = 2,
|
||||
|
||||
// Rely upon the plugin's tail to determine if the plugin should continue to process.
|
||||
// see clap_plugin_tail
|
||||
CLAP_PROCESS_TAIL = 3,
|
||||
|
||||
// Processing succeeded, but no more processing is required,
|
||||
// until the next event or variation in audio input.
|
||||
CLAP_PROCESS_SLEEP = 4,
|
||||
};
|
||||
typedef int32_t clap_process_status;
|
||||
|
||||
typedef struct clap_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.
|
||||
int64_t steady_time;
|
||||
|
||||
// Number of frames to process
|
||||
uint32_t frames_count;
|
||||
|
||||
// time info at sample 0
|
||||
// If null, then this is a free running host, no transport events will be provided
|
||||
const clap_event_transport_t *transport;
|
||||
|
||||
// Audio buffers, they must have the same count as specified
|
||||
// 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;
|
||||
clap_audio_buffer_t *audio_outputs;
|
||||
uint32_t audio_inputs_count;
|
||||
uint32_t audio_outputs_count;
|
||||
|
||||
// The input event list can't be modified.
|
||||
// Input read-only event list. The host will deliver these sorted in sample order.
|
||||
const clap_input_events_t *in_events;
|
||||
|
||||
// Output event list. The plugin must insert events in sample sorted order when inserting events
|
||||
const clap_output_events_t *out_events;
|
||||
} clap_process_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
38
tests/clap/stream.h
Normal file
38
tests/clap/stream.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
/// @page Streams
|
||||
///
|
||||
/// ## Notes on using streams
|
||||
///
|
||||
/// When working with `clap_istream` and `clap_ostream` objects to load and save
|
||||
/// state, it is important to keep in mind that the host may limit the number of
|
||||
/// bytes that can be read or written at a time. The return values for the
|
||||
/// stream read and write functions indicate how many bytes were actually read
|
||||
/// or written. You need to use a loop to ensure that you read or write the
|
||||
/// entirety of your state. Don't forget to also consider the negative return
|
||||
/// values for the end of file and IO error codes.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_istream {
|
||||
void *ctx; // reserved pointer for the stream
|
||||
|
||||
// returns the number of bytes read; 0 indicates end of file and -1 a read error
|
||||
int64_t(CLAP_ABI *read)(const struct clap_istream *stream, void *buffer, uint64_t size);
|
||||
} clap_istream_t;
|
||||
|
||||
typedef struct clap_ostream {
|
||||
void *ctx; // reserved pointer for the stream
|
||||
|
||||
// returns the number of bytes written; -1 on write error
|
||||
int64_t(CLAP_ABI *write)(const struct clap_ostream *stream, const void *buffer, uint64_t size);
|
||||
} clap_ostream_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
21
tests/clap/string-sizes.h
Normal file
21
tests/clap/string-sizes.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
// String capacity for names that can be displayed to the user.
|
||||
CLAP_NAME_SIZE = 256,
|
||||
|
||||
// String capacity for describing a path, like a parameter in a module hierarchy or path within a
|
||||
// set of nested track groups.
|
||||
//
|
||||
// This is not suited for describing a file path on the disk, as NTFS allows up to 32K long
|
||||
// paths.
|
||||
CLAP_PATH_SIZE = 1024,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
11
tests/clap/timestamp.h
Normal file
11
tests/clap/timestamp.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/std.h"
|
||||
#include "private/macros.h"
|
||||
|
||||
// This type defines a timestamp: the number of seconds since UNIX EPOCH.
|
||||
// See C's time_t time(time_t *).
|
||||
typedef uint64_t clap_timestamp;
|
||||
|
||||
// Value for unknown timestamp.
|
||||
static const CLAP_CONSTEXPR clap_timestamp CLAP_TIMESTAMP_UNKNOWN = 0;
|
||||
26
tests/clap/universal-plugin-id.h
Normal file
26
tests/clap/universal-plugin-id.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
// Pair of plugin ABI and plugin identifier.
|
||||
//
|
||||
// If you want to represent other formats please send us an update to the comment with the
|
||||
// name of the abi and the representation of the id.
|
||||
typedef struct clap_universal_plugin_id {
|
||||
// The plugin ABI name, in lowercase and null-terminated.
|
||||
// eg: "clap", "vst3", "vst2", "au", ...
|
||||
const char *abi;
|
||||
|
||||
// The plugin ID, null-terminated and formatted as follows:
|
||||
//
|
||||
// CLAP: use the plugin id
|
||||
// eg: "com.u-he.diva"
|
||||
//
|
||||
// AU: format the string like "type:subt:manu"
|
||||
// eg: "aumu:SgXT:VmbA"
|
||||
//
|
||||
// VST2: print the id as a signed 32-bits integer
|
||||
// eg: "-4382976"
|
||||
//
|
||||
// VST3: print the id as a standard UUID
|
||||
// eg: "123e4567-e89b-12d3-a456-426614174000"
|
||||
const char *id;
|
||||
} clap_universal_plugin_id_t;
|
||||
42
tests/clap/version.h
Normal file
42
tests/clap/version.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "private/macros.h"
|
||||
#include "private/std.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct clap_version {
|
||||
// This is the major ABI and API design
|
||||
// Version 0.X.Y correspond to the development stage, API and ABI are not stable
|
||||
// Version 1.X.Y correspond to the release stage, API and ABI are stable
|
||||
uint32_t major;
|
||||
uint32_t minor;
|
||||
uint32_t revision;
|
||||
} clap_version_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CLAP_VERSION_MAJOR 1
|
||||
#define CLAP_VERSION_MINOR 2
|
||||
#define CLAP_VERSION_REVISION 6
|
||||
|
||||
#define CLAP_VERSION_INIT \
|
||||
{ (uint32_t)CLAP_VERSION_MAJOR, (uint32_t)CLAP_VERSION_MINOR, (uint32_t)CLAP_VERSION_REVISION }
|
||||
|
||||
#define CLAP_VERSION_LT(maj,min,rev) ((CLAP_VERSION_MAJOR < (maj)) || \
|
||||
((maj) == CLAP_VERSION_MAJOR && CLAP_VERSION_MINOR < (min)) || \
|
||||
((maj) == CLAP_VERSION_MAJOR && (min) == CLAP_VERSION_MINOR && CLAP_VERSION_REVISION < (rev)))
|
||||
#define CLAP_VERSION_EQ(maj,min,rev) (((maj) == CLAP_VERSION_MAJOR) && ((min) == CLAP_VERSION_MINOR) && ((rev) == CLAP_VERSION_REVISION))
|
||||
#define CLAP_VERSION_GE(maj,min,rev) (!CLAP_VERSION_LT(maj,min,rev))
|
||||
|
||||
static const CLAP_CONSTEXPR clap_version_t CLAP_VERSION = CLAP_VERSION_INIT;
|
||||
|
||||
CLAP_NODISCARD static inline CLAP_CONSTEXPR bool
|
||||
clap_version_is_compatible(const clap_version_t v) {
|
||||
// versions 0.x.y were used during development stage and aren't compatible
|
||||
return v.major >= 1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue