CLAP (Clever Audio Plugin)

repository·main·Indexed 25 days ago

https://github.com/free-audio/clap

A stable Application Binary Interface (ABI) designed to standardize communication between Digital Audio Workstations (DAWs) and audio plugins such as synthesizers and effects. It provides a C/C++ interface ensuring backwards compatibility, utilizing a system of extensions for specialized functionality like parameter management, audio ports, and rendering. The documentation covers the plugin entry point via clap_plugin_entry_t, extension lifecycles, and standard plugin search paths across Linux, Windows, and macOS.

Tokens
2K
Snippets
2
Records
9
Agent score
81%

What's inside CLAP

  1. Introduction to CLAP (Clever Audio Plugin)

    main

    CLAP is an interface providing a stable Application Binary Interface (ABI) for Digital Audio Workstations (DAWs) and audio plugins (synthesizers, effects, etc.) to communicate. The ABI ensures backwards compatibility: a plugin compiled with CLAP 1.x can be loaded by any CLAP 1.y host.

    To use CLAP in your C/C++ project:

    • Include clap/clap.h for the standard interface.
    • Include clap/all.h to also include draft extensions.

    The two primary objects in the CLAP ecosystem are clap_host and clap_plugin.

  2. Format Extension and Factory IDs

    main

    All extensions and factory IDs in CLAP must follow a specific naming convention to ensure uniqueness and versioning.

    Official CLAP Extensions

    For extensions officially published by the CLAP project, use the format: clap.$NAME/$REV

    • $NAME: The name of the extension.
    • $REV: An integer revision number that starts at 1 and increments with each iteration.

    Third-party Extensions

    For extensions created by third parties that are not officially published by the CLAP project, use a reverse URI to prevent collisions: $REVERSE_URI.$NAME/$REV

    • $REVERSE_URI: A reverse domain name (e.g., com.bitwig).
    • $NAME: The name of the extension.
    • $REV: An integer revision number starting at 1.
  3. How extensions work in CLAP

    main

    Most CLAP features are implemented as extensions, which are C interfaces. Extensions allow hosts and plugins to exchange specialized functionality.

    Accessing Extensions

    Extensions are retrieved via the .extension() method on either the clap_host or clap_plugin object using a specific extension identifier.

    Extension Structure

    Every extension consists of:

    • A header: #include <clap/ext/xxx.h>
    • An extension identifier: #define CLAP_EXT_XXX "clap/XXX"
    • Host interfaces: struct clap_host_xxx (if provided by the host)
    • Plugin interfaces: struct clap_plugin_xxx (if provided by the plugin)
    • Thread-specific method definitions.

    When creating custom extensions, ensure the identifier is unique and includes versioning to prevent ABI breakage. All strings used in CLAP must be valid UTF-8.

    // host extension
    const clap_host_log *log = host->extension(host, CLAP_EXT_LOG);
    if (log)
       log->log(host, CLAP_LOG_INFO, "Hello World! ;^)");
    
    // plugin extension
    const clap_plugin_params *params = plugin->extension(plugin, CLAP_EXT_PARAMS);
    if (params)
    {
       uint32_t paramsCount = params->count(plugin);
       // ...
    }
  4. Manage the Extension Draft Lifecycle

    main

    All extensions must pass through a draft phase before becoming stable.

    Draft Phase

    1. Place the extension in the include/clap/ext/draft/ folder.
    2. Include the extension in include/clap/all.h.

    Migrating from Draft to Stable

    When an extension is ready to move from draft to stable, follow these steps to ensure the Extension ID remains unchanged:

    1. Do not change the Extension ID.
    2. Move the extension's inclusion from include/clap/all.h to include/clap/clap.h.
  5. Reference of Fundamental CLAP Extensions

    main

    These extensions are essential for implementing a basic functional plugin:

    • state: Save and load plugin state.
    • state-context: Save/load state with additional context (preset, duplicate, project).
    • resource-directory (draft): Host-provided folder for plugin resources like multi-samples.
    • params: Parameter management.
    • note-ports: Define note ports.
    • audio-ports: Define audio ports.
      • surround: Inspect surround channel mapping.
      • ambisonic: Inspect ambisonic channel mapping.
      • configurable-audio-ports: Request plugin to apply a specific configuration.
      • audio-ports-config: List of pre-defined audio port configurations.
      • audio-ports-activation: Activate/deactivate specific audio ports.
      • extensible-audio-ports (draft): Allow host to add audio ports dynamically.
    • render: Realtime or offline rendering.
    • latency: Report plugin latency.
    • tail: Processing tail length.
    • gui: Generic GUI controller.
    • voice-info: Inform host of polyphonic voice count.
    • track-info: Provide track-specific information to the plugin.
    • tuning (draft): Host-provided microtuning.
    • triggers (draft): Stateless plugin triggers (similar to parameters).
  6. Reference of Support and Integration Extensions

    main

    Support Extensions

    Used for correctness, resource management, and logging:

    • thread-check: Check current thread for correctness validation.
    • thread-pool: Use the host's thread pool.
    • log: Aggregate plugin logs via the host.
    • timer-support: Register timer handlers.
    • posix-fd-support: Register I/O handlers.

    Deeper Host Integration

    Advanced features for tighter DAW integration:

    • remote-controls: Bank of controls for mapping to hardware (e.g., 8 knobs).
    • preset-discovery: Allow host to index plugin presets in native formats.
    • preset-load: Allow host to request a preset load.
    • param-indication: Notify plugin of physical control mappings or automation.
    • note-name: Assign names to notes (e.g., for drum machines).
    • transport-control (draft): Allow plugin to control host transport.
    • context-menu: Exchange context menu entries between host and plugin.
  7. Implement the CLAP plugin entry point

    main

    To create a CLAP plugin, you must export a clap_plugin_entry_t structure named clap_entry. This structure serves as the primary interface for the host to interact with your dynamic shared object (DSO).

    Your implementation must provide three core functions: init, deinit, and get_factory.

    Important Lifecycle Rules:

    • init must be called before any other CLAP-related function or symbol in the DSO.
    • init and deinit should be treated as potentially non-idempotent. As of CLAP 1.2.0, plugin authors must handle multiple calls to init before a deinit is called (e.g., by using a mutex and a reference counter).
    • init must be fast, must not display a GUI, and must not perform user interaction.
    • If init returns false, the host must not call deinit or any other symbols from the DSO.
    • get_factory is thread-safe and can be called simultaneously by multiple threads.
  8. Standard CLAP plugin search paths

    main

    Hosts look for .clap files in the following default locations depending on the operating system:

    Linux

    • ~/.clap
    • /usr/lib/clap

    Windows

    • %COMMONPROGRAMFILES%\CLAP
    • %LOCALAPPDATA%\Programs\Common\CLAP

    MacOS

    • /Library/Audio/Plug-Ins/CLAP
    • ~/Library/Audio/Plug-Ins/CLAP

    Custom Paths Hosts must also check the CLAP_PATH environment variable. This variable contains a list of directories separated by : on Unix or ; on Windows. Each directory is searched recursively for files or bundles ending in .clap.

  9. Use clap_plugin_entry_t to manage DSO lifecycle

    main

    The clap_plugin_entry_t struct defines the entry point interface for a CLAP plugin.

    Members

    • clap_version: Initialized to CLAP_VERSION to identify the version of the CLAP specification used.
    • init(const char *plugin_path):
      • Initializes the DSO.
      • plugin_path is the path to the DSO (Linux/Windows) or the bundle (macOS).
      • Returns true on success.
      • Must be called once before any other symbols.
      • Must be defensive against multiple calls before a deinit (use a mutex and counter).
    • deinit(void):
      • De-initializes the DSO and frees resources.
      • After calling deinit, the DSO is in the same state as if init had never been called.
    • get_factory(const char *factory_id):
      • Returns a pointer to a factory for the given factory_id.
      • Returns NULL if the factory is not provided.
      • The caller must not free the returned pointer.
      • This function is thread-safe.
    typedef struct clap_plugin_entry {
       clap_version_t clap_version;
       bool(CLAP_ABI *init)(const char *plugin_path);
       void(CLAP_ABI *deinit)(void);
       const void *(CLAP_ABI *get_factory)(const char *factory_id);
    } clap_plugin_entry_t;