Skip to content

About

No description or website provided.

Topics

Resources

Stars

100 stars

Watchers

8 watching

Forks

Repository files navigation

Example CLAP Plugins

This repo serves as an example to demonstrate how to create a CLAP plugin.


The GUI

The GUI is written with Dear ImGui, which is a submodule, and rendered in software into a pixel buffer. It doesn't need any library besides the system ones, nor any GPU context: each platform only has to show the pixels and to report the mouse events.

Platform Window API Embedded Floating
Linux X11 yes yes
Linux Wayland experimental, through the host's compositor (1) experimental (1)
Windows Win32 yes yes
macOS Cocoa yes yes

(1) With the extensions from clap-wayland-experiment, a submodule. Embedding uses the wayland-surface-embedding-v1 window API: the host runs a Wayland compositor of its own, and the plugin's surface goes into the host's window through it, with the clap_surface_embedding_v1 protocol. clap-gui-host doesn't test it yet.

Everything runs on the main thread. On Linux, the host's timer drives the GUI (clap.timer-support); on Windows and macOS, the window has its own timer.

The skins, one per plugin, are in skins.cc. The plugins without a skin show a knob per parameter.

To test the hosts, the check-* plugins support only one window API and mode each, and their GUI shows the window API, the mode, the scale and the size:

  • Linux: check-x11-floating, check-x11-embed, check-wayland-floating, check-wayland-embed
  • Windows: check-windows-floating, check-windows-embed
  • macOS: check-cocoa-floating, check-cocoa-embed

There is no keyboard input yet.

Notes on distributing a plugin

A CLAP plugin should be self-contained: it should not rely upon symbols from the host, and it should export only one symbol: clap_entry.

Even if you hide all your symbols, some may remain visible at unexpected places:

  • Objective-C registers every class, including those coming from plugins, in a flat namespace. If two plugins define different classes with the same name, they clash, which results in undefined behavior. That's why our NSView subclass is created at runtime, with a name unique to the plugin's binary.
  • Xlib's error handlers are process-wide, a plugin would replace the host's ones. That's why we use XCB on X11.
  • Wayland objects belong to a connection: the plugin opens its own one rather than sharing the host's. The host and the plugin only exchange strings, the xdg-foreign handle and the xdg-activation token, with the extensions from clap-wayland-experiment, a submodule.

Building

You need CMake 3.21 or newer, a C++20 compiler, and the submodules:

git clone --recurse-submodules https://github.com/free-audio/clap-plugins
cd clap-plugins

The plugins are then in builds/<preset>/plugins/Release/clap-plugins.clap.

Linux

The GUI needs libwayland-client 1.22 or newer, wayland-protocols 1.32 or newer, and libxcb, for example Ubuntu 24.04 or newer.

# on ubuntu, adapt to your distribution and package manager
sudo apt install git ninja-build cmake pkg-config g++ libwayland-dev wayland-protocols libxcb1-dev

# on archlinux, adapt to your distribution and package manager
sudo pacman -S git ninja cmake pkgconf gcc wayland wayland-protocols libxcb

cmake --preset ninja
cmake --build --preset ninja --config Release

macOS

Install the Xcode command line tools, then:

brew install cmake ninja

cmake --preset ninja
cmake --build --preset ninja --config Release

Windows

Install Visual Studio 2022, with its C++ and CMake components. Then in a PowerShell:

cmake --preset vs
cmake --build --preset vs --config Release

Without GUI

The ninja-headless and vs-headless presets build the plugins without GUI:

cmake --preset ninja-headless
cmake --build --preset ninja-headless --config Release

Tests

The unit tests need Catch2 3 or newer, and CLAP_BUILD_TESTS:

cmake --preset ninja -DCLAP_BUILD_TESTS=ON
cmake --build --preset ninja --config Release --target clap-tests
ctest --preset ninja -C Release

Installing

Copy clap-plugins.clap where the hosts look for plugins, for example ~/.clap on Linux, ~/Library/Audio/Plug-Ins/CLAP on macOS, or %LOCALAPPDATA%\Programs\Common\CLAP on Windows.

Trying the GUIs on Linux

clap-gui-host is a minimal host, which only shows a plugin's GUI. It prints the parameter changes.

builds/ninja/tools/gui-host/Release/clap-gui-host \
  builds/ninja/plugins/Release/clap-plugins.clap com.github.free-audio.clap.synth

By default it uses the plugin's preferred window API. The options:

  • --x11 or --wayland: the window API
  • --floating: a floating window rather than an embedded one; Wayland is always floating. Click in the host's window to show or hide the plugin's window.
  • --scale <factor>: the scale given to the plugin with X11. By default, like a real host, it gives the desktop's scale: Xft.dpi, or with XWayland, the ratio between the X11 screen and the Wayland outputs' logical layout. The plugins don't guess it: they use the host's. With Wayland, the sizes are logical and the host doesn't give the scale: the plugin gets it from the compositor.

Without a plugin id, it shows the gain plugin. With an unknown one, it lists the plugins.

About

No description or website provided.

Topics

Resources

Stars

100 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages