Skip to content

Commit

Permalink
Merge branch 'next' into draft-includes
Browse files Browse the repository at this point in the history
  • Loading branch information
abique authored Jan 8, 2024
2 parents e8591df + a44b93b commit dfcd4b5
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 102 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

Note: we kept the last draft extension ID in order to not break plugins already using it.

## Removed draft extensions

* `CLAP_EXT_CHECK_FOR_UPDATE` wasn't used and it's design needed more thought.
* `CLAP_EXT_MIDI_MAPPING` wasn't used. MIDI2 seems to do it better, and the interface wasn't satisfying.

## Stabilize factory
* `CLAP_PRESET_DISCOVERY_FACTORY_ID`

Expand Down
43 changes: 27 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- [Extensions](#extensions)
- [Fundamental extensions](#fundamental-extensions)
- [Support extensions](#support-extensions)
- [Extra extensions](#extra-extensions)
- [Deeper Host integration](#deeper-host-integration)
- [Third-party extensions](#third-party-extensions)
- [Adapters](#adapters)
- [Resources](#resources)
Expand Down Expand Up @@ -81,34 +81,45 @@ You can create your own extensions and share them. Make sure that the extension
This is a list of the extensions that you most likely want to implement
and use to get a basic plugin experience:
- [log](include/clap/ext/log.h), lets the host aggregate plugin logs
- [thread-check](include/clap/ext/thread-check.h), check which thread you are currently on, useful for correctness validation
- [audio-ports](include/clap/ext/audio-ports.h), define the audio ports
- [note-ports](include/clap/ext/note-ports.h), define the note ports
- [state](include/clap/ext/state.h), save and load the plugin state
- [state-context](include/clap/ext/state-context.h), same as state but with additional context info (preset, duplicate, project)
- [resource-directory](include/clap/ext/draft/resource-directory.h), host provided folder for the plugin to save extra resource like multi-samples, ... (draft)
- [params](include/clap/ext/params.h), parameters management
- [latency](include/clap/ext/latency.h), report the plugin latency
- [note-ports](include/clap/ext/note-ports.h), define the note ports
- [audio-ports](include/clap/ext/audio-ports.h), define the audio ports
- [surround](include/clap/ext/surround.h), inspect surround channel mapping
- [ambisonic](include/clap/ext/draft/ambisonic.h), inspect ambisonic channel mapping (draft)
- [cv](include/clap/ext/draft/cv.h), inspect CV channel mapping (draft)
- [configurable-audio-ports](include/clap/ext/configurable-audio-ports.h), request the plugin to apply a given configuration
- [audio-ports-config](include/clap/ext/audio-ports-config.h), simple list of pre-defined audio ports configurations
- [audio-ports-activation](include/clap/ext/audio-ports-activation.h), activate and deactivate a given audio port
- [extensible-audio-ports](include/clap/ext/draft/extensible-audio-ports.h), let the host add audio ports to the plugin, this is useful for dynamic number of audio inputs (draft)
- [render](include/clap/ext/render.h), renders realtime or offline
- [latency](include/clap/ext/latency.h), report the plugin latency
- [tail](include/clap/ext/tail.h), processing tail length
- [state](include/clap/ext/state.h), save and load the plugin state
- [gui](include/clap/ext/gui.h), generic gui controller
- [voice-info](include/clap/ext/voice-info.h), let the host know how many voices the plugin has, this is important for polyphonic modulations
- [track-info](include/clap/ext/track-info.h), give some info to the plugin about the track it belongs to
- [tuning](include/clap/ext/draft/tuning.h), host provided microtuning (draft)
- [triggers](include/clap/ext/draft/triggers.h), plugin's triggers, similar to parameters but stateless
## Support extensions
- [thread-check](include/clap/ext/thread-check.h), check which thread you are currently on, useful for correctness validation
- [thread-pool](include/clap/ext/thread-pool.h), use the host thread pool
- [log](include/clap/ext/log.h), lets the host aggregate plugin logs
- [timer-support](include/clap/ext/timer-support.h), lets the plugin register timer handlers
- [posix-fd-support](include/clap/ext/posix-fd-support.h), lets the plugin register I/O handlers
## Extra extensions
## Deeper Host integration
- [remote-controls](include/clap/ext/remote-controls.h), bank of controls that can be mapped on a controlles with 8 knobs
- [preset-discovery](include/clap/factory/preset-discovery.h), let the host index the plugin's preset in their native file format
- [preset-load](include/clap/ext/preset-load.h), let the host ask the plugin to load a preset
- [param-indication](include/clap/ext/param-indication.h), let the plugin know when a physical control is mapped to a parameter and if there is automation data
- [note-name](include/clap/ext/note-name.h), give a name to notes, useful for drum machines
- [tuning](include/clap/ext/draft/tuning.h), host provided microtuning
- [track-info](include/clap/ext/draft/track-info.h)
- [quick-controls](include/clap/ext/draft/quick-controls.h), bank of controls that can be mapped on a controlles with 8 knobs
- [file-reference](include/clap/ext/draft/file-reference.h), let the host know about the plugin's file reference, and perform "Collect & Save"
- [check-for-update](include/clap/ext/draft/check-for-update.h), check if there is a new version of a plugin
- [audio-ports-config](include/clap/ext/audio-ports-config.h), simple list of possible configurations
- [surround](include/clap/ext/draft/surround.h), inspect surround channel mapping
- [ambisonic](include/clap/ext/draft/ambisonic.h), inspect ambisonic channel mapping
- [transport-control](include/clap/ext/draft/transport-control.h), let the plugin control the host's transport (draft)
- [context-menu](include/clap/ext/context-menu.h), exchange context menu entries between host and plugin, let the plugin ask the host to popup its own context menu
## Third-party extensions
Expand Down
80 changes: 73 additions & 7 deletions include/clap/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,100 @@ extern "C" {
// Each directory should be recursively searched for files and/or bundles as appropriate in your OS
// ending with the extension `.clap`.
//
// Every method must be thread-safe.
// init and deinit in most cases are called once, in a matched pair, when the dso is loaded / unloaded.
// In some rare situations it may be called multiple times in a process, so the functions must be defensive,
// mutex locking and counting calls if undertaking non trivial non idempotent actions.
//
// Rationale:
//
// The intent of the init() and deinit() functions is to provide a "normal" initialization patterh
// which occurs when the shared object is loaded or unloaded. As such, hosts will call each once and
// in matched pairs. In clap specifications prior to 1.1.11, this single-call was documented as a
// requirement.
//
// We realized, though, that this is not a requirement hosts can meet. If hosts load a plugin
// which itself wraps another CLAP for instance, while also loading that same clap in its memory
// space, both the host and the wrapper will call init() and deinit() and have no means to communicate
// the state.
//
// With clap 1.1.11 and beyond we are changing the spec to indicate that a host should make an
// absolute best effort to call init() and deinit() once, and always in matched pairs (for every
// init() which returns true, one deinit() should be called).
//
// This takes the de-facto burden on plugin writers to deal with multiple calls into a hard requirement.
//
// Most init() / deinit() pairs we have seen are the relatively trivial {return true;} and {}. But
// if your init() function does non-trivial one time work, the plugin author must maintain a counter
// and must manage a mutex lock. The most obvious implementation will maintain a static counter and a
// global mutex, increment the counter on each init, decrement it on each deinit, and only undertake
// the init or deinit action when the counter is zero.
typedef struct clap_plugin_entry {
clap_version_t clap_version; // initialized to CLAP_VERSION

// This function must be called first, and can only be called once.
// Initializes the DSO.
//
// This function must be called first, before any-other CLAP-related function or symbol from this
// DSO.
//
// It also must only be called once, until a later call to deinit() is made, after which init()
// can be called once more to re-initialize the DSO.
// This enables hosts to e.g. quickly load and unload a DSO for scanning its plugins, and then
// load it again later to actually use the plugins if needed.
//
// As stated above, even though hosts are forbidden to do so directly, multiple calls before any
// deinit() call may still happen. Implementations *should* take this into account, and *must*
// do so as of CLAP 1.11.
//
// It should be as fast as possible, in order to perform a very quick scan of the plugin
// descriptors.
//
// It is forbidden to display graphical user interface in this call.
// It is forbidden to perform user interaction in this call.
// It is forbidden to display graphical user interfaces in this call.
// It is forbidden to perform any user interaction in this call.
//
// If the initialization depends upon expensive computation, maybe try to do them ahead of time
// and cache the result.
//
// If init() returns false, then the host must not call deinit() nor any other clap
// related symbols from the DSO.
// Returns true on success. If init() returns false, then the DSO must be considered
// uninitialized, and the host must not call deinit() nor any other CLAP-related symbols from the
// DSO.
// This function also returns true in the case where the DSO is already initialized, and no
// actual initialization work is done in this call, as explain above.
//
// plugin_path is the path to the DSO (Linux, Windows), or the bundle (macOS).
//
// This function may be called on any thread, including a different one from the one a later call
// to deinit() (or a later init()) can be made.
// However, it is forbidden to call this function simultaneously from multiple threads.
// It is also forbidden to call it simultaneously with *any* other CLAP-related symbols from the
// DSO, including (but not limited to) deinit().
bool(CLAP_ABI *init)(const char *plugin_path);

// No more calls into the DSO must be made after calling deinit().
// De-initializes the DSO, freeing any resources allocated or initialized by init().
//
// After this function is called, no more calls into the DSO must be made, except calling init()
// again to re-initialize the DSO.
// This means that after deinit() is called, the DSO can be considered to be in the same state
// as if init() was never called at all yet, enabling it to be re-initialized as needed.
//
// As stated above, even though hosts are forbidden to do so directly, multiple calls before any
// new init() call may still happen. Implementations *should* take this into account, and *must*
// do so as of CLAP 1.11.
//
// Just like init(), this function may be called on any thread, including a different one from
// the one init() was called from, or from the one a later init() call can be made.
// However, it is forbidden to call this function simultaneously from multiple threads.
// It is also forbidden to call it simultaneously with *any* other CLAP-related symbols from the
// DSO, including (but not limited to) deinit().
void(CLAP_ABI *deinit)(void);

// Get the pointer to a factory. See factory/plugin-factory.h for an example.
//
// Returns null if the factory is not provided.
// The returned pointer must *not* be freed by the caller.
//
// Unlike init() and deinit(), this function can be called simultaneously by multiple threads.
//
// [thread-safe]
const void *(CLAP_ABI *get_factory)(const char *factory_id);
} clap_plugin_entry_t;

Expand Down
32 changes: 0 additions & 32 deletions include/clap/ext/draft/check-for-update.h

This file was deleted.

41 changes: 0 additions & 41 deletions include/clap/ext/draft/midi-mappings.h

This file was deleted.

20 changes: 14 additions & 6 deletions include/clap/ext/state-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
/// on the context.
///
/// Briefly, when loading a preset or duplicating a device, the plugin may want to partially load
/// the state and initialize certain things differently.
/// the state and initialize certain things differently, like handling limited resources or fixed
/// connections to external hardware resources.
///
/// Save and Load operations may have a different context.
/// All three operations should be equivalent:
Expand All @@ -20,21 +21,28 @@
/// clap_plugin_state_context.save(CLAP_STATE_CONTEXT_FOR_PRESET),
/// CLAP_STATE_CONTEXT_FOR_PRESET)
///
/// If in doubt, fallback to clap_plugin_state.
///
/// If the plugin implements CLAP_EXT_STATE_CONTEXT then it is mandatory to also implement
/// CLAP_EXT_STATE.
///
/// It is unspecified which context is equivalent to clap_plugin_state.{save,load}()

#ifdef __cplusplus
extern "C" {
#endif

static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context.draft/1";
static CLAP_CONSTEXPR const char CLAP_EXT_STATE_CONTEXT[] = "clap.state-context/2";

enum clap_plugin_state_context_type {
// suitable for duplicating a plugin instance
CLAP_STATE_CONTEXT_FOR_DUPLICATE = 1,
// suitable for storing and loading a state as a preset
CLAP_STATE_CONTEXT_FOR_PRESET = 1,

// suitable for duplicating a plugin instance
CLAP_STATE_CONTEXT_FOR_DUPLICATE = 2,

// suitable for loading a state as a preset
CLAP_STATE_CONTEXT_FOR_PRESET = 2,
// suitable for storing and loading a state within a project/song
CLAP_STATE_CONTEXT_FOR_PROJECT = 3,
};

typedef struct clap_plugin_state_context {
Expand Down
4 changes: 4 additions & 0 deletions include/clap/ext/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
/// values and non-parameter state. This is used to persist a plugin's state
/// between project reloads, when duplicating and copying plugin instances, and
/// for host-side preset management.
///
/// If you need to know if the save/load operation is meant for duplicating a plugin
/// instance, for saving/loading a plugin preset or while saving/loading the project
/// then have a look at clap_plugin_state_context_t.

static CLAP_CONSTEXPR const char CLAP_EXT_STATE[] = "clap.state";

Expand Down

0 comments on commit dfcd4b5

Please sign in to comment.