Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* [plugin.h](include/clap/plugin.h): clarify activate/deactivate and start/stop processing
* [host.h](include/clap/host.h): clarify request_callback() when called from the main-thread
* [meters.h](include/clap/ext/draft/meters.h): new extension to let the plugin expose its meters (gain reduction, levels, ...) to the host, readable from any thread.

# Changes in 1.2.10

Expand Down
1 change: 1 addition & 0 deletions include/clap/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ext/draft/extensible-audio-ports.h"
#include "ext/draft/flush-events.h"
#include "ext/draft/gain-adjustment-metering.h"
#include "ext/draft/meters.h"
#include "ext/draft/mini-curve-display.h"
#include "ext/draft/octave-number.h"
#include "ext/draft/params-origin.h"
Expand Down
125 changes: 125 additions & 0 deletions include/clap/ext/draft/meters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#pragma once

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

// This extension lets the plugin expose its meters to the host: gain reduction, input and output
// levels, and so on, each with one or more channels.
//
// The host can display them in its mixer, or map them to a control surface, without opening the
// plugin's GUI. The values can be read from any thread, so the host can poll them at its own
// display rate.
//
// A plugin with a single gain reduction value should also implement
// clap.gain-adjustment-metering; a gain reduction meter here uses the same sign.

static CLAP_CONSTEXPR const char CLAP_EXT_METERS[] = "clap.meters/1";

#ifdef __cplusplus
extern "C" {
#endif

enum clap_meter_kind {
// The meter doesn't fit any other kind. Its unit is unspecified and the host should only
// rely on clap_meter_info.min_value and max_value to display it.
CLAP_METER_KIND_OTHER = 0,

// Gain adjustment in dB, with the same sign as clap.gain-adjustment-metering:
// zero means no gain reduction, a negative value means the plugin is reducing the gain,
// as with a compressor or limiter, and a positive value means it is adding gain, as with
// an expander.
CLAP_METER_KIND_GAIN_REDUCTION = 1,

// Signal level in dBFS. Silence may be reported as -infinity or as any value below
// clap_meter_info.min_value.
CLAP_METER_KIND_LEVEL = 2,

// Note: more entries could be added here in the future
};

enum clap_meter_flags {
// A promise by the plugin: all the values one get_values() call returns come from the same
// processed block. Without this flag each value is read on its own and two channels may
// come from neighbouring blocks, which is fine for level bars but not for a value derived
// from several channels, such as a correlation or a balance.
//
// To keep the promise without blocking either thread, the plugin keeps a few copies of the
// meter's value array and one atomic index naming the current one: after each block the
// audio thread fills a copy no reader can hold and then stores the index; get_values()
// loads the index and copies that array. Three copies make both sides wait-free.
CLAP_METER_IS_COHERENT = 1 << 0,
};

typedef struct clap_meter_info {
// Stable meter identifier, it must never change.
clap_id id;

// Displayable name, eg: "Gain Reduction", "Input", "Output".
char name[CLAP_NAME_SIZE];

// see enum clap_meter_kind
uint32_t kind;

// bitmask of clap_meter_flags
uint32_t flags;

// Number of values the meter has, eg: 1 for a linked gain reduction, 2 for a stereo level.
uint32_t channel_count;

// Display range suggested by the plugin, in the meter's unit.
double min_value;
double max_value;
} clap_meter_info_t;

typedef struct clap_plugin_meters {
// Returns the number of meters.
// [main-thread]
uint32_t(CLAP_ABI *count)(const clap_plugin_t *plugin);

// Copies the meter's info to meter_info and returns true on success.
// [main-thread]
bool(CLAP_ABI *get_info)(const clap_plugin_t *plugin,
uint32_t index,
clap_meter_info_t *meter_info);

// Copies the latest values of the meter meter_id into values, one per channel, up to
// capacity values, and returns the number of values written.
//
// The values are the ones the plugin would show on its own meters for the most recently
// processed block, ballistics included. Reading them must not change them: several readers
// may poll the same meter.
//
// Unless the meter has CLAP_METER_IS_COHERENT, the values of one call may come from
// different blocks: each is read on its own, and a stereo pair can be one block apart.
// A plugin that needs its channels together publishes them as one block and sets the flag;
// the host never synchronises, it only copies.
//
// After processing stops the plugin keeps returning the last values it computed, until
// deactivate(); after activation and before the first process() it returns 0.
//
// Returns 0 if meter_id is unknown, or if the plugin is not active or has not processed
// any block since it was activated.
//
// This function must be lock-free and wait-free, as it can be called concurrently with
// process(), for example from a GUI or a network thread of the host.
// [thread-safe]
uint32_t(CLAP_ABI *get_values)(const clap_plugin_t *plugin,
clap_id meter_id,
double *values,
uint32_t capacity);
} clap_plugin_meters_t;

typedef struct clap_host_meters {
// Informs the host that the list of meters or their info changed.
// The host will call count() and get_info() again.
//
// The list can only change while the plugin is deactivated. If the plugin is activated, it
// must call clap_host->request_restart() and delay the change until the host calls
// clap_plugin->deactivate().
// [main-thread & !active]
void(CLAP_ABI *changed)(const clap_host_t *host);
} clap_host_meters_t;

#ifdef __cplusplus
}
#endif