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

Undo #334

Closed
wants to merge 10 commits into from
16 changes: 16 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# Changes in 1.1.10

* [surround.h](include/clap/ext/draft/surround.h): simplify the design
* [ambisonic.h](include/clap/ext/draft/ambisonic.h): simplify the design
* [configurable-audio-ports.h](include/clap/ext/draft/configurable-audio-ports.h): simplify the design
* [gui.h](include/clap/ext/gui.h): documentation clarifications
* [entry.h](include/clap/entry.h): documentation clarifications

## Draft extensions

* [undo.h](include/clap/ext/draft/undo.h): undo support

# Changes in 1.1.9

* [entry.h](include/clap/entry.h): clarify what the `plugin_path` is on macOS

# Changes in 1.1.8

* [params.h](include/clap/ext/params.h): document how persisting parameter values between sessions should be implemented
Expand Down
1 change: 1 addition & 0 deletions include/clap/clap.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@
#include "ext/draft/tuning.h"
#include "ext/draft/configurable-audio-ports.h"
#include "ext/draft/extensible-audio-ports.h"
#include "ext/draft/undo.h"
2 changes: 2 additions & 0 deletions include/clap/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ typedef struct clap_plugin_entry {
//
// 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().
Expand Down
19 changes: 12 additions & 7 deletions include/clap/ext/draft/ambisonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// 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/2";
static CLAP_CONSTEXPR const char CLAP_EXT_AMBISONIC[] = "clap.ambisonic.draft/3";

static CLAP_CONSTEXPR const char CLAP_PORT_AMBISONIC[] = "ambisonic";

Expand All @@ -28,21 +28,26 @@ enum {
CLAP_AMBISONIC_NORMALIZATION_N2D = 4,
};

typedef struct clap_ambisonic_info {
typedef struct clap_ambisonic_config {
uint32_t ordering;
uint32_t normalization;
} clap_ambisonic_info_t;
} 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_info)(const clap_plugin_t *plugin,
bool is_input,
uint32_t port_index,
clap_ambisonic_info_t *info);
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;

