commit dc5d6e4c83db8081210e22bf074524a3935f8386
parent fa1af14290d7e00955b9c4bb5ea1c796fde81281
Author: Alexandre BIQUE <bique.alexandre@gmail.com>
Date: Wed, 28 Apr 2021 10:37:16 +0200
Better transport, faster plugin metadata scanning
Diffstat:
4 files changed, 200 insertions(+), 221 deletions(-)
diff --git a/.clang-format b/.clang-format
@@ -50,7 +50,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
-ColumnLimit: 80
+ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
diff --git a/include/clap/clap.h b/include/clap/clap.h
@@ -29,13 +29,15 @@
#include <stddef.h>
#include <stdint.h>
+#include "events.h"
+
#ifdef __cplusplus
extern "C" {
#endif
-#define CLAP_VERSION_MAKE(Major, Minor, Revision) \
+#define CLAP_VERSION_MAKE(Major, Minor, Revision) \
((((Major)&0xff) << 16) | (((Minor)&0xff) << 8) | ((Revision)&0xff))
-#define CLAP_VERSION CLAP_VERSION_MAKE(0, 3, 0)
+#define CLAP_VERSION CLAP_VERSION_MAKE(0, 4, 0)
#define CLAP_VERSION_MAJ(Version) (((Version) >> 16) & 0xff)
#define CLAP_VERSION_MIN(Version) (((Version) >> 8) & 0xff)
#define CLAP_VERSION_REV(Version) ((Version)&0xff)
@@ -59,180 +61,6 @@ typedef enum clap_string_size {
CLAP_NAME_SIZE = 64,
} clap_string_size;
-// Description of the plugin
-#define CLAP_ATTR_DESCRIPTION "clap/description"
-// Manufacturer name
-#define CLAP_ATTR_MANUFACTURER "clap/manufacturer"
-// Url to product
-#define CLAP_ATTR_URL "clap/url"
-// Url to support page, or mail to support
-#define CLAP_ATTR_SUPPORT "clap/support"
-
-////////////////
-// PARAMETERS //
-////////////////
-
-typedef union clap_param_value {
- bool b;
- double d;
- int64_t i;
-} clap_param_value;
-
-///////////////
-// TRANSPORT //
-///////////////
-
-typedef struct clap_loop_info {
- bool is_loop_active;
- double loop_start;
- double loop_end;
-} clap_loop_info;
-
-////////////
-// EVENTS //
-////////////
-
-typedef enum clap_event_type {
- CLAP_EVENT_NOTE_ON, // note attribute
- CLAP_EVENT_NOTE_OFF, // note attribute
- CLAP_EVENT_NOTE_EXPRESSION, // note_expression attribute
- CLAP_EVENT_CHOKE, // no attribute
- CLAP_EVENT_PARAM_SET, // param attribute
- CLAP_EVENT_JUMP, // jump attribute
- CLAP_EVENT_TEMPO, // tempo attribute
- CLAP_EVENT_PLAY, // is_playing attribute
- CLAP_EVENT_RECORD, // is_recording attribute
- CLAP_EVENT_TSIG, // tsig attribute
- CLAP_EVENT_CHORD, // chord attribute
-
- /* MIDI Style */
- CLAP_EVENT_PROGRAM, // program attribute
- CLAP_EVENT_MIDI, // midi attribute
- CLAP_EVENT_MIDI_SYSEX, // midi attribute
-} clap_event_type;
-
-/** Note On/Off event. */
-typedef struct clap_event_note {
- int32_t key; // 0..127
- int32_t channel; // 0..15
- double velocity; // 0..1
-} clap_event_note;
-
-typedef enum clap_note_expression {
- // TODO range, 20 * log(K * x)?
- CLAP_NOTE_EXPRESSION_VOLUME,
-
- // pan, -1 left, 1 right
- CLAP_NOTE_EXPRESSION_PAN,
-
- // relative tunind in semitone
- CLAP_NOTE_EXPRESSION_TUNING,
- CLAP_NOTE_EXPRESSION_VIBRATO,
- CLAP_NOTE_EXPRESSION_BRIGHTNESS,
- CLAP_NOTE_EXPRESSION_BREATH,
- CLAP_NOTE_EXPRESSION_PRUSSURE,
- CLAP_NOTE_EXPRESSION_TIMBRE,
-
- // TODO...
-} clap_note_expression;
-
-typedef struct clap_event_note_expression {
- clap_note_expression expression_id;
- int32_t key; // 0..127, or -1 to match all keys
- int32_t channel; // 0..15, or -1 to match all channels
- int32_t control; // 0..127
- double normalized_value; // see expression for the range
- double normalized_ramp;
-} clap_event_note_expression;
-
-typedef struct clap_event_param {
- int32_t key;
- int32_t channel;
- uint32_t index; // parameter index
- clap_param_value normalized_value;
- double normalized_ramp; // valid until the end of the block or the next event
-} clap_event_param;
-
-typedef struct clap_event_jump {
- double song_pos_beats; // position in beats
- double song_pos_seconds; // position in seconds
-
- double bar_start; // start pos of the current bar
- int32_t bar_number; // bar at song pos 0 has the number 0
-} clap_event_jump;
-
-typedef struct clap_event_tsig {
- int16_t num; // time signature numerator
- int16_t denom; // time signature denominator
-} clap_event_tsig;
-
-typedef struct clap_event_chord {
- // bitset of active keys:
- // - 11 bits
- // - root note is not part of the bitset
- // - bit N is: root note + N + 1
- // 0000 0000 0100 0100 -> minor chord
- // 0000 0000 0100 1000 -> major chord
- uint16_t note_mask;
- uint8_t root_note; // 0..11, 0 for C
-} clap_event_chord;
-
-typedef struct clap_event_midi {
- uint8_t data[4];
-} clap_event_midi;
-
-typedef struct clap_event_midi_sysex {
- const uint8_t *buffer; // midi buffer
- uint32_t size;
-} clap_event_midi_sysex;
-
-/**
- * Asks the plugin to load a program.
- * This is analogue to the midi program change.
- *
- * The main advantage of setting a program instead of loading
- * a preset, is that the program should already be in the plugin's
- * memory, and can be set instantly (no loading time).
- */
-typedef struct clap_event_program {
- int32_t channel; // 0..15, -1 unspecified
- int32_t bank_msb; // 0..0x7FFFFFFF, -1 unspecified
- int32_t bank_lsb; // 0..0x7FFFFFFF, -1 unspecified
- int32_t program; // 0..0x7FFFFFFF
-} clap_event_program;
-
-typedef struct clap_event {
- clap_event_type type;
- uint32_t time; // offset from the first sample in the process block
-
- union {
- clap_event_note note;
- clap_event_note_expression note_expression;
- clap_event_param param;
- clap_event_jump jump;
- clap_event_chord chord;
- double tempo;
- clap_event_tsig tsig;
- bool is_playing;
- bool is_recording;
- clap_event_program program;
- clap_event_midi midi;
- clap_event_midi_sysex midi_sysex;
- };
-} clap_event;
-
-typedef struct clap_event_list {
- void *ctx;
-
- uint32_t (*size)(const clap_event_list *list);
-
- // Don't free the return event, it belongs to the list
- const clap_event *(*get)(const clap_event_list *list, uint32_t index);
-
- // Makes a copy of the event
- void (*push_back)(const clap_event_list *list, const clap_event *event);
-} clap_event_list;
-
/////////////
// PROCESS //
/////////////
@@ -258,7 +86,7 @@ typedef struct clap_audio_buffer {
uint32_t latency; // latency from/to the audio interface
uint64_t constant_mask; // bitmask for each channel, 1 if the value is
// constant for the whole buffer
- const char *plugin_port_id; // optional, used for validation
+ uint32_t port_id;
} clap_audio_buffer;
typedef struct clap_process {
@@ -267,8 +95,6 @@ typedef struct clap_process {
bool has_transport; // if false then this is a free running host, no
// transport events will be provided
- clap_loop_info loop_info; // only valid if has_transport is true
-
// Audio buffers, they must have the same count as specified
// by clap_plugin_audio_ports->get_count().
// The index maps to clap_plugin_audio_ports->get_info().
@@ -301,10 +127,7 @@ typedef struct clap_host {
/* Returns the size of the original string. If this is larger than size, then
* the function did not have enough space to copy all the data.
* [thread-safe] */
- int32_t (*get_attribute)(clap_host * host,
- const char *attr,
- char * buffer,
- int32_t size);
+ int32_t (*get_attribute)(clap_host *host, const char *attr, char *buffer, int32_t size);
/* Query an extension.
* [thread-safe] */
@@ -334,22 +157,25 @@ typedef enum clap_plugin_type {
CLAP_PLUGIN_ANALYZER = (1 << 3),
} clap_plugin_type;
-typedef struct clap_plugin {
+typedef struct clap_plugin_descriptor {
int32_t clap_version; // initialized to CLAP_VERSION
- void *plugin_data; // reserved pointer for the plugin
-
- /* The 3 following strings are here because:
- * - they are mandatory
- * - it is convenient when you debug, to be able to see
- * the plugin name, id and version by displaying
- * the structure.
- */
- char name[CLAP_NAME_SIZE]; // plugin name, eg: "Diva"
- char id[CLAP_ID_SIZE]; // plugin id, eg: "com.u-he.diva"
- char version[CLAP_NAME_SIZE]; // the plugin version, eg: "1.3.2"
+ const char *id; // eg: "com.u-he.diva"
+ const char *name; // eg: "Diva"
+ 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"
uint64_t plugin_type; // bitfield of clap_plugin_type
+} clap_plugin_descriptor;
+
+typedef struct clap_plugin {
+ const clap_plugin_descriptor *desc;
+
+ void *plugin_data; // reserved pointer for the plugin
/* Free the plugin and its resources.
* It is not required to deactivate the plugin prior to this call. */
@@ -360,10 +186,7 @@ typedef struct clap_plugin {
* Returns the size of the original string or 0 if there is no
* value for this attributes.
* [thread-safe] */
- int32_t (*get_attribute)(clap_plugin *plugin,
- const char * attr,
- char * buffer,
- int32_t size);
+ int32_t (*get_attribute)(clap_plugin *plugin, const char *attr, char *buffer, int32_t size);
/* activation/deactivation
* [main-thread] */
@@ -372,14 +195,17 @@ typedef struct clap_plugin {
/* process audio, events, ...
* [audio-thread] */
- clap_process_status (*process)(clap_plugin * plugin,
- const clap_process *process);
+ clap_process_status (*process)(clap_plugin *plugin, const clap_process *process);
/* query an extension
* [thread-safe] */
const void *(*extension)(clap_plugin *plugin, const char *id);
} clap_plugin;
+/////////////////
+// ENTRY POINT //
+/////////////////
+
/* This interface is the entry point of the dynamic library.
*
* Every methods must be thread-safe. */
@@ -391,15 +217,17 @@ struct clap_plugin_entry {
* [thread-safe] */
int32_t (*get_plugin_count)(void);
- /* Create a clap_plugin by its index.
+ /* Retrieves a plugin descriptor by its index.
* Returns null in case of error.
+ * The descriptor does not need to be freed.
* [thread-safe] */
- clap_plugin *(*create_plugin_by_index)(clap_host *host, int32_t index);
+ const clap_plugin_descriptor *(*get_plugin_descriptor)(clap_host *host, int32_t index);
/* Create a clap_plugin by its plugin_id.
+ * The returned pointer must be freed by calling plugin->destroy(plugin);
* Returns null in case of error.
* [thread-safe] */
- clap_plugin *(*create_plugin_by_id)(clap_host *host, const char *plugin_id);
+ clap_plugin *(*create_plugin)(clap_host *host, const char *plugin_id);
};
/* Entry point */
diff --git a/include/clap/events.h b/include/clap/events.h
@@ -0,0 +1,156 @@
+#pragma once
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum clap_event_type {
+ CLAP_EVENT_NOTE_ON, // note attribute
+ CLAP_EVENT_NOTE_OFF, // note attribute
+ CLAP_EVENT_NOTE_EXPRESSION, // note_expression attribute
+ CLAP_EVENT_CHOKE, // no attribute
+ CLAP_EVENT_PARAM_SET, // param attribute
+ CLAP_EVENT_TIME_INFO, // time_info attribute
+ CLAP_EVENT_CHORD, // chord attribute
+
+ /* MIDI Style */
+ CLAP_EVENT_PROGRAM, // program attribute
+ CLAP_EVENT_MIDI, // midi attribute
+ CLAP_EVENT_MIDI_SYSEX, // midi attribute
+} clap_event_type;
+
+/** Note On/Off event. */
+typedef struct clap_event_note {
+ int32_t key; // 0..127
+ int32_t channel; // 0..15
+ double velocity; // 0..1
+} clap_event_note;
+
+typedef enum clap_note_expression {
+ // TODO range, 20 * log(K * x)?
+ CLAP_NOTE_EXPRESSION_VOLUME,
+
+ // pan, -1 left, 1 right
+ CLAP_NOTE_EXPRESSION_PAN,
+
+ // relative tunind in semitone
+ CLAP_NOTE_EXPRESSION_TUNING,
+ CLAP_NOTE_EXPRESSION_VIBRATO,
+ CLAP_NOTE_EXPRESSION_BRIGHTNESS,
+ CLAP_NOTE_EXPRESSION_BREATH,
+ CLAP_NOTE_EXPRESSION_PRUSSURE,
+ CLAP_NOTE_EXPRESSION_TIMBRE,
+
+ // TODO...
+} clap_note_expression;
+
+typedef struct clap_event_note_expression {
+ clap_note_expression expression_id;
+ int32_t key; // 0..127, or -1 to match all keys
+ int32_t channel; // 0..15, or -1 to match all channels
+ int32_t control; // 0..127
+ double normalized_value; // see expression for the range
+ double normalized_ramp;
+} clap_event_note_expression;
+
+typedef union clap_param_value {
+ bool b;
+ double d;
+ int64_t i;
+} clap_param_value;
+
+typedef struct clap_event_param {
+ int32_t key;
+ int32_t channel;
+ uint32_t index; // parameter index
+ clap_param_value normalized_value;
+ double normalized_ramp; // valid until the end of the block or the next event
+} clap_event_param;
+
+typedef struct clap_event_time_info {
+ double song_pos_beats; // position in beats
+ double song_pos_seconds; // position in seconds
+
+ double tempo; // in bpm
+ double tempo_ramp; // tempo increment for each samples and until the next
+ // time info event
+
+ double bar_start; // start pos of the current bar
+ int32_t bar_number; // bar at song pos 0 has the number 0
+
+ bool is_loop_active;
+ double loop_start; // in beats
+ double loop_end; // in beats
+
+ int16_t num; // time signature numerator
+ int16_t denom; // time signature denominator
+} clap_event_time_info;
+
+typedef struct clap_event_chord {
+ // bitset of active keys:
+ // - 11 bits
+ // - root note is not part of the bitset
+ // - bit N is: root note + N + 1
+ // 0000 0000 0100 0100 -> minor chord
+ // 0000 0000 0100 1000 -> major chord
+ uint16_t note_mask;
+ uint8_t root_note; // 0..11, 0 for C
+} clap_event_chord;
+
+typedef struct clap_event_midi {
+ uint8_t data[4];
+} clap_event_midi;
+
+typedef struct clap_event_midi_sysex {
+ const uint8_t *buffer; // midi buffer
+ uint32_t size;
+} clap_event_midi_sysex;
+
+/**
+ * Asks the plugin to load a program.
+ * This is analogue to the midi program change.
+ *
+ * The main advantage of setting a program instead of loading
+ * a preset, is that the program should already be in the plugin's
+ * memory, and can be set instantly (no loading time).
+ */
+typedef struct clap_event_program {
+ int32_t channel; // 0..15, -1 unspecified
+ int32_t bank_msb; // 0..0x7FFFFFFF, -1 unspecified
+ int32_t bank_lsb; // 0..0x7FFFFFFF, -1 unspecified
+ int32_t program; // 0..0x7FFFFFFF
+} clap_event_program;
+
+typedef struct clap_event {
+ clap_event_type type;
+ uint32_t time; // offset from the first sample in the process block
+
+ union {
+ clap_event_note note;
+ clap_event_note_expression note_expression;
+ clap_event_param param;
+ clap_event_time_info time_info;
+ clap_event_chord chord;
+ clap_event_program program;
+ clap_event_midi midi;
+ clap_event_midi_sysex midi_sysex;
+ };
+} clap_event;
+
+typedef struct clap_event_list {
+ void *ctx;
+
+ uint32_t (*size)(const clap_event_list *list);
+
+ // Don't free the return event, it belongs to the list
+ const clap_event *(*get)(const clap_event_list *list, uint32_t index);
+
+ // Makes a copy of the event
+ void (*push_back)(const clap_event_list *list, const clap_event *event);
+} clap_event_list;
+
+#ifdef __cplusplus
+}
+#endif
+\ No newline at end of file
diff --git a/include/clap/ext/audio-ports.h b/include/clap/ext/audio-ports.h
@@ -21,14 +21,14 @@ typedef enum clap_audio_port_channel_mapping {
} clap_audio_port_channel_mapping;
typedef struct clap_audio_port_info {
- char id[CLAP_ID_SIZE]; // stable identifier
- char name[CLAP_NAME_SIZE]; // displayable name
- bool is_main; // there can only be 1 main input and output
- bool is_cv; // control voltage
- bool supports_64_bits; // 32 bit support is mandatory, the host chooses
- // between 32 and 64.
- bool supports_in_place; // if true the daw can use the same buffer for input
- // and output, only for main input to main output
+ uint32_t id; // stable identifier
+ char name[CLAP_NAME_SIZE]; // displayable name
+ bool is_main; // there can only be 1 main input and output
+ bool is_cv; // control voltage
+ bool supports_64_bits; // 32 bit support is mandatory, the host chooses
+ // between 32 and 64.
+ bool supports_in_place; // if true the daw can use the same buffer for input
+ // and output, only for main input to main output
int32_t channel_count;
clap_audio_port_channel_mapping channel_mapping;
} clap_audio_port_info;
@@ -41,15 +41,9 @@ typedef struct clap_plugin_audio_ports {
// get info about about an audio port.
// [main-thread]
- void (*get_info)(clap_plugin * plugin,
- int32_t index,
- bool is_input,
- clap_audio_port_info *info);
+ void (*get_info)(clap_plugin *plugin, int32_t index, bool is_input, clap_audio_port_info *info);
- void (*activate_port)(clap_plugin *plugin,
- int32_t index,
- bool is_input,
- bool use_64);
+ void (*activate_port)(clap_plugin *plugin, int32_t index, bool is_input, bool use_64);
void (*deactivate_port)(clap_plugin *plugin, int32_t index, bool is_input);
// Returns the port latency.