diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a133fa..c3d25b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Changed +* Use clap library from external package. + ## [0.2.0] - 2024-02-14 ### Added * Demonstration of plugin GUI using raw XCB calls. diff --git a/README.md b/README.md index c38e4f2..9afd26e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ -# vclap +# CLAP plugin in V Demonstration of a [CLAP](https://github.com/free-audio/clap) audio plugin in V. -Currently it does nothing besides being correctly built against official -CLAP headers and loading into a DAW without any errors. +Built on top of [clap](https://github.com/odiroot/clap-lib) library for V language. -**Note**: Only tested on Linux. +Current features: + +- Builds a spec-compliant CLAP plugin. +- Shows a barebones GUI based on XCB/X11 (no controls). +- Runs under Bitwig Studio on Linux. ## Quickstart @@ -14,11 +17,15 @@ On top of that you'd need: - GNU Make - GCC +- `libxcb` +- `libxmdcp` +- `libxau` Start with: ```sh git clone https://github.com/mo-foss/vclap.git cd vclap +v install make ``` diff --git a/include/clap/audio-buffer.h b/include/clap/audio-buffer.h deleted file mode 100644 index cd18f3a..0000000 --- a/include/clap/audio-buffer.h +++ /dev/null @@ -1,37 +0,0 @@ -#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 diff --git a/include/clap/clap.h b/include/clap/clap.h deleted file mode 100644 index e57dbf4..0000000 --- a/include/clap/clap.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * CLAP - CLever Audio Plugin - * ~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * Copyright (c) 2014...2022 Alexandre BIQUE - * - * 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/draft/plugin-invalidation.h" -#include "factory/draft/preset-discovery.h" - -#include "plugin.h" -#include "plugin-features.h" -#include "host.h" - -#include "ext/audio-ports-config.h" -#include "ext/audio-ports.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/params.h" -#include "ext/posix-fd-support.h" -#include "ext/render.h" -#include "ext/state.h" -#include "ext/tail.h" -#include "ext/thread-check.h" -#include "ext/thread-pool.h" -#include "ext/timer-support.h" -#include "ext/voice-info.h" - -#include "ext/draft/ambisonic.h" -#include "ext/draft/audio-ports-activation.h" -#include "ext/draft/context-menu.h" -#include "ext/draft/cv.h" -#include "ext/draft/midi-mappings.h" -#include "ext/draft/param-indication.h" -#include "ext/draft/preset-load.h" -#include "ext/draft/remote-controls.h" -#include "ext/draft/resource-directory.h" -#include "ext/draft/state-context.h" -#include "ext/draft/surround.h" -#include "ext/draft/track-info.h" -#include "ext/draft/triggers.h" -#include "ext/draft/tuning.h" -#include "ext/draft/configurable-audio-ports.h" -#include "ext/draft/extensible-audio-ports.h" diff --git a/include/clap/color.h b/include/clap/color.h deleted file mode 100644 index 3f64359..0000000 --- a/include/clap/color.h +++ /dev/null @@ -1,18 +0,0 @@ -#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; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/entry.h b/include/clap/entry.h deleted file mode 100644 index 36f91f8..0000000 --- a/include/clap/entry.h +++ /dev/null @@ -1,71 +0,0 @@ -#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`. -// -// Every method must be thread-safe. -typedef struct clap_plugin_entry { - clap_version_t clap_version; // initialized to CLAP_VERSION - - // This function must be called first, and can only be called once. - // - // 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 interface in this call. - // It is forbidden to perform user interaction in this call. - // - // If the initialization depends upon expensive computation, maybe try to do them ahead of time - // and cache the result. - // - // If init() returns false, then the host must not call deinit() nor any other clap - // related symbols from the DSO. - // - // plugin_path is the path to the DSO (Linux, Windows), or the bundle (macOS). - bool(CLAP_ABI *init)(const char *plugin_path); - - // No more calls into the DSO must be made after calling 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. - const void *(CLAP_ABI *get_factory)(const char *factory_id); -} clap_plugin_entry_t; - -/* Entry point */ -CLAP_EXPORT extern clap_plugin_entry_t clap_entry; -// CLAP_EXPORT extern const clap_plugin_entry_t clap_entry; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/events.h b/include/clap/events.h deleted file mode 100644 index 3a587be..0000000 --- a/include/clap/events.h +++ /dev/null @@ -1,286 +0,0 @@ -#pragma once - -#include "private/std.h" -#include "fixedpoint.h" -#include "id.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// event header -// must be the first attribute of the event -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. -// In the case of note choke or end events: -// - the velocity is ignored. -// - key and channel are used to match active notes, a value of -1 matches all. -typedef struct clap_event_note { - clap_event_header_t header; - - int32_t note_id; // -1 if unspecified, otherwise >=0 - int16_t port_index; - int16_t channel; // 0..15 - int16_t key; // 0..127 - double velocity; // 0..1 -} clap_event_note_t; - -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 semitone, from -120 to +120 - 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, -1 for global - 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, -1 for global - 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, -1 for global - 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, -}; - -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; - -typedef struct clap_event_midi_sysex { - clap_event_header_t header; - - uint16_t port_index; - const uint8_t *buffer; // midi buffer - 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 diff --git a/include/clap/ext/audio-ports-config.h b/include/clap/ext/audio-ports-config.h deleted file mode 100644 index 4627154..0000000 --- a/include/clap/ext/audio-ports-config.h +++ /dev/null @@ -1,103 +0,0 @@ -#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/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 diff --git a/include/clap/ext/audio-ports.h b/include/clap/ext/audio-ports.h deleted file mode 100644 index 74b94c3..0000000 --- a/include/clap/ext/audio-ports.h +++ /dev/null @@ -1,117 +0,0 @@ -#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) - // - CLAP_PORT_CV (defined in the cv 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 diff --git a/include/clap/ext/draft/ambisonic.h b/include/clap/ext/draft/ambisonic.h deleted file mode 100644 index 556af9a..0000000 --- a/include/clap/ext/draft/ambisonic.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -// This extension can be used to specify the channel mapping used by the plugin. - -static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC[] = "clap.ambisonic.draft/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 - // - // config_id: the configuration id, see clap_plugin_audio_ports_config. - // If config_id is CLAP_INVALID_ID, then this function queries the current port info. - // [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 diff --git a/include/clap/ext/draft/audio-ports-activation.h b/include/clap/ext/draft/audio-ports-activation.h deleted file mode 100644 index f451c00..0000000 --- a/include/clap/ext/draft/audio-ports-activation.h +++ /dev/null @@ -1,59 +0,0 @@ -#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/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 diff --git a/include/clap/ext/draft/check-for-update.h b/include/clap/ext/draft/check-for-update.h deleted file mode 100644 index 71ebe81..0000000 --- a/include/clap/ext/draft/check-for-update.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_CHECK_FOR_UPDATE[] = "clap.check_for_update.draft/0"; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct clap_check_for_update_info { - const char *version; // latest version - const char *release_date; // YYYY-MM-DD - const char *url; // url to a download page which the user can visit - - bool is_preview; // true if this version is a preview release -} clap_check_for_update_info_t; - -typedef struct clap_plugin_check_for_update { - // [main-thread] - void(CLAP_ABI *check)(const clap_plugin_t *plugin, bool include_preview); -} clap_plugin_check_for_update_t; - -typedef struct clap_host_check_for_update { - // [main-thread] - void(CLAP_ABI *on_new_version)(const clap_host_t *host, - const clap_check_for_update_info_t *update_info); -} clap_host_check_for_update_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/configurable-audio-ports.h b/include/clap/ext/draft/configurable-audio-ports.h deleted file mode 100644 index 4fe60cd..0000000 --- a/include/clap/ext/draft/configurable-audio-ports.h +++ /dev/null @@ -1,57 +0,0 @@ -#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.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 diff --git a/include/clap/ext/draft/context-menu.h b/include/clap/ext/draft/context-menu.h deleted file mode 100644 index 85c3abb..0000000 --- a/include/clap/ext/draft/context-menu.h +++ /dev/null @@ -1,164 +0,0 @@ -#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.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, - // TODO: kind trigger once the trigger ext is marked as stable -}; - -// 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 diff --git a/include/clap/ext/draft/cv.h b/include/clap/ext/draft/cv.h deleted file mode 100644 index 343c836..0000000 --- a/include/clap/ext/draft/cv.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -// This extension can be used to specify the cv channel type used by the plugin. -// Work in progress, suggestions are welcome - -static CLAP_CONSTEXPR const char CLAP_EXT_CV[] = "clap.cv.draft/0"; -static CLAP_CONSTEXPR const char CLAP_PORT_CV[] = "cv"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - // TODO: standardize values? - CLAP_CV_VALUE = 0, - CLAP_CV_GATE = 1, - CLAP_CV_PITCH = 2, -}; - -// TODO: maybe we want a channel_info instead, where we could have more details about the supported -// ranges? - -typedef struct clap_plugin_cv { - // Returns true on success. - // [main-thread] - bool(CLAP_ABI *get_channel_type)(const clap_plugin_t *plugin, - bool is_input, - uint32_t port_index, - uint32_t channel_index, - uint32_t *channel_type); -} clap_plugin_cv_t; - -typedef struct clap_host_cv { - // Informs the host that the channels type have changed. - // The channels type can only change when the plugin is de-activated. - // [main-thread,!active] - void(CLAP_ABI *changed)(const clap_host_t *host); -} clap_host_cv_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/extensible-audio-ports.h b/include/clap/ext/draft/extensible-audio-ports.h deleted file mode 100644 index 278594b..0000000 --- a/include/clap/ext/draft/extensible-audio-ports.h +++ /dev/null @@ -1,33 +0,0 @@ -#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.draft0"; - -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 diff --git a/include/clap/ext/draft/midi-mappings.h b/include/clap/ext/draft/midi-mappings.h deleted file mode 100644 index c584e9d..0000000 --- a/include/clap/ext/draft/midi-mappings.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_MIDI_MAPPINGS[] = "clap.midi-mappings.draft/0"; - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - CLAP_MIDI_MAPPING_CC7, - CLAP_MIDI_MAPPING_CC14, - CLAP_MIDI_MAPPING_RPN, - CLAP_MIDI_MAPPING_NRPN, -}; -typedef int32_t clap_midi_mapping_type; - -typedef struct clap_midi_mapping { - int32_t channel; - int32_t number; - clap_id param_id; -} clap_midi_mapping_t; - -typedef struct clap_plugin_midi_mappings { - // [main-thread] - uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin); - - // Returns true on success and stores the result into mapping. - // [main-thread] - bool(CLAP_ABI *get)(const clap_plugin_t *plugin, uint32_t index, clap_midi_mapping_t *mapping); -} clap_plugin_midi_mappings_t; - -typedef struct clap_host_midi_mappings { - // [main-thread] - void(CLAP_ABI *changed)(const clap_host_t *host); -} clap_host_midi_mappings_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/draft/param-indication.h b/include/clap/ext/draft/param-indication.h deleted file mode 100644 index 5ec45f7..0000000 --- a/include/clap/ext/draft/param-indication.h +++ /dev/null @@ -1,73 +0,0 @@ -#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.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 diff --git a/include/clap/ext/draft/preset-load.h b/include/clap/ext/draft/preset-load.h deleted file mode 100644 index 92263f1..0000000 --- a/include/clap/ext/draft/preset-load.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -static const char CLAP_EXT_PRESET_LOAD[] = "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 diff --git a/include/clap/ext/draft/remote-controls.h b/include/clap/ext/draft/remote-controls.h deleted file mode 100644 index 07566d0..0000000 --- a/include/clap/ext/draft/remote-controls.h +++ /dev/null @@ -1,79 +0,0 @@ -#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.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 diff --git a/include/clap/ext/draft/resource-directory.h b/include/clap/ext/draft/resource-directory.h deleted file mode 100644 index fc65eaa..0000000 --- a/include/clap/ext/draft/resource-directory.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include "../../plugin.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_RESOURCE_DIRECTORY[] = "clap.resource-directory.draft/0"; - -#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 diff --git a/include/clap/ext/draft/state-context.h b/include/clap/ext/draft/state-context.h deleted file mode 100644 index 4912a6e..0000000 --- a/include/clap/ext/draft/state-context.h +++ /dev/null @@ -1,64 +0,0 @@ -#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. -/// -/// 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 the plugin implements CLAP_EXT_STATE_CONTEXT then it is mandatory to also implement -/// CLAP_EXT_STATE. - -#ifdef __cplusplus -extern "C" { -#endif - -static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context.draft/1"; - -enum clap_plugin_state_context_type { - // suitable for duplicating a plugin instance - CLAP_STATE_CONTEXT_FOR_DUPLICATE = 1, - - // suitable for loading a state as a preset - CLAP_STATE_CONTEXT_FOR_PRESET = 2, -}; - -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 diff --git a/include/clap/ext/draft/surround.h b/include/clap/ext/draft/surround.h deleted file mode 100644 index 82f4e88..0000000 --- a/include/clap/ext/draft/surround.h +++ /dev/null @@ -1,83 +0,0 @@ -#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.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 Left - CLAP_SURROUND_BR = 5, // Back Right - CLAP_SURROUND_FLC = 6, // Front Left of Center - CLAP_SURROUND_FRC = 7, // Front Right of Center - CLAP_SURROUND_BC = 8, // Back Center - CLAP_SURROUND_SL = 9, // Side Left - CLAP_SURROUND_SR = 10, // Side Right - CLAP_SURROUND_TC = 11, // Top Center - CLAP_SURROUND_TFL = 12, // Front Left Height - CLAP_SURROUND_TFC = 13, // Front Center Height - CLAP_SURROUND_TFR = 14, // Front Right Height - CLAP_SURROUND_TBL = 15, // Rear Left Height - CLAP_SURROUND_TBC = 16, // Rear Center Height - CLAP_SURROUND_TBR = 17, // Rear Right Height -}; - -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 diff --git a/include/clap/ext/draft/track-info.h b/include/clap/ext/draft/track-info.h deleted file mode 100644 index a79e67c..0000000 --- a/include/clap/ext/draft/track-info.h +++ /dev/null @@ -1,62 +0,0 @@ -#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.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 diff --git a/include/clap/ext/draft/transport-control.h b/include/clap/ext/draft/transport-control.h deleted file mode 100644 index 8a7e7b5..0000000 --- a/include/clap/ext/draft/transport-control.h +++ /dev/null @@ -1,66 +0,0 @@ -#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.draft/0"; - -#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 diff --git a/include/clap/ext/draft/triggers.h b/include/clap/ext/draft/triggers.h deleted file mode 100644 index fa1e83a..0000000 --- a/include/clap/ext/draft/triggers.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -#include "../../plugin.h" -#include "../../events.h" -#include "../../string-sizes.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_TRIGGERS[] = "clap.triggers.draft/0"; - -#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 -// -// 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 diff --git a/include/clap/ext/draft/tuning.h b/include/clap/ext/draft/tuning.h deleted file mode 100644 index db8d976..0000000 --- a/include/clap/ext/draft/tuning.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "../../plugin.h" -#include "../../events.h" -#include "../../string-sizes.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_TUNING[] = "clap.tuning.draft/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 diff --git a/include/clap/ext/event-registry.h b/include/clap/ext/event-registry.h deleted file mode 100644 index c89cea4..0000000 --- a/include/clap/ext/event-registry.h +++ /dev/null @@ -1,22 +0,0 @@ -#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 diff --git a/include/clap/ext/gui.h b/include/clap/ext/gui.h deleted file mode 100644 index 7704da9..0000000 --- a/include/clap/ext/gui.h +++ /dev/null @@ -1,237 +0,0 @@ -#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. -/// -/// 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; - - // only if can resize horizontally and vertically - 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 - // [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 diff --git a/include/clap/ext/latency.h b/include/clap/ext/latency.h deleted file mode 100644 index 862b334..0000000 --- a/include/clap/ext/latency.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "../plugin.h" - -static CLAP_CONSTEXPR const char CLAP_EXT_LATENCY[] = "clap.latency"; - -#ifdef __cplusplus -extern "C" { -#endif - -// The audio ports scan has to be done while the plugin is deactivated. -typedef struct clap_plugin_latency { - // Returns the plugin latency in samples. - // [main-thread] - 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 if the plugin is deactivated. - // If the plugin is activated, call host->request_restart() - // [main-thread] - void(CLAP_ABI *changed)(const clap_host_t *host); -} clap_host_latency_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/ext/log.h b/include/clap/ext/log.h deleted file mode 100644 index 9609c6c..0000000 --- a/include/clap/ext/log.h +++ /dev/null @@ -1,33 +0,0 @@ -#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 diff --git a/include/clap/ext/note-name.h b/include/clap/ext/note-name.h deleted file mode 100644 index 41e6a83..0000000 --- a/include/clap/ext/note-name.h +++ /dev/null @@ -1,37 +0,0 @@ -#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 diff --git a/include/clap/ext/note-ports.h b/include/clap/ext/note-ports.h deleted file mode 100644 index f91b527..0000000 --- a/include/clap/ext/note-ports.h +++ /dev/null @@ -1,79 +0,0 @@ -#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 diff --git a/include/clap/ext/params.h b/include/clap/ext/params.h deleted file mode 100644 index 2ec7e02..0000000 --- a/include/clap/ext/params.h +++ /dev/null @@ -1,382 +0,0 @@ -#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.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 - double max_value; // Maximum plain value - double default_value; // Default plain value -} 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 diff --git a/include/clap/ext/posix-fd-support.h b/include/clap/ext/posix-fd-support.h deleted file mode 100644 index c713ec8..0000000 --- a/include/clap/ext/posix-fd-support.h +++ /dev/null @@ -1,49 +0,0 @@ -#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 diff --git a/include/clap/ext/render.h b/include/clap/ext/render.h deleted file mode 100644 index 0e1c1cd..0000000 --- a/include/clap/ext/render.h +++ /dev/null @@ -1,39 +0,0 @@ -#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 diff --git a/include/clap/ext/state.h b/include/clap/ext/state.h deleted file mode 100644 index 8d028e1..0000000 --- a/include/clap/ext/state.h +++ /dev/null @@ -1,41 +0,0 @@ -#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. - -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 diff --git a/include/clap/ext/tail.h b/include/clap/ext/tail.h deleted file mode 100644 index 5d79e3a..0000000 --- a/include/clap/ext/tail.h +++ /dev/null @@ -1,26 +0,0 @@ -#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 diff --git a/include/clap/ext/thread-check.h b/include/clap/ext/thread-check.h deleted file mode 100644 index 7b68e1b..0000000 --- a/include/clap/ext/thread-check.h +++ /dev/null @@ -1,53 +0,0 @@ -#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 user interaction, -/// so it is recommended to run long and expensive tasks such as preset indexing or asset loading -/// in dedicated background threads. -/// -/// audio-thread: -/// This thread is used for realtime audio processing. Its execution should be as deterministic -/// as possible to meet the audio interface's deadline (can be <1ms). In other words, there is a -/// known set of operations that should be avoided: malloc() and free(), mutexes (spin mutexes -/// are worse), I/O, waiting, ... -/// The audio-thread is something symbolic, there isn't one OS thread that remains the -/// audio-thread for the plugin lifetime. As you may guess, the host is likely to have a -/// thread pool and the plugin.process() call may be scheduled on different OS threads over time. -/// The most important thing is that there can't be two audio-threads at the same time. All the -/// 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. The audio-thread can be seen as a concurrency guard for -/// all functions marked with [audio-thread]. - -// 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 diff --git a/include/clap/ext/thread-pool.h b/include/clap/ext/thread-pool.h deleted file mode 100644 index 790bef9..0000000 --- a/include/clap/ext/thread-pool.h +++ /dev/null @@ -1,66 +0,0 @@ -#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 diff --git a/include/clap/ext/timer-support.h b/include/clap/ext/timer-support.h deleted file mode 100644 index 221de96..0000000 --- a/include/clap/ext/timer-support.h +++ /dev/null @@ -1,31 +0,0 @@ -#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 diff --git a/include/clap/ext/voice-info.h b/include/clap/ext/voice-info.h deleted file mode 100644 index 344ed8a..0000000 --- a/include/clap/ext/voice-info.h +++ /dev/null @@ -1,56 +0,0 @@ -#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 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 diff --git a/include/clap/factory/draft/plugin-invalidation.h b/include/clap/factory/draft/plugin-invalidation.h deleted file mode 100644 index ea698e5..0000000 --- a/include/clap/factory/draft/plugin-invalidation.h +++ /dev/null @@ -1,47 +0,0 @@ -#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/draft0"; - -#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 diff --git a/include/clap/factory/draft/preset-discovery.h b/include/clap/factory/draft/preset-discovery.h deleted file mode 100644 index 05223d9..0000000 --- a/include/clap/factory/draft/preset-discovery.h +++ /dev/null @@ -1,327 +0,0 @@ -/* - 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 "../../version.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/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, -}; - -// TODO: move clap_timestamp_t, CLAP_TIMESTAMP_UNKNOWN and clap_plugin_id_t to parent files once we -// settle with preset discovery - -// 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_t; - -// Value for unknown timestamp. -static const clap_timestamp_t CLAP_TIMESTAMP_UNKNOWN = 0; - -// Pair of plugin ABI and plugin identifier -typedef struct clap_plugin_id { - // The plugin ABI name, in lowercase. - // eg: "clap" - const char *abi; - - // The plugin ID, for example "com.u-he.Diva". - // If the ABI rely upon binary plugin ids, then they shall be hex encoded (lower case). - const char *id; -} clap_plugin_id_t; - -// 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_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_t creation_time, - clap_timestamp_t 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_t 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 diff --git a/include/clap/factory/plugin-factory.h b/include/clap/factory/plugin-factory.h deleted file mode 100644 index 0899665..0000000 --- a/include/clap/factory/plugin-factory.h +++ /dev/null @@ -1,42 +0,0 @@ -#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 diff --git a/include/clap/fixedpoint.h b/include/clap/fixedpoint.h deleted file mode 100644 index fb042d3..0000000 --- a/include/clap/fixedpoint.h +++ /dev/null @@ -1,16 +0,0 @@ -#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; diff --git a/include/clap/host.h b/include/clap/host.h deleted file mode 100644 index ddfeb8e..0000000 --- a/include/clap/host.h +++ /dev/null @@ -1,44 +0,0 @@ -#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. - // [thread-safe] - void(CLAP_ABI *request_callback)(const struct clap_host *host); -} clap_host_t; - -#ifdef __cplusplus -} -#endif diff --git a/include/clap/id.h b/include/clap/id.h deleted file mode 100644 index 3b2b6e6..0000000 --- a/include/clap/id.h +++ /dev/null @@ -1,8 +0,0 @@ -#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; diff --git a/include/clap/plugin-features.h b/include/clap/plugin-features.h deleted file mode 100644 index e5dc18c..0000000 --- a/include/clap/plugin-features.h +++ /dev/null @@ -1,79 +0,0 @@ -#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" diff --git a/include/clap/plugin.h b/include/clap/plugin.h deleted file mode 100644 index 97ead81..0000000 --- a/include/clap/plugin.h +++ /dev/null @@ -1,110 +0,0 @@ -#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. - // [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]. - // Once activated the latency and port configuration must remain constant, until deactivation. - // Returns true on success. - // [main-thread & !active_state] - 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_state] - void(CLAP_ABI *deactivate)(const struct clap_plugin *plugin); - - // Call start processing before processing. - // Returns true on success. - // [audio-thread & active_state & !processing_state] - bool(CLAP_ABI *start_processing)(const struct clap_plugin *plugin); - - // Call stop processing before sending the plugin to sleep. - // [audio-thread & active_state & processing_state] - 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_state] - 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_state & processing_state] - 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 diff --git a/include/clap/private/macros.h b/include/clap/private/macros.h deleted file mode 100644 index ba1d665..0000000 --- a/include/clap/private/macros.h +++ /dev/null @@ -1,50 +0,0 @@ -#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 diff --git a/include/clap/private/std.h b/include/clap/private/std.h deleted file mode 100644 index 1c2ffdd..0000000 --- a/include/clap/private/std.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "macros.h" - -#ifdef CLAP_HAS_CXX11 -# include -#else -# include -#endif - -#ifdef __cplusplus -# include -#else -# include -# include -#endif diff --git a/include/clap/process.h b/include/clap/process.h deleted file mode 100644 index c9dbf92..0000000 --- a/include/clap/process.h +++ /dev/null @@ -1,66 +0,0 @@ -#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 diff --git a/include/clap/stream.h b/include/clap/stream.h deleted file mode 100644 index b9b0b6c..0000000 --- a/include/clap/stream.h +++ /dev/null @@ -1,38 +0,0 @@ -#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 diff --git a/include/clap/string-sizes.h b/include/clap/string-sizes.h deleted file mode 100644 index 4334c6d..0000000 --- a/include/clap/string-sizes.h +++ /dev/null @@ -1,21 +0,0 @@ -#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 diff --git a/include/clap/version.h b/include/clap/version.h deleted file mode 100644 index 33072a2..0000000 --- a/include/clap/version.h +++ /dev/null @@ -1,42 +0,0 @@ -#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 1 -#define CLAP_VERSION_REVISION 10 - -#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; -} diff --git a/main.v b/main.v index 6048746..0ea705e 100644 --- a/main.v +++ b/main.v @@ -1,8 +1,8 @@ -import vclap +import plugin // Exposes the plugin to the host (DAW). @[markused] -__global clap_entry = vclap.plugin_entry +__global clap_entry = plugin.entry // This requires modification to `clap/entry.h`. // Remove "const" so you get: // CLAP_EXPORT extern clap_plugin_entry_t clap_entry; diff --git a/vclap/.clang-format b/plugin/.clang-format similarity index 100% rename from vclap/.clang-format rename to plugin/.clang-format diff --git a/vclap/gui/gui.v b/plugin/gui/gui.v similarity index 100% rename from vclap/gui/gui.v rename to plugin/gui/gui.v diff --git a/vclap/gui/xcb.v b/plugin/gui/xcb.v similarity index 100% rename from vclap/gui/xcb.v rename to plugin/gui/xcb.v diff --git a/plugin/plugin.v b/plugin/plugin.v new file mode 100644 index 0000000..7a6fa84 --- /dev/null +++ b/plugin/plugin.v @@ -0,0 +1,302 @@ +module plugin + +import odiroot.clap +import odiroot.clap.ext as cext +import plugin.gui { GUI } + +const gui_width = 640 +const gui_height = 480 + +// This should be the actual implementation of the plugin with +// all the interesting logic like DSP, UI, etc. +@[heap] +struct MinimalPlugin { + host &clap.Host +mut: + sample_rate f64 + latency u32 + host_posix_fd &cext.HostPosixFdSupport = unsafe { nil } + gui &gui.GUI = unsafe { nil } +} + +// Extract our actual pluging from CLAP plugin wrapper. +fn from_clap(clap_plugin &clap.Plugin) &MinimalPlugin { + return unsafe { &MinimalPlugin(clap_plugin.plugin_data) } +} + +fn (mut mp MinimalPlugin) init(clap_plugin &clap.Plugin) bool { + mp.host_posix_fd = mp.host.get_extension(mp.host, cext.ext_posix_fd_support.str) + return true +} + +fn (mp MinimalPlugin) destroy(clap_plugin &clap.Plugin) { + // Cleanup plugin members here. +} + +fn (mut mp MinimalPlugin) activate(clap_plugin &clap.Plugin, sample_rate f64, min_frames_count u32, max_frames_count u32) bool { + mp.sample_rate = sample_rate + return true +} + +fn (mp MinimalPlugin) deactivate(clap_plugin &clap.Plugin) { +} + +fn (mp MinimalPlugin) start_processing(clap_plugin &clap.Plugin) bool { + return true +} + +fn (mp MinimalPlugin) stop_processing(clap_plugin &clap.Plugin) { +} + +fn (mp MinimalPlugin) reset(clap_plugin &clap.Plugin) { + // Cleanup plugin members here. +} + +fn (mp MinimalPlugin) process_event(header &clap.EventHeader) { + if header.space_id != clap.core_event_space_id { + return + } + + match header.@type { + u16(clap.event_note_on) { + // Handle note playing. + event := unsafe { &clap.EventNote(header) } + debug('Note ON: ${event.note_id}') + } + u16(clap.event_note_off) { + // Handle note stop playing. + event := unsafe { &clap.EventNote(header) } + debug('Note OFF: ${event.note_id}') + } + // And so on... + else { + t := unsafe { clap.EventType(header.@type) } + debug('Unsupported event type: ${t}') + } + } +} + +fn (mp MinimalPlugin) process(clap_plugin &clap.Plugin, mut process clap.Process) clap.ProcessStatus { + frame_count := process.frames_count + event_count := process.in_events.size(process.in_events) + + mut event_index := u32(0) + mut next_frame := if event_count > 0 { 0 } else { frame_count } + + for i := 0; i < frame_count; { + for event_index < event_count { + // Handle every event at frame i. + if next_frame != i { + break + } + + header := process.in_events.get(process.in_events, event_index) + + if header.time != i { + next_frame = header.time + break + } + + mp.process_event(header) + event_index++ + + // Event list exhausted. + if event_index == event_count { + next_frame = frame_count + break + } + } + + for ; i < next_frame; i++ { + // In general: + // mut inputs := []AudioBuffer{cap: int(process.audio_inputs_count)} + // for k := 0; k < process.audio_inputs_count; k++ { + // inputs << unsafe{ process.audio_inputs[k] } + // } + input_left := unsafe { process.audio_inputs[0].data32[0][i] } + input_right := unsafe { process.audio_inputs[0].data32[1][i] } + + // Swap left and right channels. + unsafe { + process.audio_outputs[0].data32[0][i] = input_right + } + unsafe { + process.audio_outputs[0].data32[1][i] = input_left + } + } + } + + return clap.process_continue +} + +fn (mut mp MinimalPlugin) get_extension(clap_plugin &clap.Plugin, id &char) voidptr { + v_id := unsafe { cstring_to_vstring(id) } + + match v_id { + cext.ext_latency { + return &cext.PluginLatency{ + get: fn [mp] (clap_plugin &clap.Plugin) u32 { + return mp.latency + } + } + } + cext.ext_audio_ports { + return &cext.PluginAudioPorts{ + count: fn (clap_plugin &clap.Plugin, is_input bool) u32 { + return 1 + } + get: fn (clap_plugin &clap.Plugin, index u32, is_input bool, mut info cext.AudioPortInfo) bool { + // Just one port. + if index > 0 { + return false + } + + info.id = 0 + info.channel_count = 2 + info.flags = cext.audio_port_is_main + info.port_type = cext.port_stereo.str + info.in_place_pair = C.CLAP_INVALID_ID + + // Translate string to constant array. + port_name := 'Example audio port' + for i, chr in port_name { + info.name[i] = chr + } + info.name[port_name.len] = char(0) + + return true + } + } + } + cext.ext_note_ports { + return &cext.PluginNotePorts{ + count: fn (clap_plugin &clap.Plugin, is_input bool) u32 { + return 1 + } + get: fn (clap_plugin &clap.Plugin, index u32, is_input bool, mut info &cext.NotePortInfo) bool { + if index > 0 { + return false + } + + info.id = 0 + // vfmt off + info.supported_dialects = ( + u32(cext.note_dialect_clap) | + u32(cext.note_dialect_midi_mpe) | + u32(cext.note_dialect_midi2) + ) + // vfmt on + info.preferred_dialect = u32(cext.note_dialect_clap) + + port_name := 'Example note port' + for i, chr in port_name { + info.name[i] = chr + } + info.name[port_name.len] = char(0) + + return true + } + } + } + cext.ext_gui { + return &cext.PluginGUI{ + is_api_supported: fn (clap_plugin &clap.Plugin, api &char, is_floating bool) bool { + if is_floating { + return false + } + v_api := unsafe { cstring_to_vstring(api) } + // Only X11 for now. + return v_api == cext.window_api_x11 + } + get_preferred_api: fn (clap_plugin &clap.Plugin, mut api voidptr, mut is_floating &bool) bool { + is_floating = false + api = &cext.window_api_x11.str + return true + } + create: fn [mut mp] (clap_plugin &clap.Plugin, api &char, is_floating bool) bool { + v_api := unsafe { cstring_to_vstring(api) } + if v_api != cext.window_api_x11 || is_floating { + return false + } + if !isnil(mp.gui) { + panic('GUI already initialised!') + } + mp.gui = GUI.create(gui_width, gui_height, plugin_name) + // Register the file descriptor we'll receive events from. + if !isnil(mp.host_posix_fd) && !isnil(mp.host_posix_fd.register_fd) { + mp.host_posix_fd.register_fd(mp.host, mp.gui.fd, cext.posix_fd_read) + } + + return true + } + destroy: fn [mut mp] (clap_plugin &clap.Plugin) { + if !isnil(mp.host_posix_fd) && !isnil(mp.host_posix_fd.unregister_fd) { + mp.host_posix_fd.unregister_fd(mp.host, mp.gui.fd) + } + if isnil(mp.gui) { + panic('GUI not initialised!') + } + mp.gui.destroy() + + unsafe { + mp.gui = nil + } + } + set_scale: fn (clap_plugin &clap.Plugin, scale f64) bool { + return false + } + get_size: fn (clap_plugin &clap.Plugin, mut width &u32, mut height &u32) bool { + width = gui_width + height = gui_height + return true + } + can_resize: fn (clap_plugin &clap.Plugin) bool { + return false + } + get_resize_hints: fn (clap_plugin &clap.Plugin, hints &cext.GUIResizeHints) bool { + return false + } + adjust_size: fn (clap_plugin &clap.Plugin, mut width &u32, mut height &u32) bool { + width = gui_width + height = gui_height + return true + } + set_size: fn (clap_plugin &clap.Plugin, width &u32, height &u32) bool { + return true + } + set_parent: fn [mut mp] (clap_plugin &clap.Plugin, window &cext.Window) bool { + v_wapi := unsafe { (&char(window.api)).vstring() } + assert v_wapi == cext.window_api_x11, 'Bad GUI API' + + mp.gui.set_parent(window.x11) + return true + } + set_transient: fn (clap_plugin &clap.Plugin, window &cext.Window) bool { + return false + } + suggest_title: fn (clap_plugin &clap.Plugin, title &char) {} + show: fn [mp] (clap_plugin &clap.Plugin) bool { + mp.gui.set_visible(true) + return true + } + hide: fn [mp] (clap_plugin &clap.Plugin) bool { + mp.gui.set_visible(false) + return true + } + } + } + cext.ext_posix_fd_support { + return &cext.PluginPosixFdSupport{ + on_fd: fn [mp] (clap_plugin &clap.Plugin, fd int, flags cext.PosixFdFlags) { + mp.gui.on_posix_fd() + } + } + } + else { + return unsafe { nil } + } + } +} + +fn (mp MinimalPlugin) on_main_thread(clap_plugin &clap.Plugin) { +} diff --git a/vclap/setup.v b/plugin/setup.v similarity index 70% rename from vclap/setup.v rename to plugin/setup.v index 048992f..8a486cb 100644 --- a/vclap/setup.v +++ b/plugin/setup.v @@ -1,6 +1,8 @@ -module vclap +module plugin import v.vmod +import odiroot.clap +import odiroot.clap.factory as cfactory // Only need to change the mod file to update the version. const manifest = vmod.decode(@VMOD_FILE) or { panic(err) } @@ -17,9 +19,9 @@ const _plugin_features = [ ]! // Plugin information, extracted at load time. -const _plugin_id = 'example.hello.world' -const _plugin_descriptor = C.clap_plugin_descriptor_t{ - id: _plugin_id.str +const _id = 'example.hello.world' +const _descriptor = clap.PluginDescriptor{ + id: _id.str name: plugin_name.str vendor: c'MOFOSS' version: current_version.str @@ -30,13 +32,13 @@ const _plugin_descriptor = C.clap_plugin_descriptor_t{ }) } -fn create_plugin(factory &C.clap_plugin_factory_t, host &C.clap_host_t, plugin_id &char) &C.clap_plugin_t { +fn create_plugin(factory &cfactory.PluginFactory, host &clap.Host, plugin_id &char) &clap.Plugin { // Sanity checks for lib version and correct plugin expected. - if !C.clap_version_is_compatible(host.clap_version) { + if !clap.version_is_compatible(host.clap_version) { return unsafe { nil } } v_plugin_id := unsafe { cstring_to_vstring(plugin_id) } - if v_plugin_id != vclap._plugin_id { + if v_plugin_id != _id { return unsafe { nil } } @@ -44,9 +46,10 @@ fn create_plugin(factory &C.clap_plugin_factory_t, host &C.clap_host_t, plugin_i main_plugin := &MinimalPlugin{ host: host } + // This is the "official" plugin. - clap_plugin := &C.clap_plugin_t{ - desc: &vclap._plugin_descriptor + clap_plugin := &clap.Plugin{ + desc: &plugin._descriptor // It always carries a pointer to our custom structure. plugin_data: main_plugin init: main_plugin.init @@ -66,15 +69,14 @@ fn create_plugin(factory &C.clap_plugin_factory_t, host &C.clap_host_t, plugin_i fn entry_get_factory(factory_id &char) voidptr { factory_id_v := unsafe { factory_id.vstring() } - - if factory_id_v == clap_plugin_factory_id { - factory := C.clap_plugin_factory_t{ - get_plugin_count: fn (factory &C.clap_plugin_factory_t) u32 { + if factory_id_v == cfactory.plugin_factory_id { + factory := cfactory.PluginFactory{ + get_plugin_count: fn (factory &cfactory.PluginFactory) u32 { return 1 } - get_plugin_descriptor: fn (factory &C.clap_plugin_factory_t, index u32) &C.clap_plugin_descriptor_t { + get_plugin_descriptor: fn (factory &cfactory.PluginFactory, index u32) &clap.PluginDescriptor { if index == 0 { - return &vclap._plugin_descriptor + return &plugin._descriptor } else { return unsafe { nil } } @@ -87,8 +89,8 @@ fn entry_get_factory(factory_id &char) voidptr { return unsafe { nil } } -pub const plugin_entry = C.clap_plugin_entry_t{ - clap_version: C.clap_version_t{} +pub const entry = clap.PluginEntry{ + clap_version: clap.Version{} init: fn (plugin_path &char) bool { return true } diff --git a/vclap/utils.v b/plugin/utils.v similarity index 77% rename from vclap/utils.v rename to plugin/utils.v index 3b71aad..227490d 100644 --- a/vclap/utils.v +++ b/plugin/utils.v @@ -1,4 +1,4 @@ -module vclap +module plugin @[if debug] fn debug(s string) { diff --git a/v.mod b/v.mod index 2bc2069..e495ea0 100644 --- a/v.mod +++ b/v.mod @@ -1,7 +1,9 @@ Module { - name: 'vclap' + name: 'clap-plugin' description: 'Demonstration of a CLAP audio plugin in V.' version: '0.2.0' license: 'MIT' - dependencies: [] + dependencies: [ + 'odiroot.clap' + ] } diff --git a/vclap/c_abi.v b/vclap/c_abi.v deleted file mode 100644 index cdc4e0f..0000000 --- a/vclap/c_abi.v +++ /dev/null @@ -1,150 +0,0 @@ -module vclap - -#flag -I @VMODROOT/include -#include "clap/clap.h" - -enum ClapProcessStatus { - error = 0 - @continue = 1 - continue_if_not_quiet = 2 - tail = 3 - sleep = 4 -} - -type C.clap_id = u32 - -@[typedef] -struct C.clap_version_t { - major u32 = u32(C.CLAP_VERSION_MAJOR) - minor u32 = u32(C.CLAP_VERSION_MINOR) - revision u32 = u32(C.CLAP_VERSION_REVISION) -} - -@[typedef] -struct C.clap_plugin_descriptor_t { - clap_version C.clap_version_t = C.clap_version_t{} - id &char - name &char - vendor &char - url &char = ''.str - manual_url &char = ''.str - support_url &char = ''.str - version &char - description &char - features &&char -} - -@[typedef] -struct C.clap_plugin_t { - desc &C.clap_plugin_descriptor_t @[required] - plugin_data voidptr @[required] - - init fn (&C.clap_plugin_t) bool @[required] - destroy fn (&C.clap_plugin_t) @[required] - activate fn (&C.clap_plugin_t, f64, u32, u32) bool @[required] - deactivate fn (&C.clap_plugin_t) @[required] - start_processing fn (&C.clap_plugin_t) bool - stop_processing fn (&C.clap_plugin_t) - reset fn (&C.clap_plugin_t) - process fn (&C.clap_plugin_t, &C.clap_process_t) ClapProcessStatus - get_extension fn (&C.clap_plugin_t, &char) voidptr - on_main_thread fn (&C.clap_plugin_t) -} - -@[heap; typedef] -struct C.clap_host_t { - clap_version C.clap_version_t - get_extension fn (&C.clap_host_t, &char) voidptr -} - -@[typedef] -struct C.clap_plugin_factory_t { - get_plugin_count fn (&C.clap_plugin_factory_t) u32 - get_plugin_descriptor fn (&C.clap_plugin_factory_t, u32) &C.clap_plugin_descriptor_t - create_plugin fn (&C.clap_plugin_factory_t, &C.clap_host_t, &char) &C.clap_plugin_t -} - -@[typedef] -struct C.clap_plugin_entry_t { - clap_version C.clap_version_t - init fn (&char) bool - deinit fn () - get_factory fn (&char) voidptr -} - -@[typedef] -struct C.clap_process_t { - steady_time i64 - frames_count u32 - transport &C.clap_event_transport_t - audio_inputs &C.clap_audio_buffer_t - audio_inputs_count u32 - audio_outputs_count u32 - in_events &C.clap_input_events_t - out_events &C.clap_output_events_t -mut: - audio_outputs &C.clap_audio_buffer_t -} - -@[typedef] -struct C.clap_event_transport_t {} - -@[typedef] -struct C.clap_audio_buffer_t { - channel_count u32 - latency u32 - constant_mask u64 -mut: - data32 &&f32 - data64 &&f64 -} - -@[typedef] -struct C.clap_input_events_t { - ctx voidptr - size fn (&C.clap_input_events_t) u32 - get fn (&C.clap_input_events_t, u32) &C.clap_event_header_t -} - -@[typedef] -struct C.clap_event_header_t { - size u32 - time u32 - space_id u16 - @type u16 - flags u32 -} - -@[typedef] -struct C.clap_event_note_t { - header C.clap_event_header_t - note_id int - port_index i16 - channel i16 - key i16 - velocity f64 -} - -enum ClapEventType as u16 { - note_on = 0 - note_off = 1 - note_choke = 2 - note_end = 3 - note_expression = 4 - param_value = 5 - param_mod = 6 - param_gesture_begin = 7 - param_gesture_end = 8 - transport = 9 - midi = 10 - midi_sysex = 11 - midi2 = 12 -} - -@[typedef] -struct C.clap_output_events_t {} - -const clap_plugin_factory_id = unsafe { (&char(C.CLAP_PLUGIN_FACTORY_ID)).vstring() } -const clap_core_event_space_id = u16(C.CLAP_CORE_EVENT_SPACE_ID) - -fn C.clap_version_is_compatible(C.clap_version_t) bool diff --git a/vclap/ext_audio_ports.v b/vclap/ext_audio_ports.v deleted file mode 100644 index f7dbef6..0000000 --- a/vclap/ext_audio_ports.v +++ /dev/null @@ -1,29 +0,0 @@ -module vclap - -const clap_ext_audio_ports = unsafe { (&char(C.CLAP_EXT_AUDIO_PORTS)).vstring() } -const clap_port_stereo = unsafe { (&char(C.CLAP_PORT_STEREO)).vstring() } -const clap_port_mono = unsafe { (&char(C.CLAP_PORT_MONO)).vstring() } - -@[typedef] -struct C.clap_audio_port_info_t { -mut: - id C.clap_id - name [256]char - flags u32 - channel_count u32 - port_type &char - in_place_pair C.clap_id -} - -@[typedef] -struct C.clap_plugin_audio_ports_t { - count fn (&C.clap_plugin_t, bool) u32 - get fn (&C.clap_plugin_t, u32, bool, &C.clap_audio_port_info_t) bool -} - -enum ClapAudioPortFlags as u32 { - is_main = 1 << 0 - supports_64_bits = 1 << 1 - prefers_64_bits = 1 << 2 - requires_common_sample_size = 1 << 3 -} diff --git a/vclap/ext_gui.v b/vclap/ext_gui.v deleted file mode 100644 index c698ce7..0000000 --- a/vclap/ext_gui.v +++ /dev/null @@ -1,49 +0,0 @@ -module vclap - -const clap_ext_gui = unsafe { (&char(C.CLAP_EXT_GUI)).vstring() } -const clap_window_api_x11 = unsafe { (&char(C.CLAP_WINDOW_API_X11)).vstring() } -const clap_window_api_wayland = unsafe { (&char(C.CLAP_WINDOW_API_WAYLAND)).vstring() } - -type C.clap_hwnd = voidptr -type C.clap_nsview = voidptr -type C.clap_xwnd = u32 - -@[typedef] -struct C.clap_window_t { - api &char - // union { - cocoa C.clap_nsview - x11 C.clap_xwnd - win32 C.clap_hwnd - ptr voidptr - // } -} - -@[typedef] -struct C.clap_gui_resize_hints_t { - can_resize_horizontally bool - can_resize_vertically bool - preserve_aspect_ratio bool - aspect_ratio_width u32 - aspect_ratio_height u32 -} - -@[typedef] -struct C.clap_plugin_gui_t { - is_api_supported fn (&C.clap_plugin_t, &char, bool) bool - // voidptr is &&char in original but used in a weird way. - get_preferred_api fn (&C.clap_plugin_t, voidptr, &bool) bool - create fn (&C.clap_plugin_t, &char, bool) bool - destroy fn (&C.clap_plugin_t) - set_scale fn (&C.clap_plugin_t, f64) bool - get_size fn (&C.clap_plugin_t, &u32, &u32) bool - can_resize fn (&C.clap_plugin_t) bool - get_resize_hints fn (&C.clap_plugin_t, &C.clap_gui_resize_hints_t) bool - adjust_size fn (&C.clap_plugin_t, &u32, &u32) bool - set_size fn (&C.clap_plugin_t, &u32, &u32) bool - set_parent fn (&C.clap_plugin_t, &C.clap_window_t) bool - set_transient fn (&C.clap_plugin_t, &C.clap_window_t) bool - suggest_title fn (&C.clap_plugin_t, &char) - show fn (&C.clap_plugin_t) bool - hide fn (&C.clap_plugin_t) bool -} diff --git a/vclap/ext_latency.v b/vclap/ext_latency.v deleted file mode 100644 index 556a1e5..0000000 --- a/vclap/ext_latency.v +++ /dev/null @@ -1,8 +0,0 @@ -module vclap - -const clap_ext_latency = unsafe { (&char(C.CLAP_EXT_LATENCY)).vstring() } - -@[typedef] -struct C.clap_plugin_latency_t { - get fn (&C.clap_plugin_t) u32 -} diff --git a/vclap/ext_note_ports.v b/vclap/ext_note_ports.v deleted file mode 100644 index 3df3bac..0000000 --- a/vclap/ext_note_ports.v +++ /dev/null @@ -1,25 +0,0 @@ -module vclap - -const clap_ext_note_ports = unsafe { (&char(C.CLAP_EXT_NOTE_PORTS)).vstring() } - -@[typedef] -struct C.clap_note_port_info_t { -mut: - id C.clap_id - supported_dialects u32 - preferred_dialect u32 - name [256]char -} - -@[typedef] -struct C.clap_plugin_note_ports_t { - count fn (&C.clap_plugin_t, bool) u32 - get fn (&C.clap_plugin_t, u32, bool, &C.clap_note_port_info_t) bool -} - -enum ClapNoteDialect as u32 { - clap = 1 << 0 - midi = 1 << 1 - midi_mpe = 1 << 2 - midi2 = 1 << 3 -} diff --git a/vclap/ext_posix_fd.v b/vclap/ext_posix_fd.v deleted file mode 100644 index 4e106d5..0000000 --- a/vclap/ext_posix_fd.v +++ /dev/null @@ -1,21 +0,0 @@ -module vclap - -const clap_ext_posix_fd_support = unsafe { (&char(C.CLAP_EXT_POSIX_FD_SUPPORT)).vstring() } - -enum ClapPosixFDFlags as u32 { - read = 1 << 0 - write = 1 << 1 - error = 1 << 2 -} - -@[typedef] -struct C.clap_host_posix_fd_support_t { - register_fd fn (&C.clap_host_t, int, ClapPosixFDFlags) bool - modify_fd fn (&C.clap_host_t, int, ClapPosixFDFlags) bool - unregister_fd fn (&C.clap_host_t, int) bool -} - -@[typedef] -struct C.clap_plugin_posix_fd_support_t { - on_fd fn (&C.clap_plugin_t, int, ClapPosixFDFlags) -} diff --git a/vclap/plugin.v b/vclap/plugin.v deleted file mode 100644 index 948d64d..0000000 --- a/vclap/plugin.v +++ /dev/null @@ -1,300 +0,0 @@ -module vclap - -import vclap.gui { GUI } - -const gui_width = 640 -const gui_height = 480 - -// This should be the actual implementation of the plugin with -// all the interesting logic like DSP, UI, etc. -@[heap] -struct MinimalPlugin { - host &C.clap_host_t -mut: - sample_rate f64 - latency u32 - host_posix_fd &C.clap_host_posix_fd_support_t = unsafe { nil } - gui &gui.GUI = unsafe { nil } -} - -// Extract our actual pluging from CLAP plugin wrapper. -fn from_clap(clap_plugin &C.clap_plugin_t) &MinimalPlugin { - return unsafe { &MinimalPlugin(clap_plugin.plugin_data) } -} - -fn (mut mp MinimalPlugin) init(clap_plugin &C.clap_plugin_t) bool { - mp.host_posix_fd = mp.host.get_extension(mp.host, clap_ext_posix_fd_support.str) - return true -} - -fn (mp MinimalPlugin) destroy(clap_plugin &C.clap_plugin_t) { - // Cleanup plugin members here. -} - -fn (mut mp MinimalPlugin) activate(clap_plugin &C.clap_plugin_t, sample_rate f64, min_frames_count u32, max_frames_count u32) bool { - mp.sample_rate = sample_rate - return true -} - -fn (mp MinimalPlugin) deactivate(clap_plugin &C.clap_plugin_t) { -} - -fn (mp MinimalPlugin) start_processing(clap_plugin &C.clap_plugin_t) bool { - return true -} - -fn (mp MinimalPlugin) stop_processing(clap_plugin &C.clap_plugin_t) { -} - -fn (mp MinimalPlugin) reset(clap_plugin &C.clap_plugin_t) { - // Cleanup plugin members here. -} - -fn (mp MinimalPlugin) process_event(header &C.clap_event_header_t) { - if header.space_id != clap_core_event_space_id { - return - } - - match header.@type { - u16(ClapEventType.note_on) { - // Handle note playing. - event := &C.clap_event_note_t(header) - debug('Note ON: ${event.note_id}') - } - u16(ClapEventType.note_off) { - // Handle note stop playing. - event := &C.clap_event_note_t(header) - debug('Note OFF: ${event.note_id}') - } - // And so on... - else { - t := unsafe { ClapEventType(header.@type) } - debug('Unsupported event type: ${t}') - } - } -} - -fn (mp MinimalPlugin) process(clap_plugin &C.clap_plugin_t, mut process C.clap_process_t) ClapProcessStatus { - frame_count := process.frames_count - event_count := process.in_events.size(process.in_events) - - mut event_index := u32(0) - mut next_frame := if event_count > 0 { 0 } else { frame_count } - - for i := 0; i < frame_count; { - for event_index < event_count { - // Handle every event at frame i. - if next_frame != i { - break - } - - header := process.in_events.get(process.in_events, event_index) - - if header.time != i { - next_frame = header.time - break - } - - mp.process_event(header) - event_index++ - - // Event list exhausted. - if event_index == event_count { - next_frame = frame_count - break - } - } - - for ; i < next_frame; i++ { - // In general: - // mut inputs := []C.clap_audio_buffer_t{cap: int(process.audio_inputs_count)} - // for k := 0; k < process.audio_inputs_count; k++ { - // inputs << unsafe{ process.audio_inputs[k] } - // } - input_left := unsafe { process.audio_inputs[0].data32[0][i] } - input_right := unsafe { process.audio_inputs[0].data32[1][i] } - - // Swap left and right channels. - unsafe { - process.audio_outputs[0].data32[0][i] = input_right - } - unsafe { - process.audio_outputs[0].data32[1][i] = input_left - } - } - } - - return ClapProcessStatus.@continue -} - -fn (mut mp MinimalPlugin) get_extension(clap_plugin &C.clap_plugin_t, id &char) voidptr { - v_id := unsafe { cstring_to_vstring(id) } - - match v_id { - clap_ext_latency { - return &C.clap_plugin_latency_t{ - get: fn [mp] (clap_plugin &C.clap_plugin_t) u32 { - return mp.latency - } - } - } - clap_ext_audio_ports { - return &C.clap_plugin_audio_ports_t{ - count: fn (clap_plugin &C.clap_plugin_t, is_input bool) u32 { - return 1 - } - get: fn (clap_plugin &C.clap_plugin_t, index u32, is_input bool, mut info C.clap_audio_port_info_t) bool { - // Just one port. - if index > 0 { - return false - } - - info.id = 0 - info.channel_count = 2 - info.flags = u32(ClapAudioPortFlags.is_main) - info.port_type = clap_port_stereo.str - info.in_place_pair = C.CLAP_INVALID_ID - - // Translate string to constant array. - port_name := 'Example audio port' - for i, chr in port_name { - info.name[i] = chr - } - info.name[port_name.len] = char(0) - - return true - } - } - } - clap_ext_note_ports { - return &C.clap_plugin_note_ports_t{ - count: fn (clap_plugin &C.clap_plugin_t, is_input bool) u32 { - return 1 - } - get: fn (clap_plugin &C.clap_plugin_t, index u32, is_input bool, mut info C.clap_note_port_info_t) bool { - if index > 0 { - return false - } - - info.id = 0 - // vfmt off - info.supported_dialects = ( - u32(ClapNoteDialect.clap) | - u32(ClapNoteDialect.midi_mpe) | - u32(ClapNoteDialect.midi2) - ) - // vfmt on - info.preferred_dialect = u32(ClapNoteDialect.clap) - - port_name := 'Example note port' - for i, chr in port_name { - info.name[i] = chr - } - info.name[port_name.len] = char(0) - - return true - } - } - } - clap_ext_gui { - return &C.clap_plugin_gui_t{ - is_api_supported: fn (clap_plugin &C.clap_plugin_t, api &char, is_floating bool) bool { - if is_floating { - return false - } - v_api := unsafe { cstring_to_vstring(api) } - // Only X11 for now. - return v_api == clap_window_api_x11 - } - get_preferred_api: fn (clap_plugin &C.clap_plugin_t, mut api voidptr, mut is_floating &bool) bool { - is_floating = false - api = unsafe { &clap_window_api_x11 } - return true - } - create: fn [mut mp] (clap_plugin &C.clap_plugin_t, api &char, is_floating bool) bool { - v_api := unsafe { cstring_to_vstring(api) } - if v_api != clap_window_api_x11 || is_floating { - return false - } - if !isnil(mp.gui) { - panic('GUI already initialised!') - } - mp.gui = GUI.create(vclap.gui_width, vclap.gui_height, plugin_name) - // Register the file descriptor we'll receive events from. - if !isnil(mp.host_posix_fd) && !isnil(mp.host_posix_fd.register_fd) { - mp.host_posix_fd.register_fd(mp.host, mp.gui.fd, ClapPosixFDFlags.read) - } - - return true - } - destroy: fn [mut mp] (clap_plugin &C.clap_plugin_t) { - if !isnil(mp.host_posix_fd) && !isnil(mp.host_posix_fd.unregister_fd) { - mp.host_posix_fd.unregister_fd(mp.host, mp.gui.fd) - } - if isnil(mp.gui) { - panic('GUI not initialised!') - } - mp.gui.destroy() - - unsafe { - mp.gui = nil - } - } - set_scale: fn (clap_plugin &C.clap_plugin_t, scale f64) bool { - return false - } - get_size: fn (clap_plugin &C.clap_plugin_t, mut width &u32, mut height &u32) bool { - width = vclap.gui_width - height = vclap.gui_height - return true - } - can_resize: fn (clap_plugin &C.clap_plugin_t) bool { - return false - } - get_resize_hints: fn (clap_plugin &C.clap_plugin_t, hints &C.clap_gui_resize_hints_t) bool { - return false - } - adjust_size: fn (clap_plugin &C.clap_plugin_t, mut width &u32, mut height &u32) bool { - width = vclap.gui_width - height = vclap.gui_height - return true - } - set_size: fn (clap_plugin &C.clap_plugin_t, width &u32, height &u32) bool { - return true - } - set_parent: fn [mut mp] (clap_plugin &C.clap_plugin_t, window &C.clap_window_t) bool { - v_wapi := unsafe { (&char(window.api)).vstring() } - assert v_wapi == clap_window_api_x11, 'Bad GUI API' - - mp.gui.set_parent(window.x11) - return true - } - set_transient: fn (clap_plugin &C.clap_plugin_t, window &C.clap_window_t) bool { - return false - } - suggest_title: fn (clap_plugin &C.clap_plugin_t, title &char) {} - show: fn [mp] (clap_plugin &C.clap_plugin_t) bool { - mp.gui.set_visible(true) - return true - } - hide: fn [mp] (clap_plugin &C.clap_plugin_t) bool { - mp.gui.set_visible(false) - return true - } - } - } - clap_ext_posix_fd_support { - return &C.clap_plugin_posix_fd_support_t{ - on_fd: fn [mp] (clap_plugin &C.clap_plugin_t, fd int, flags ClapPosixFDFlags) { - mp.gui.on_posix_fd() - } - } - } - else { - return unsafe { nil } - } - } -} - -fn (mp MinimalPlugin) on_main_thread(clap_plugin &C.clap_plugin_t) { -}