From 16ea91a42195a56d6abf94b7fd9afecc9b0bb942 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 30 Sep 2024 03:09:28 -0400 Subject: [PATCH 1/8] Add a description of the expectation of request_callback timing (#422) * Add a description of the expectation of request_callback timing Without making a requirement, indicate the intent of the timing. * Add an apostrophe * Add host can starve feedback from alex * more review feedback * notjusthosts --- include/clap/host.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/clap/host.h b/include/clap/host.h index ddfeb8e7..c647c198 100644 --- a/include/clap/host.h +++ b/include/clap/host.h @@ -35,6 +35,12 @@ typedef struct clap_host { void(CLAP_ABI *request_process)(const struct clap_host *host); // Request the host to schedule a call to plugin->on_main_thread(plugin) on the main thread. + // This callback should be called as soon as practicable, usually in the host application's next + // available main thread time slice. Typically callbacks occur withink 33ms / 30hz. + // Despite this guidance, plugins should not make assumptions about the exactness of timing for + // a main thread callback, but hosts should endeavour to be prompt. For example, in high load situations + // the environment may starve the gui/main thread in favor of audio processing, leading to substantially + // longer latencies for the callback than the indicative times given here. // [thread-safe] void(CLAP_ABI *request_callback)(const struct clap_host *host); } clap_host_t; From 1d35ca1230e7763e02f83fee4d8a548b7e21340a Mon Sep 17 00:00:00 2001 From: Javantea Date: Thu, 24 Oct 2024 13:31:21 -0700 Subject: [PATCH 2/8] Fix abort on delete plugin from track FX. --- src/plugin-template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugin-template.c b/src/plugin-template.c index 8436815c..00f1ca3e 100644 --- a/src/plugin-template.c +++ b/src/plugin-template.c @@ -419,7 +419,7 @@ static void entry_deinit_guard(void) { #endif const int cnt = --g_entry_init_counter; - assert(cnt > 0); + assert(cnt >= 0); bool succeed = true; if (cnt == 0) From bcbf761efe35d36d8c7775058c2d8876abd4b1db Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Wed, 30 Oct 2024 08:50:41 -0400 Subject: [PATCH 3/8] Document the special lifetime of clap_event_midi_sysex::buffer per conversation on discord, oct 29 --- include/clap/events.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/include/clap/events.h b/include/clap/events.h index a6e97513..198c7222 100644 --- a/include/clap/events.h +++ b/include/clap/events.h @@ -297,11 +297,27 @@ typedef struct clap_event_midi { uint8_t data[3]; } clap_event_midi_t; +// clap_event_midi_sysex contains a pointer to a sysex contents buffer. +// The lifetime of this buffer is (from host->plugin) only the process +// call in which the event is delivered or (from plugin->host) only the +// duration of a try_push call. +// +// Since `clap_output_events.try_push` requires hosts to make a copy of +// an event, host implementers receiving sysex messages from plugins need +// to take care to both copy the event (so header, size, etc...) but +// also memcpy the contents of the sysex pointer to host-owned memory, and +// not just copy the data pointer. +// +// Similarly plugins retaining the sysex outside the lifetime of a single +// process call must copy the sysex buffer to plugin-owned memory. +// +// As a consequence, the data structure pointed to by the sysex buffer +// must be contiguous and copyable with `memcpy` of `size` bytes. typedef struct clap_event_midi_sysex { clap_event_header_t header; uint16_t port_index; - const uint8_t *buffer; // midi buffer + const uint8_t *buffer; // midi buffer. See lifetime comment above. uint32_t size; } clap_event_midi_sysex_t; From 9f90dc031396e954f11e25bd3ff973c833769e74 Mon Sep 17 00:00:00 2001 From: jatin Date: Tue, 8 Oct 2024 11:52:53 -0700 Subject: [PATCH 4/8] draft scratch-memory extension --- include/clap/all.h | 1 + include/clap/ext/draft/scratch-memory.h | 91 +++++++++++++++++++++++++ include/clap/plugin.h | 1 + 3 files changed, 93 insertions(+) create mode 100644 include/clap/ext/draft/scratch-memory.h diff --git a/include/clap/all.h b/include/clap/all.h index 2ce982a5..bfda937b 100644 --- a/include/clap/all.h +++ b/include/clap/all.h @@ -11,3 +11,4 @@ #include "ext/draft/triggers.h" #include "ext/draft/tuning.h" #include "ext/draft/undo.h" +#include "ext/draft/scratch-memory.h" diff --git a/include/clap/ext/draft/scratch-memory.h b/include/clap/ext/draft/scratch-memory.h new file mode 100644 index 00000000..556e5eab --- /dev/null +++ b/include/clap/ext/draft/scratch-memory.h @@ -0,0 +1,91 @@ +#pragma once + +#include "../../plugin.h" + +// This extension lets the plugin request "scratch" memory +// from the host. Scratch memory can be accessed during the +// `process()` callback, but its content not persistent +// between callbacks. +// +// The motivation for this extension is to allow the plugin host +// to "share" a single scratch buffer across multiple plugin +// instances. +// +// For example, imagine the host needs to process three plugins +// in sequence, and each plugin requires 10K of scratch memory. +// If each plugin pre-allocates its own scratch memory, then 30K +// of memory is being allocated in total. However, if each plugin +// requests 10K of scratch memory from the host, then the host can +// allocate a single 10K scratch buffer, and make it available to all +// three plugins. +// +// This optimization may allow for reduced memory usage and improved +// CPU cache usage. + +static CLAP_CONSTEXPR const char CLAP_EXT_SCRATCH_MEMORY[] = "clap.scratch-memory/1"; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clap_host_scratch_memory { + // Asks the host for certain amount of scratch memory. + // If the host is unable to provide the memory, it should + // return "false". + // + // The plugin may call this method multiple times (for + // example, gradually decreasing the amount of scratch + // being asked for until the host returns true), however, + // the plugin should avoid calling this method un-neccesarily + // since the host implementation may be relatively expensive. + // If the plugin calls `reserve()` multiple times, then the + // final call determines the actual amount of scratch memory + // that will be available to the plugin. If the final call + // returns false then no scratch memory will be provided, + // regardless of any previous calls to `reserve()`. + // + // When the plugin is de-activated, the scratch memory + // is invalidated, and the host may free the memory if + // appropriate. The plugin will need to reserve scratch + // memory again the next time it is activated. + // + // In the context of plugins and hosts that implement + // the "thread-pool" extension, scratch memory is assumed + // to be "thread-local". The plugin should request the maximum + // amount of scratch memory that it will need on a single + // thread. Accordingly, the host must ensure that each + // thread can independently provide the requested amount + // of scratch memory. + // + // [main-thread & being-activated] + bool(CLAP_ABI *reserve)(const clap_host_t *host, uint32_t scratch_size_bytes); + + // Asks the host for the previously reserved scratch memory. + // If the host returned "true" when scratch memory was requested, + // then this method must return a pointer to a memory block at least + // as large as the reserved size. If the host returned "false" + // when scratch memory was requested, then this method must not + // be called, and will return NULL. + // + // This method may only be called by the plugin from the audio thread, + // (i.e. during the process() or thread_pool.exec() callback), and + // the provided memory is only valid until the plugin returns from + // that callback. The plugin must not hold any references to data + // that lives in the scratch memory after returning from the callback, + // as that data will likely be over-written by another plugin using + // the same scratch memory. + // + // The provided memory is not initialized, and may have been used + // by other plugin instances, so the plugin must correctly initialize + // the memory when using it. + // + // The provided memory is owned by the host, so the plugin should not + // attempt to free the memory. + // + // [audio-thread] + void*(CLAP_ABI *access)(const clap_host_t *host); +} clap_host_scratch_memory_t; + +#ifdef __cplusplus +} +#endif diff --git a/include/clap/plugin.h b/include/clap/plugin.h index 7e83074b..0a239457 100644 --- a/include/clap/plugin.h +++ b/include/clap/plugin.h @@ -61,6 +61,7 @@ typedef struct clap_plugin { // In this call the plugin may allocate memory and prepare everything needed for the process // call. The process's sample rate will be constant and process's frame count will included in // the [min, max] range, which is bounded by [1, INT32_MAX]. + // In this call the plugin may call host-provided methods marked [being-activated]. // Once activated the latency and port configuration must remain constant, until deactivation. // Returns true on success. // [main-thread & !active] From 9adb31abee482b342bd4d9ed98e1db7dfb99f840 Mon Sep 17 00:00:00 2001 From: Eva Date: Sat, 16 Nov 2024 18:13:44 -0500 Subject: [PATCH 5/8] remove erroneous comment in ambisonic.h comment refered to a previous version of the ambisonic extension. --- include/clap/ext/ambisonic.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/clap/ext/ambisonic.h b/include/clap/ext/ambisonic.h index c9775171..8889904b 100644 --- a/include/clap/ext/ambisonic.h +++ b/include/clap/ext/ambisonic.h @@ -43,9 +43,6 @@ typedef struct clap_plugin_ambisonic { 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, From 820885c949c26d62a2b7aac528e9202bc73250b7 Mon Sep 17 00:00:00 2001 From: Roelof van Krimpen Date: Mon, 22 Apr 2024 12:59:26 +0200 Subject: [PATCH 6/8] Draft track-location --- include/clap/all.h | 1 + include/clap/color.h | 2 ++ include/clap/ext/draft/location.h | 51 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 include/clap/ext/draft/location.h diff --git a/include/clap/all.h b/include/clap/all.h index bfda937b..54bbfbc4 100644 --- a/include/clap/all.h +++ b/include/clap/all.h @@ -9,6 +9,7 @@ #include "ext/draft/resource-directory.h" #include "ext/draft/transport-control.h" #include "ext/draft/triggers.h" +#include "ext/draft/location.h" #include "ext/draft/tuning.h" #include "ext/draft/undo.h" #include "ext/draft/scratch-memory.h" diff --git a/include/clap/color.h b/include/clap/color.h index 3f643590..9da24fac 100644 --- a/include/clap/color.h +++ b/include/clap/color.h @@ -13,6 +13,8 @@ typedef struct clap_color { uint8_t blue; } clap_color_t; +static const CLAP_CONSTEXPR clap_color_t CLAP_COLOR_TRANSPARENT = { 0, 0, 0, 0 }; + #ifdef __cplusplus } #endif diff --git a/include/clap/ext/draft/location.h b/include/clap/ext/draft/location.h new file mode 100644 index 00000000..519c4e6c --- /dev/null +++ b/include/clap/ext/draft/location.h @@ -0,0 +1,51 @@ +#pragma once + +#include "../../plugin.h" +#include "../../color.h" + +// This extension allows a host to tell the plugin more about its position +// within a project or session. + +static CLAP_CONSTEXPR const char CLAP_EXT_LOCATION[] = "clap.location/1"; + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + CLAP_PLUGIN_LOCATION_PROJECT, + CLAP_PLUGIN_LOCATION_TRACK, + CLAP_PLUGIN_LOCATION_TRACK_GROUP, + CLAP_PLUGIN_LOCATION_DEVICE, + CLAP_PLUGIN_LOCATION_DEVICE_PARALLEL_GROUP, + CLAP_PLUGIN_LOCATION_DEVICE_SERIAL_GROUP, +}; + +typedef struct clap_plugin_location_element { + // Internal ID of the element. This is not intended for display to the user, + // but rather to give the host a potential quick way for lookups. + const char *id; + // User friendly name of the element. + const char *name; + // Kind of the element, must be one of the CLAP_PLUGIN_LOCATION_* values. + int kind; + // Index within the parent element. + uint32_t index_in_group; + // Color for this element, should be CLAP_COLOR_TRANSPARENT if no color is + // used for this element. + clap_color_t color; +} clap_plugin_location_element_t; + + +typedef struct clap_plugin_location { + // Called by the host when the location of the plugin instance changes. + // + // The last item in this array always refers to the device itself, and as + // such is expected to be of kind CLAP_PLUGIN_LOCATION_DEVICE. + // [main-thread] + void (*set_location)(clap_plugin_t *plugin, clap_plugin_location_element_t *path, int num_elements); +} clap_plugin_location_t; + +#ifdef __cplusplus +} +#endif From 3363912192c34e81b9fdbff09ed5201b9a613efe Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Mon, 18 Nov 2024 18:43:04 +0100 Subject: [PATCH 7/8] Update ChangeLog --- ChangeLog.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index c47a37dd..b0d1d05d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,20 @@ +# Changes in 1.2.3 + +## New draft extensions + +* [scratch-memory](include/clap/ext/draft/scratch-memory.h): host provided scratch memory within the process call +* [location](include/clap/ext/draft/location.h): better info about the plugin location within the project + +## Documention + +* [events.h](include/clap/events.h): clarify sysex lifetime +* [host.h](include/clap/host.h): clarify `request_callback()` +* [ambisonic.h](include/clap/ext/ambisonic.h): remove bad comment + +## Fixes + +* [plugin-template.c](src/plugin-template.c): fix bad assertion + # Changes in 1.2.2 * [thread-check.h](include/clap/ext/thread-check.h): expand the thread-doc to clarify and expand realtime From 702e51cb92a10a43168e304a129d982fa5e3cdc3 Mon Sep 17 00:00:00 2001 From: Alexandre Bique Date: Mon, 18 Nov 2024 18:44:07 +0100 Subject: [PATCH 8/8] CLAP 1.2.3 --- include/clap/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clap/version.h b/include/clap/version.h index d11069c1..78ac8b8c 100644 --- a/include/clap/version.h +++ b/include/clap/version.h @@ -22,7 +22,7 @@ typedef struct clap_version { #define CLAP_VERSION_MAJOR 1 #define CLAP_VERSION_MINOR 2 -#define CLAP_VERSION_REVISION 2 +#define CLAP_VERSION_REVISION 3 #define CLAP_VERSION_INIT \ { (uint32_t)CLAP_VERSION_MAJOR, (uint32_t)CLAP_VERSION_MINOR, (uint32_t)CLAP_VERSION_REVISION }