Expand Down
30 changes: 9 additions & 21 deletions include/clap/ext/draft/configurable-audio-ports.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ extern "C" {
// 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.draft0";
"clap.configurable-audio-ports.draft1";

typedef struct clap_audio_port_configuration_request {
// When true, allows the plugin to pick a similar port configuration instead
// if the requested one can't be applied.
bool is_best_effort;

// Identifies the port by is_input and port_index
bool is_input;
uint32_t port_index;
Expand All @@ -30,27 +26,19 @@ typedef struct clap_audio_port_configuration_request {
// - CLAP_PORT_MONO: (discard)
// - CLAP_PORT_STEREO: (discard)
// - CLAP_PORT_SURROUND: const uint8_t *channel_map
// - CLAP_PORT_AMBISONIC: const clap_ambisonic_info_t *info
// - 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 {
// Some ports may not be configurable, or simply the result of another port configuration.
// For example if you have a simple delay plugin, then the output port must have the exact
// same type as the input port; in that example, we consider the output port type to be a
// function (identity) of the input port type.
// [main-thread && !active]
bool(CLAP_ABI *is_port_configurable)(const clap_plugin_t *plugin,
bool is_input,
uint32_t port_index);

// Submit a bunch of configuration requests which will atomically be applied together,
// or discarded together.
// If is_dry_run is true, then checks if the configuration can be applied.
// If is_dry_run is false, then applies the configuration.
// Returns true if applied.
// [main-thread && !active]
bool(CLAP_ABI *request_configuration)(
const clap_plugin_t *plugin,
const struct clap_audio_port_configuration_request *requests,
uint32_t request_count);
bool(CLAP_ABI *apply_configuration)(const clap_plugin_t *plugin,
const struct clap_audio_port_configuration_request *requests,
uint32_t request_count,
bool is_dry_run);
} clap_plugin_configurable_audio_ports_t;

#ifdef __cplusplus
Expand Down
18 changes: 9 additions & 9 deletions include/clap/ext/draft/surround.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// 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/3";
static CLAP_CONSTEXPR const char CLAP_EXT_SURROUND[] = "clap.surround.draft/4";

static CLAP_CONSTEXPR const char CLAP_PORT_SURROUND[] = "surround";

Expand Down Expand Up @@ -54,21 +54,21 @@ enum {
};

typedef struct clap_plugin_surround {
// Stores into the channel_map array, the surround identifier of each channel.
// 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.
//
// 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.
// channel_map_capacity should 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);

// Informs the plugin that the host preferred channel map has changed.
// [main-thread]
void(CLAP_ABI *changed)(const clap_plugin_t *plugin);
} clap_plugin_surround_t;

typedef struct clap_host_surround {
Expand Down
63 changes: 63 additions & 0 deletions include/clap/ext/draft/undo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#pragma once

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

static CLAP_CONSTEXPR const char CLAP_EXT_UNDO[] = "clap.undo.draft/0";

// Describes an undo step
typedef struct clap_undo_info {
// This is the unique identifier of this undo step.
// It is valid until loading a state or destroying the plugin.
clap_id id;

// A short string which describes the corresponding change.
char description[CLAP_NAME_SIZE];
} clap_undo_info_t;

typedef struct clap_plugin_undo {
// returns true if an undo/redo step exists and the info were provided
// [main-thread]
bool (*get_current_undo_info)(clap_plugin_t *plugin, clap_undo_info_t *info);
bool (*get_current_redo_info)(clap_plugin_t *plugin, clap_undo_info_t *info);

// request the plugin to perform an undo operation (async)
// returns true if the request is being processed, false otherwise.
// when returning true, the plugin must call clap_host_undo->after_undo_request() once the
// request is completed or failed.
//
// The plugin should only perform the operation if the current
// undo/redo operation matches the given id; this is because of the asynchronous nature of the
// task and to avoid race conditions if the plugin's undo manager lives in a different thread.
//
// [main-thread]
bool (*request_undo)(clap_plugin_t *plugin, clap_id id);
bool (*request_redo)(clap_plugin_t *plugin, clap_id id);
} clap_plugin_undo_t;

typedef struct clap_host_undo {
// Marks the begining and end of a change which will lead to the creation of an undo step.
// [main-thread]
void (*begin_changes)(clap_host_t *host, const clap_undo_info_t *info);
void (*end_changes)(clap_host_t *host, const clap_undo_info_t *info);

// Marks the beginning and end of processing an undo change.
// [main-thread]
void (*begin_undo)(clap_host_t *host, const clap_undo_info_t *info);
void (*end_undo)(clap_host_t *host, const clap_undo_info_t *info);

// Marks the beginning and end of processing a redo change.
// [main-thread]
void (*begin_redo)(clap_host_t *host, const clap_undo_info_t *info);
void (*end_redo)(clap_host_t *host, const clap_undo_info_t *info);

// A destructive change happened which makes it impossible to perform an undo.
// The entire plugin's undo/redo stack has been cleared.
// [main-thread]
void (*after_destructive_change)(clap_host_t *host);

// Callbacks for clap_plugin_undo->request_*()
// [main-thread]
void (*after_undo_request)(clap_host_t *host, clap_id id, bool succeed, const char *error_msg);
void (*after_redo_request)(clap_host_t *host, clap_id id, bool succeed, const char *error_msg);
} clap_host_undo_t;
17 changes: 7 additions & 10 deletions include/clap/ext/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,28 +147,25 @@ typedef struct clap_plugin_gui {
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).
// Only for embedded windows.
// [main-thread]
// [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]
// [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.
//
// Only for embedded windows.
//
// Returns true if the plugin could adjust the given size.
// [main-thread]
// [main-thread & !floating]
bool(CLAP_ABI *adjust_size)(const clap_plugin_t *plugin, uint32_t *width, uint32_t *height);

// Sets the window size. Only for embedded windows.
// Sets the window size.
//
// Returns true if the plugin could resize its window to the given size.
// [main-thread]
// [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.
Expand Down Expand Up @@ -204,7 +201,7 @@ typedef struct clap_plugin_gui {

typedef struct clap_host_gui {
// The host should call get_resize_hints() again.
// [thread-safe]
// [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.
Expand All @@ -215,7 +212,7 @@ typedef struct clap_host_gui {
* 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] */
* [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.
Expand Down