Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLAP 1.2.3 #432

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
17 changes: 17 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ and use to get a basic plugin experience:
- [clap-sys](https://github.com/glowcoil/clap-sys), rust binding
- [CLAP-for-Delphi](https://github.com/Bremmers/CLAP-for-Delphi), Delphi binding
- [clap-zig-bindings](https://sr.ht/~interpunct/clap-zig-bindings/), Zig bindings
## Artwork
Expand Down
2 changes: 2 additions & 0 deletions include/clap/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +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"
2 changes: 2 additions & 0 deletions include/clap/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
31 changes: 29 additions & 2 deletions include/clap/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ extern "C" {
#endif

// event header
// must be the first attribute of the event
// All clap events start with an event header to determine the overall
// size of the event and its type and space (a namespacing for types).
// clap_event objects are contiguous regions of memory which can be copied
// with a memcpy of `size` bytes starting at the top of the header. As
// such, be very careful when desiginig clap events with internal pointers
// and other non-value-types to consider the lifetime of those members.
typedef struct clap_event_header {
uint32_t size; // event size including this header, eg: sizeof (clap_event_note)
uint32_t time; // sample offset within the buffer for this event
Expand Down Expand Up @@ -266,6 +271,12 @@ enum clap_transport_flags {
CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL = 1 << 7,
};

// clap_event_transport provides song position, tempo, and similar information
// from the host to the plugin. There are two ways a host communicates these values.
// In the `clap_process` structure sent to each processing block, the host must
// provide a transport structure which indicates the available information at the
// start of the block. If the host provides sample-accurate tempo or transport changes,
// it can also provide subsequent inter-block transport updates by delivering a new event.
typedef struct clap_event_transport {
clap_event_header_t header;

Expand Down Expand Up @@ -297,11 +308,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;

Expand Down
3 changes: 0 additions & 3 deletions include/clap/ext/ambisonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
74 changes: 74 additions & 0 deletions include/clap/ext/draft/location.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#pragma once

#include "../../color.h"
#include "../../plugin.h"
#include "../../string-sizes.h"

// This extension allows a host to tell the plugin more about its position
// within a project or session.

static CLAP_CONSTEXPR const char CLAP_EXT_LOCATION[] = "clap.location/1";

#ifdef __cplusplus
extern "C" {
#endif

enum {
// Represents a document/project/session.
CLAP_PLUGIN_LOCATION_PROJECT = 1,
abique marked this conversation as resolved.
Show resolved Hide resolved

// Represents a group of tracks.
// It can contain track groups, tracks, and devices (post processing).
// The first device within a track group has the index of
// the last track or track group within this group + 1.
abique marked this conversation as resolved.
Show resolved Hide resolved
CLAP_PLUGIN_LOCATION_TRACK_GROUP = 2,

// Represents a single track.
// It contains devices (serial).
CLAP_PLUGIN_LOCATION_TRACK = 3,

// Represents a single device.
// It can contain other nested device chains.
CLAP_PLUGIN_LOCATION_DEVICE = 4,

// Represents a nested device chain (serial).
// Its parent must be a device.
// It contains other devices.
CLAP_PLUGIN_LOCATION_NESTED_DEVICE_CHAIN = 5,
abique marked this conversation as resolved.
Show resolved Hide resolved
};

typedef struct clap_plugin_location_element {
// Kind of the element, must be one of the CLAP_PLUGIN_LOCATION_* values.
uint32_t kind;

// Index within the parent element.
// Set to 0 if irrelevant.
uint32_t index;
abique marked this conversation as resolved.
Show resolved Hide resolved

// Internal ID of the element.
// This is not intended for display to the user,
// but rather to give the host a potential quick way for lookups.
char id[CLAP_PATH_SIZE];

// User friendly name of the element.
char name[CLAP_NAME_SIZE];

// Color for this element, 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(CLAP_ABI *set_location)(clap_plugin_t *plugin,
clap_plugin_location_element_t *path,
abique marked this conversation as resolved.
Show resolved Hide resolved
uint32_t num_elements);
} clap_plugin_location_t;

#ifdef __cplusplus
}
#endif
90 changes: 90 additions & 0 deletions include/clap/ext/draft/scratch-memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#pragma once

#include "../../plugin.h"

// This extension lets the plugin request "scratch" memory from the host.
//
// The scratch memory is thread-local, and can be accessed during
// `clap_plugin->process()` and `clap_plugin_thread_pool->exec()`;
// its content is not persistent between callbacks.
//
// The motivation for this extension is to allow the plugin host
// to "share" a single scratch buffer across multiple plugin
// instances.
//
// For example, imagine the host needs to process N plugins
// in sequence, and each plugin requires 10K of scratch memory.
// If each plugin pre-allocates its own scratch memory, then N * 10K
// of memory is being allocated in total. However, if each plugin
// requests 10K of scratch memory from the host, then the host can
// allocate a single 10K scratch buffer, and make it available to all
// plugins.
//
// This optimization may allow for reduced memory usage and improved
// CPU cache usage.

static CLAP_CONSTEXPR const char CLAP_EXT_SCRATCH_MEMORY[] = "clap.scratch-memory/1";

#ifdef __cplusplus
extern "C" {
#endif

typedef struct clap_host_scratch_memory {
// Asks the host to reserve scratch memory.
//
// The plugin may call this method multiple times (for
// example, gradually decreasing the amount of scratch
// being asked for until the host returns true), however,
// the plugin should avoid calling this method un-neccesarily
// since the host implementation may be relatively expensive.
// If the plugin calls `reserve()` multiple times, then the
// last call invalidates all previous calls.
//
// De-activating the plugin releases the scratch memory.
//
// `max_concurrency_hint` is an optional hint which indicates
// the maximum number of threads concurrently accessing the scratch memory.
// Set to 0 if unspecified.
//
// Returns true on success.
//
// [main-thread & being-activated]
bool(CLAP_ABI *reserve)(const clap_host_t *host,
uint32_t scratch_size_bytes,
uint32_t max_concurrency_hint);

// Returns a pointer to the "thread-local" scratch memory.
//
// If the scratch memory wasn't successfully reserved, returns NULL.
//
// If the plugin crosses `max_concurrency_hint`, then the return value
// is either NULL or a valid scratch memory pointer.
//
// This method may only be called by the plugin from the audio thread,
// (i.e. during the process() or thread_pool.exec() callback), and
// the provided memory is only valid until the plugin returns from
// that callback. The plugin must not hold any references to data
// that lives in the scratch memory after returning from the callback,
// as that data will likely be over-written by another plugin using
// the same scratch memory.
//
// The provided memory is not initialized, and may have been used
// by other plugin instances, so the plugin must correctly initialize
// the memory when using it.
//
// The provided memory is owned by the host, so the plugin must not
// free the memory.
//
// If the plugin wants to share the same scratch memory pointer with
// many threads, it must access the the scratch at the beginning of the
// `process()` callback, cache the returned pointer before calling
// `clap_host_thread_pool->request_exec()` and clear the cached pointer
// before returning from `process()`.
//
// [audio-thread]
void *(CLAP_ABI *access)(const clap_host_t *host);
} clap_host_scratch_memory_t;

#ifdef __cplusplus
}
#endif
11 changes: 9 additions & 2 deletions include/clap/ext/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
/// Embedding the window gives more control to the host, and feels more integrated.
/// Floating window are sometimes the only option due to technical limitations.
///
/// The Embedding protocol is by far the most common, supported by all hosts to date,
/// and a plugin author should support at least that case.
///
/// Showing the GUI works as follow:
/// 1. clap_plugin_gui->is_api_supported(), check what can work
/// 2. clap_plugin_gui->create(), allocates gui resources
Expand Down Expand Up @@ -85,7 +88,10 @@ typedef struct clap_gui_resize_hints {
bool can_resize_horizontally;
bool can_resize_vertically;

// only if can resize horizontally and vertically
// if both horizontal and vertical resize are available, do we preserve the
// aspect ratio, and if so, what is the width x height aspect ratio to preserve.
// These flags are unused if can_resize_horizontally or vertically are false,
// and ratios are unused if preserve is false.
bool preserve_aspect_ratio;
uint32_t aspect_ratio_width;
uint32_t aspect_ratio_height;
Expand All @@ -94,7 +100,8 @@ typedef struct clap_gui_resize_hints {
// 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
// Returns true if the requested gui api is supported, either in floating (plugin-created)
// or non-floating (embedded) mode.
// [main-thread]
bool(CLAP_ABI *is_api_supported)(const clap_plugin_t *plugin, const char *api, bool is_floating);

Expand Down
6 changes: 3 additions & 3 deletions include/clap/ext/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ typedef struct clap_param_info {
// '/' 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
double min_value; // Minimum plain value. Must be finite (`std::isfinite` true)
double max_value; // Maximum plain value. Must be finite
double default_value; // Default plain value. Must be in [min, max] range.
} clap_param_info_t;

typedef struct clap_plugin_params {
Expand Down
7 changes: 7 additions & 0 deletions include/clap/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ 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 within 33ms / 30hz.
// Despite this guidance, plugins should not make assumptions about the exactness of timing for
// a main thread callback, but hosts should endeavour to be prompt. For example, in high load
// situations the environment may starve the gui/main thread in favor of audio processing,
// leading to substantially longer latencies for the callback than the indicative times given
// here.
// [thread-safe]
void(CLAP_ABI *request_callback)(const struct clap_host *host);
} clap_host_t;
Expand Down
1 change: 1 addition & 0 deletions include/clap/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion include/clap/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
2 changes: 1 addition & 1 deletion src/plugin-template.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading