commit 63862e945204b2b10a307e311b2ff9786fa19bee
parent 2f909c9fe16c9bcff2617ac395eb222809f1973a
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date: Tue, 9 Dec 2014 20:12:09 +0100
Update the spec
Diffstat:
4 files changed, 579 insertions(+), 648 deletions(-)
diff --git a/include/clap/clap.h b/include/clap/clap.h
@@ -299,7 +299,8 @@ struct clap_plugin
void *host_data; // reserved pointer for the host
void *plugin_data; // reserved pointer for the plugin
- /* Free the plugin and its resources. */
+ /* Free the plugin and its resources.
+ * It is not required to deactivate the plugin prior to this call. */
void (*destroy)(struct clap_plugin *plugin);
/* Copy at most size of the attribute's value into buffer.
@@ -332,7 +333,9 @@ typedef struct clap_plugin *(*clap_create_f)(uint32_t plugin_index,
/* Plugin entry point. If plugins_count is not null, then clap_create has
* to store the number of plugins available in *plugins_count.
* If clap_create failed to create a plugin, it returns NULL.
- * The return value has to be freed by calling plugin->destroy(plugin). */
+ * The return value has to be freed by calling plugin->destroy(plugin).
+ *
+ * This function must be thread-safe. */
struct clap_plugin *
clap_create(uint32_t plugin_index,
struct clap_host *host,
diff --git a/include/clap/ext/ports.h b/include/clap/ext/ports.h
@@ -38,19 +38,19 @@ struct clap_ports_config
struct clap_plugin_ports
{
/* Returns the number of available configurations */
- uint32_t (*get_ports_configs_count)(struct clap_plugin *plugin);
- bool (*get_ports_config)(struct clap_plugin *plugin,
- uint32_t config_index,
- struct clap_ports_config *config);
- bool (*get_port_info)(struct clap_plugin *plugin,
- uint32_t config_index,
- uint32_t port_index,
- struct clap_port_info *port);
- bool (*set_ports_config)(struct clap_plugin *plugin,
- uint32_t config_index);
- bool (*set_port_repeat)(struct clap_plugin *plugin,
- uint32_t port_index,
- uint32_t count);
+ uint32_t (*get_configs_count)(struct clap_plugin *plugin);
+ bool (*get_config)(struct clap_plugin *plugin,
+ uint32_t config_index,
+ struct clap_ports_config *config);
+ bool (*get_info)(struct clap_plugin *plugin,
+ uint32_t config_index,
+ uint32_t port_index,
+ struct clap_port_info *port);
+ bool (*set_config)(struct clap_plugin *plugin,
+ uint32_t config_index);
+ bool (*set_repeat)(struct clap_plugin *plugin,
+ uint32_t port_index,
+ uint32_t count);
};
#endif /* !CLAP_EXT_PORT_H */
diff --git a/spec.html b/spec.html
@@ -108,85 +108,85 @@ tt.docutils {
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#goals" id="id2">Goals</a><ul>
-<li><a class="reference internal" href="#later-goals" id="id3">Later goals</a></li>
-<li><a class="reference internal" href="#design-choice" id="id4">Design choice</a></li>
+<li><a class="reference internal" href="#design-choice" id="id3">Design choice</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#specification" id="id5">Specification</a><ul>
-<li><a class="reference internal" href="#how-to-read-the-specification" id="id6">How to read the specification</a></li>
-<li><a class="reference internal" href="#encoding" id="id7">Encoding</a></li>
-<li><a class="reference internal" href="#plugins-location" id="id8">Plugins location</a><ul>
-<li><a class="reference internal" href="#common" id="id9">Common</a></li>
-<li><a class="reference internal" href="#linux" id="id10">Linux</a></li>
-<li><a class="reference internal" href="#windows" id="id11">Windows</a></li>
-<li><a class="reference internal" href="#mac" id="id12">Mac</a></li>
-<li><a class="reference internal" href="#multi-architecture-conventions" id="id13">Multi-architecture conventions</a></li>
+<li><a class="reference internal" href="#specification" id="id4">Specification</a><ul>
+<li><a class="reference internal" href="#how-to-read-the-specification" id="id5">How to read the specification</a></li>
+<li><a class="reference internal" href="#encoding" id="id6">Encoding</a></li>
+<li><a class="reference internal" href="#plugins-location" id="id7">Plugins location</a><ul>
+<li><a class="reference internal" href="#common" id="id8">Common</a></li>
+<li><a class="reference internal" href="#linux" id="id9">Linux</a></li>
+<li><a class="reference internal" href="#windows" id="id10">Windows</a></li>
+<li><a class="reference internal" href="#mac" id="id11">Mac</a></li>
+<li><a class="reference internal" href="#multi-architecture-conventions" id="id12">Multi-architecture conventions</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#instantiate-a-plugin" id="id14">Instantiate a plugin</a><ul>
-<li><a class="reference internal" href="#precautions" id="id15">Precautions</a></li>
+<li><a class="reference internal" href="#instantiate-a-plugin" id="id13">Instantiate a plugin</a><ul>
+<li><a class="reference internal" href="#precautions" id="id14">Precautions</a></li>
+<li><a class="reference internal" href="#release-a-plugin" id="id15">Release a plugin</a></li>
<li><a class="reference internal" href="#plugins-collection" id="id16">Plugins collection</a><ul>
<li><a class="reference internal" href="#sample-plugin-loader" id="id17">Sample plugin loader</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#description" id="id18">Description</a></li>
+<li><a class="reference internal" href="#plugin-description" id="id18">Plugin description</a></li>
<li><a class="reference internal" href="#audio-ports-configuration" id="id19">Audio ports configuration</a><ul>
<li><a class="reference internal" href="#pin-layout" id="id20">Pin layout</a></li>
-<li><a class="reference internal" href="#available-configurations" id="id21">Available configurations</a></li>
-<li><a class="reference internal" href="#selecting-a-configuration" id="id22">Selecting a configuration</a></li>
-<li><a class="reference internal" href="#repeatable-channels" id="id23">Repeatable channels</a></li>
-<li><a class="reference internal" href="#feedback-stream" id="id24">Feedback stream</a></li>
+<li><a class="reference internal" href="#configurations" id="id21">Configurations</a></li>
+<li><a class="reference internal" href="#getting-the-ports-configurations" id="id22">Getting the ports configurations</a></li>
+<li><a class="reference internal" href="#selecting-a-configuration" id="id23">Selecting a configuration</a></li>
+<li><a class="reference internal" href="#repeatable-channels" id="id24">Repeatable channels</a></li>
</ul>
</li>
</ul>
</li>
-<li><a class="reference internal" href="#threading" id="id25">Threading</a></li>
-<li><a class="reference internal" href="#activation" id="id26">Activation</a></li>
-<li><a class="reference internal" href="#processing" id="id27">Processing</a><ul>
-<li><a class="reference internal" href="#audio-buffers" id="id28">Audio buffers</a></li>
-<li><a class="reference internal" href="#events" id="id29">Events</a><ul>
-<li><a class="reference internal" href="#notes" id="id30">Notes</a></li>
-<li><a class="reference internal" href="#parameters" id="id31">Parameters</a></li>
-<li><a class="reference internal" href="#pitch" id="id32">Pitch</a></li>
+<li><a class="reference internal" href="#activation" id="id25">Activation</a></li>
+<li><a class="reference internal" href="#processing" id="id26">Processing</a><ul>
+<li><a class="reference internal" href="#audio-buffers" id="id27">Audio buffers</a></li>
+<li><a class="reference internal" href="#events" id="id28">Events</a><ul>
+<li><a class="reference internal" href="#notes" id="id29">Notes</a></li>
+<li><a class="reference internal" href="#parameters" id="id30">Parameters</a></li>
+<li><a class="reference internal" href="#pitch" id="id31">Pitch</a></li>
</ul>
</li>
</ul>
</li>
-<li><a class="reference internal" href="#id1" id="id33">Parameters</a><ul>
-<li><a class="reference internal" href="#types" id="id34">Types</a></li>
-<li><a class="reference internal" href="#scales" id="id35">Scales</a></li>
-<li><a class="reference internal" href="#automation" id="id36">Automation</a></li>
+<li><a class="reference internal" href="#id1" id="id32">Parameters</a><ul>
+<li><a class="reference internal" href="#types" id="id33">Types</a></li>
+<li><a class="reference internal" href="#scales" id="id34">Scales</a></li>
+<li><a class="reference internal" href="#automation" id="id35">Automation</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#graphical-user-interface" id="id37">Graphical User Interface</a><ul>
-<li><a class="reference internal" href="#showing-the-gui" id="id38">Showing the GUI</a></li>
-<li><a class="reference internal" href="#sending-events-to-the-host" id="id39">Sending events to the host</a></li>
-<li><a class="reference internal" href="#hiding-the-gui" id="id40">Hiding the GUI</a></li>
-<li><a class="reference internal" href="#embedding" id="id41">Embedding</a><ul>
-<li><a class="reference internal" href="#example-on-windows" id="id42">Example on Windows</a></li>
-<li><a class="reference internal" href="#resizing-the-window" id="id43">Resizing the window</a></li>
+<li><a class="reference internal" href="#graphical-user-interface" id="id36">Graphical User Interface</a><ul>
+<li><a class="reference internal" href="#showing-the-gui" id="id37">Showing the GUI</a></li>
+<li><a class="reference internal" href="#sending-events-to-the-host" id="id38">Sending events to the host</a></li>
+<li><a class="reference internal" href="#hiding-the-gui" id="id39">Hiding the GUI</a></li>
+<li><a class="reference internal" href="#embedding" id="id40">Embedding</a><ul>
+<li><a class="reference internal" href="#example-on-windows" id="id41">Example on Windows</a></li>
+<li><a class="reference internal" href="#resizing-the-window" id="id42">Resizing the window</a></li>
</ul>
</li>
</ul>
</li>
-<li><a class="reference internal" href="#presets" id="id44">Presets</a><ul>
-<li><a class="reference internal" href="#list-plugin-s-presets" id="id45">List plugin's presets</a></li>
-<li><a class="reference internal" href="#load-a-preset" id="id46">Load a preset</a></li>
+<li><a class="reference internal" href="#presets" id="id43">Presets</a><ul>
+<li><a class="reference internal" href="#list-plugin-s-presets" id="id44">List plugin's presets</a></li>
+<li><a class="reference internal" href="#load-a-preset" id="id45">Load a preset</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#save-and-restore-plugin-s-state" id="id47">Save and restore plugin's state</a></li>
-<li><a class="reference internal" href="#extension-system" id="id48">Extension system</a></li>
+<li><a class="reference internal" href="#save-and-restore-plugin-s-state" id="id46">Save and restore plugin's state</a></li>
+<li><a class="reference internal" href="#extension-system" id="id47">Extension system</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#examples" id="id49">Examples</a><ul>
-<li><a class="reference internal" href="#examples-clap-info-clap-info-c" id="id50">examples/clap-info/clap-info.c</a></li>
+<li><a class="reference internal" href="#examples" id="id48">Examples</a><ul>
+<li><a class="reference internal" href="#examples-clap-info-clap-info-c" id="id49">examples/clap-info/clap-info.c</a></li>
</ul>
</li>
-<li><a class="reference internal" href="#references" id="id51">References</a><ul>
-<li><a class="reference internal" href="#clap-h" id="id52">clap.h</a></li>
-<li><a class="reference internal" href="#clap-embed-h" id="id53">clap-embed.h</a></li>
-<li><a class="reference internal" href="#clap-embed-win32-h" id="id54">clap-embed-win32.h</a></li>
-<li><a class="reference internal" href="#clap-embed-xlib-h" id="id55">clap-embed-xlib.h</a></li>
+<li><a class="reference internal" href="#references" id="id50">References</a><ul>
+<li><a class="reference internal" href="#clap-clap-h" id="id51">clap/clap.h</a></li>
+<li><a class="reference internal" href="#clap-ext-ports-h" id="id52">clap/ext/ports.h</a></li>
+<li><a class="reference internal" href="#clap-ext-embed-h" id="id53">clap/ext/embed.h</a></li>
+<li><a class="reference internal" href="#clap-ext-embed-win32-h" id="id54">clap/ext/embed-win32.h</a></li>
+<li><a class="reference internal" href="#clap-ext-embed-xlib-h" id="id55">clap/ext/embed-xlib.h</a></li>
</ul>
</li>
</ul>
@@ -194,84 +194,62 @@ tt.docutils {
<div class="section" id="goals">
<h1><a class="toc-backref" href="#id2">Goals</a></h1>
<ul class="simple">
-<li>Make a free audio plugin format</li>
+<li>Make a free digital instrument and effect plugin format</li>
<li>Be easy to understand and implement</li>
<li>Bring new features missed in VST 2.4</li>
-<li>Designed to work on any operating system</li>
+<li>Designed to work on any operating system and processor architecture</li>
<li>Be event oriented</li>
-<li>Be extensible without breaking existing plugins</li>
+<li>Be extensible without breaking existing interface</li>
<li>Be easy to bridge</li>
+<li>Support dynamic configuration: let a modular plugin dynamically
+add new parameters, new outputs/inputs, etc...</li>
</ul>
-<div class="section" id="later-goals">
-<h2><a class="toc-backref" href="#id3">Later goals</a></h2>
-<ul class="simple">
-<li>Provide a reference host</li>
-<li>Provide some reference plugins</li>
-<li>Provide a validation plugin, which should signal anything wrong the host does</li>
-<li>Provide a validation host, which should give hard time to the plugin and
-ensure that basic functionnality are working</li>
-<li>Provide a libclap2vst, which adapts a clap plugin interface to a vst plugin
-interface</li>
-<li>Provide a remote plugin/host library</li>
-<li>Provide a libvst2clap, which adapts a vst plugin interface to a clap plugin
-interface</li>
-</ul>
-</div>
<div class="section" id="design-choice">
-<h2><a class="toc-backref" href="#id4">Design choice</a></h2>
+<h2><a class="toc-backref" href="#id3">Design choice</a></h2>
<ul class="simple">
-<li>The plugin and the host interface must be thread-safe.</li>
-<li>Avoid pointer exchange between the host and the plugin
-whenever it is possible. The chosen way is to pass a buffer
-as a parameter and let the host/plugin copy/read data from it.
-Rationale: as the host and the plugin can be multi-threaded,
-keeping pointers to the plugin or host internal memory can lead
-to race conditions. Also it can lead to ambiguities about who's
-responsible to free the memory. Also the host and the plugin
-may use custom allocator.</li>
-<li>Use the C language.</li>
-<li>Have support for dynamic configuration, to let a modular plugin
-add new parameters, new outputs/inputs, etc... dynamically.</li>
+<li>Use the C language for the interface.</li>
+<li>The host interface must be thread-safe.</li>
+<li>The plugin interface is not thread-safe.</li>
</ul>
</div>
</div>
<div class="section" id="specification">
-<h1><a class="toc-backref" href="#id5">Specification</a></h1>
+<h1><a class="toc-backref" href="#id4">Specification</a></h1>
<div class="section" id="how-to-read-the-specification">
-<h2><a class="toc-backref" href="#id6">How to read the specification</a></h2>
+<h2><a class="toc-backref" href="#id5">How to read the specification</a></h2>
<p>The specification should be read along the reference headers.
-<a class="reference external" href="https://abique.github.io/clap/">https://abique.github.io/clap/</a> gives a convinient view for that.</p>
+<a class="reference external" href="https://free-audio.github.io/clap/">https://free-audio.github.io/clap/</a> gives a convinient view for that.</p>
</div>
<div class="section" id="encoding">
-<h2><a class="toc-backref" href="#id7">Encoding</a></h2>
+<h2><a class="toc-backref" href="#id6">Encoding</a></h2>
<p>All the strings exchanged through the CLAP interface must be encoded in UTF-8
and must be valid.</p>
</div>
<div class="section" id="plugins-location">
-<h2><a class="toc-backref" href="#id8">Plugins location</a></h2>
+<h2><a class="toc-backref" href="#id7">Plugins location</a></h2>
<div class="section" id="common">
-<h3><a class="toc-backref" href="#id9">Common</a></h3>
+<h3><a class="toc-backref" href="#id8">Common</a></h3>
<ul class="simple">
<li>Directories should be scanned recursively.</li>
</ul>
</div>
<div class="section" id="linux">
-<h3><a class="toc-backref" href="#id10">Linux</a></h3>
+<h3><a class="toc-backref" href="#id9">Linux</a></h3>
<ul class="simple">
<li>Plugins distributed with packages should be installed to: <tt class="docutils literal">/usr/lib/clap/</tt></li>
<li>Plugins installed in the user's home should be installed to: <tt class="docutils literal"><span class="pre">${HOME}/.clap/</span></tt></li>
</ul>
</div>
<div class="section" id="windows">
-<h3><a class="toc-backref" href="#id11">Windows</a></h3>
+<h3><a class="toc-backref" href="#id10">Windows</a></h3>
<p>TBD</p>
</div>
<div class="section" id="mac">
-<h3><a class="toc-backref" href="#id12">Mac</a></h3>
+<h3><a class="toc-backref" href="#id11">Mac</a></h3>
<p>TBD</p>
</div>
<div class="section" id="multi-architecture-conventions">
-<h3><a class="toc-backref" href="#id13">Multi-architecture conventions</a></h3>
+<h3><a class="toc-backref" href="#id12">Multi-architecture conventions</a></h3>
<p>Let's say that we have a plugin called <tt class="docutils literal">DigitalDragon</tt>. If we distribute
it for multiple architecture, then the host should be able to identify which
version is suited for the current architecture by reading its name.</p>
@@ -318,41 +296,51 @@ built for the native/current architecture.</p>
</div>
</div>
<div class="section" id="instantiate-a-plugin">
-<h2><a class="toc-backref" href="#id14">Instantiate a plugin</a></h2>
-<p>Plugin instantiating can be done in a few steps:</p>
+<h2><a class="toc-backref" href="#id13">Instantiate a plugin</a></h2>
+<p>Plugin instantiation can be done in a few steps:</p>
<ul class="simple">
-<li>load the plugin library</li>
+<li>load the plugin library with <tt class="docutils literal">dlopen</tt> or symilar functions</li>
<li>find the symbol <tt class="docutils literal">clap_create</tt></li>
<li>instantiate the plugin by calling <tt class="docutils literal">clap_create</tt></li>
</ul>
<div class="section" id="precautions">
-<h3><a class="toc-backref" href="#id15">Precautions</a></h3>
+<h3><a class="toc-backref" href="#id14">Precautions</a></h3>
<ul class="simple">
<li>The function <tt class="docutils literal">clap_create</tt> must be thread-safe.</li>
<li>It must not throw exceptions.</li>
<li>It can return <tt class="docutils literal">NULL</tt>.</li>
</ul>
</div>
+<div class="section" id="release-a-plugin">
+<h3><a class="toc-backref" href="#id15">Release a plugin</a></h3>
+<p>To release a plugin, call <tt class="docutils literal"><span class="pre">plugin->destroy(plugin);</span></tt>.
+It is not required to deactivate the plugin prior to destroy it.</p>
+</div>
<div class="section" id="plugins-collection">
<h3><a class="toc-backref" href="#id16">Plugins collection</a></h3>
-<p>A single dynamic library can contains multiple clap plugins.
-To list them, you have to call <tt class="docutils literal">clap_create</tt> with an index of 0 and increment
-the index until you reach <tt class="docutils literal">plugin_count</tt>.
-<tt class="docutils literal">clap_create</tt> returns <tt class="docutils literal">NULL</tt> if the plugin creation failed or if
+<p>A single shared library can contains multiple clap plugins.
+To list them, you have to call <tt class="docutils literal">clap_create</tt> with an index of 0.
+<tt class="docutils literal">clap_create</tt> will store the number of plugins in the collection
+into the parameter <tt class="docutils literal">*plugins_count</tt>. After that you can create any
+of them by using an <tt class="docutils literal">index</tt> between <tt class="docutils literal">0</tt> and <tt class="docutils literal">*plugins_count</tt>.</p>
+<p><tt class="docutils literal">clap_create</tt> returns <tt class="docutils literal">NULL</tt> if the plugin creation failed or if
<tt class="docutils literal">plugin_index >= plugin_count</tt>.</p>
<div class="section" id="sample-plugin-loader">
<h4><a class="toc-backref" href="#id17">Sample plugin loader</a></h4>
<p>See <a class="reference internal" href="#examples-clap-info-clap-info-c">examples/clap-info/clap-info.c</a></p>
</div>
</div>
-<div class="section" id="description">
-<h3><a class="toc-backref" href="#id18">Description</a></h3>
-<p>Both the <tt class="docutils literal">struct clap_plugin;</tt> and <tt class="docutils literal">struct clap_host;</tt> have a few attribute giving
-general plugin/host information.</p>
+<div class="section" id="plugin-description">
+<h3><a class="toc-backref" href="#id18">Plugin description</a></h3>
+<p><tt class="docutils literal">struct clap_plugin</tt> only contains a interger <tt class="docutils literal">clap_version</tt> which
+indicates which version of the clap interface has been used to build the plugin, and
+a few methods. This attribute must be initialized by the plugin with
+<tt class="docutils literal">CLAP_PLUGIN_VERSION</tt>.</p>
+<p>Then to get plugin's attribute, you have to use <tt class="docutils literal"><span class="pre">plugin->get_attribute(plugin,</span> <span class="pre">...)</span></tt>.</p>
<table border="1" class="docutils">
<colgroup>
-<col width="25%" />
-<col width="75%" />
+<col width="34%" />
+<col width="66%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Attribute</th>
@@ -360,68 +348,53 @@ general plugin/host information.</p>
</tr>
</thead>
<tbody valign="top">
-<tr><td>clap_version</td>
-<td>Described the plugin format version implemented. Should be
-initialized with CLAP_PLUGIN_VERSION,
-or CLAP_VERSION_MAKE(1, 0, 0) if you want to only support
-version 1.0.0</td>
-</tr>
-<tr><td>id</td>
+<tr><td>CLAP_ATTR_ID</td>
<td>Unique identifier of the plugin. It should never change. It
should be the same on any plateform.</td>
</tr>
-<tr><td>name</td>
+<tr><td>CLAP_ATTR_NAME</td>
<td>The name of the product.</td>
</tr>
-<tr><td>description</td>
+<tr><td>CLAP_ATTR_DESCRIPTION</td>
<td>A brief description of the product.</td>
</tr>
-<tr><td>manufacturer</td>
+<tr><td>CLAP_ATTR_MANUFACTURER</td>
<td>Which company made the plugin.</td>
</tr>
-<tr><td>version</td>
+<tr><td>CLAP_ATTR_VERSION</td>
<td>A string describing the product version.</td>
</tr>
-<tr><td>url</td>
+<tr><td>CLAP_ATTR_URL</td>
<td>An URL to the product homepage.</td>
</tr>
-<tr><td>license</td>
+<tr><td>CLAP_ATTR_LICENSE</td>
<td>The plugin license type, Custom, GPLv3, MIT, ...</td>
</tr>
-<tr><td>support</td>
+<tr><td>CLAP_ATTR_SUPPORT</td>
<td>A link to the support, it can be
<tt class="docutils literal">mailto:support@company.com</tt> or
<tt class="docutils literal"><span class="pre">http://company.com/support</span></tt>.</td>
</tr>
-<tr><td>categories</td>
+<tr><td>CLAP_ATTR_CATEGORIES</td>
<td>A string containing a list of categories, joined with <tt class="docutils literal">;</tt>.
For example: <tt class="docutils literal">fm;analogue;delay</tt>.</td>
</tr>
-<tr><td>type</td>
+<tr><td>CLAP_ATTR_TYPE</td>
<td>Bitfield describing what the plugin does. See
<tt class="docutils literal">enum clap_plugin_type</tt>.</td>
</tr>
-<tr><td>chunk_size</td>
+<tr><td>CLAP_ATTR_CHUNK_SIZE</td>
<td>The process buffer, must have a number of sample multiple of
<tt class="docutils literal">chunk_size</tt>.</td>
</tr>
-<tr><td>latency</td>
+<tr><td>CLAP_ATTR_LATENCY</td>
<td>The latency introduced by the plugin.</td>
</tr>
-<tr><td>has_gui</td>
-<td>True if the plugin can show a graphical user interface</td>
-</tr>
-<tr><td>supports_tuning</td>
+<tr><td>CLAP_ATTR_SUPPORTS_TUNING</td>
<td>True if the plugin supports tuning</td>
</tr>
-<tr><td>supports_microtones</td>
-<td>True if the plugin supports micro tones</td>
-</tr>
-<tr><td>host_data</td>
-<td>Reserved pointer for the host.</td>
-</tr>
-<tr><td>plugin_data</td>
-<td>Reserved pointer for the plugin.</td>
+<tr><td>CLAP_ATTR_IS_REMOTE_PROCESSING</td>
+<td>True if the plugin supports tuning</td>
</tr>
</tbody>
</table>
@@ -431,7 +404,8 @@ For example: <tt class="docutils literal">fm;analogue;delay</tt>.</td>
<p>A plugin may have multiple audio ports, and so multiple audio ports
layout or configurations.</p>
<p>An audio port has a type: mono, stereo, surround and a role: main
-input/output, sidechain, feedback.</p>
+input/output or sidechain. We might add a feedback role in the futur
+if there is a need for it.</p>
<div class="section" id="pin-layout">
<h4><a class="toc-backref" href="#id20">Pin layout</a></h4>
<table border="1" class="docutils">
@@ -485,7 +459,20 @@ input/output, sidechain, feedback.</p>
</tr>
</tbody>
</table>
-<p>So for the following configuration:</p>
+</div>
+<div class="section" id="configurations">
+<h4><a class="toc-backref" href="#id21">Configurations</a></h4>
+<p>After the call to <tt class="docutils literal">clap_create()</tt> the new plugin uses the default ports
+configuration: 1 stereo input and 1 stereo output. So if you're fine with
+it, there is nothing more to do.</p>
+<p>If a plugins wants to offer more ports configuration to the host/user, it
+has to use ports extension. See <a class="reference internal" href="#clap-ext-ports-h">clap/ext/ports.h</a>.</p>
+<p>The host can select a ports configuration only if the plugin is in
+the deactivated state.</p>
+<p>Note that if the plugin does not support the default configuration
+which is stereo input and stereo output, then it must return false
+during the plugin activation (<tt class="docutils literal"><span class="pre">plugin->activate(plugin)</span></tt>).</p>
+<p>Here is a configuration for a stereo sidechain compressor:</p>
<table border="1" class="docutils">
<colgroup>
<col width="12%" />
@@ -521,15 +508,6 @@ input/output, sidechain, feedback.</p>
<tr><td>process->inputs[3]</td>
<td>right sidechain</td>
</tr>
-<tr><td rowspan="2">input</td>
-<td rowspan="2">stereo</td>
-<td rowspan="2">feedback</td>
-<td>process->inputs[4]</td>
-<td>left feedback</td>
-</tr>
-<tr><td>process->inputs[5]</td>
-<td>right feedback</td>
-</tr>
<tr><td rowspan="2">output</td>
<td rowspan="2">stereo</td>
<td rowspan="2">inout</td>
@@ -539,36 +517,41 @@ input/output, sidechain, feedback.</p>
<tr><td>process->outputs[1]</td>
<td>right input</td>
</tr>
-<tr><td rowspan="2">output</td>
-<td rowspan="2">stereo</td>
-<td rowspan="2">feedback</td>
-<td>process->outputs[2]</td>
-<td>left feedback</td>
-</tr>
-<tr><td>process->outputs[3]</td>
-<td>right feedback</td>
-</tr>
</tbody>
</table>
</div>
-<div class="section" id="available-configurations">
-<h4><a class="toc-backref" href="#id21">Available configurations</a></h4>
+<div class="section" id="getting-the-ports-configurations">
+<h4><a class="toc-backref" href="#id22">Getting the ports configurations</a></h4>
+<pre class="code c literal-block">
+<span class="cp">#include <clap/ext/ports.h>
+</span>
+<span class="k">struct</span> <span class="n">clap_plugin_ports</span> <span class="o">*</span><span class="n">ports</span> <span class="o">=</span> <span class="n">plugin</span><span class="o">-></span><span class="n">extension</span><span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">CLAP_EXT_PORTS</span><span class="p">);</span>
+<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ports</span><span class="p">)</span>
+ <span class="k">return</span><span class="p">;</span> <span class="c1">// no ports extensions
+</span><span class="kt">uint32_t</span> <span class="n">count</span> <span class="o">=</span> <span class="n">ports</span><span class="o">-></span><span class="n">get_configs_count</span><span class="p">(</span><span class="n">plugin</span><span class="p">);</span>
+<span class="k">for</span> <span class="p">(</span><span class="kt">uint32_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">count</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">struct</span> <span class="n">clap_ports_config</span> <span class="n">config</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ports</span><span class="o">-></span><span class="n">get_config</span><span class="p">(</span><span class="n">plugin</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="o">&</span><span class="n">config</span><span class="p">))</span>
+ <span class="k">continue</span><span class="p">;</span>
+ <span class="c1">// ...
+</span><span class="p">}</span>
+</pre>
<p>It is possible to discover a plugin's port configurations by calling
-<tt class="docutils literal"><span class="pre">plugin->get_ports_configs_count(plugin);</span></tt>. It returns the number of
+<tt class="docutils literal"><span class="pre">ports->get_configs_count(plugin);</span></tt>. It returns the number of
configurations. Then for each configuration you have to call
-<tt class="docutils literal"><span class="pre">plugin->get_ports_config(plugin,</span> config_index, &config);</tt> which will
+<tt class="docutils literal"><span class="pre">ports->get_config(plugin,</span> config_index, &config);</tt> which will
tell you the number of input and output ports. Then to get the port details,
you have to call
-<tt class="docutils literal"><span class="pre">plugin->get_port_info(plugin,</span> config_index, port_index, &port);</tt>.</p>
+<tt class="docutils literal"><span class="pre">ports->get_info(plugin,</span> config_index, port_index, &port);</tt>.</p>
</div>
<div class="section" id="selecting-a-configuration">
-<h4><a class="toc-backref" href="#id22">Selecting a configuration</a></h4>
+<h4><a class="toc-backref" href="#id23">Selecting a configuration</a></h4>
<p>Selecting an audio configuration has to be done when the plugin is deactivated.
It is done by calling <tt class="docutils literal"><span class="pre">plugin->set_port_config(plugin,</span> config_index)</tt>.
If the call returns false, then the plugin is in failed state.</p>
</div>
<div class="section" id="repeatable-channels">
-<h4><a class="toc-backref" href="#id23">Repeatable channels</a></h4>
+<h4><a class="toc-backref" href="#id24">Repeatable channels</a></h4>
<p>Repeatable channels are a special case. A channel can be identified as
repeatable if <tt class="docutils literal"><span class="pre">channel->is_repeatable</span> == true</tt>.</p>
<p>A useful case is for an analyzer. Imagine a spectroscope, to which you want to
@@ -577,57 +560,15 @@ the spectrograph, so it is a convinient way analyze many tracks in the same
spectroscope.</p>
<p>For the special case of repeatable side chain input, the host
has to tell the plugin how many times the port should be repeated.
-To do that it has to call <tt class="docutils literal"><span class="pre">plugin->set_port_repeat(plugin,</span> port_index, count)</tt>.
+To do that it has to call <tt class="docutils literal"><span class="pre">plugin->set_repeat(plugin,</span> port_index, count)</tt>.
If it returns <tt class="docutils literal">false</tt> then the plugin is in the same state as before
the call.</p>
-</div>
-<div class="section" id="feedback-stream">
-<h4><a class="toc-backref" href="#id24">Feedback stream</a></h4>
-<p>Feedback stream are used to plug external audio processing into one
-of the plugin feedback loop.</p>
-<p>A practical usage is to put an effect in a delay feedback loop.</p>
-<p>A feedback loop has it's both ends identified by <tt class="docutils literal"><span class="pre">clap_channel->stream_id</span></tt>.</p>
-<p>During the audio processing, <tt class="docutils literal">struct clap_process</tt> contains a callback which
-is used to process the feedback stream:</p>
-<pre class="code c literal-block">
-<span class="kt">void</span> <span class="nf">my_plugin_process</span><span class="p">(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span> <span class="k">struct</span> <span class="n">clap_process</span> <span class="o">*</span><span class="n">process</span><span class="p">)</span>
-<span class="p">{</span>
- <span class="kt">uint32_t</span> <span class="n">fb_in</span><span class="p">;</span> <span class="c1">// index to the stereo feedback input buffer
-</span> <span class="kt">uint32_t</span> <span class="n">fb_out</span><span class="p">;</span> <span class="c1">// index to the stereo feedback output buffer
-</span> <span class="kt">uint32_t</span> <span class="n">stream_id</span><span class="p">;</span> <span class="c1">// the feedback stream id
-</span> <span class="kt">uint32_t</span> <span class="n">offset</span><span class="p">;</span>
-
- <span class="c1">// process all the buffer
-</span> <span class="k">for</span> <span class="p">(</span><span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">offset</span> <span class="o"><</span> <span class="n">process</span><span class="o">-></span><span class="n">samples_count</span><span class="p">;</span>
- <span class="n">offset</span> <span class="o">+=</span> <span class="n">process</span><span class="o">-></span><span class="n">feedback_chunk_size</span><span class="p">)</span>
- <span class="p">{</span>
-
- <span class="c1">// ...
-</span>
- <span class="c1">// prepare feedback output buffer
-</span> <span class="k">for</span> <span class="p">(</span><span class="kt">uint32_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">process</span><span class="o">-></span><span class="n">feedback_chunk_size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
- <span class="n">process</span><span class="o">-></span><span class="n">output</span><span class="p">[</span><span class="n">fb_out</span><span class="p">][</span><span class="n">offset</span> <span class="o">+</span> <span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">XXX</span><span class="p">;</span>
- <span class="n">process</span><span class="o">-></span><span class="n">output</span><span class="p">[</span><span class="n">fb_out</span> <span class="o">+</span> <span class="mi">1</span><span class="p">][</span><span class="n">offset</span> <span class="o">+</span> <span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">XXX</span><span class="p">;</span>
- <span class="p">}</span>
-
- <span class="c1">// process one sample feedback
-</span> <span class="n">process</span><span class="o">-></span><span class="n">feedback</span><span class="p">(</span><span class="n">process</span><span class="p">,</span> <span class="n">stream_id</span><span class="p">,</span> <span class="n">process</span><span class="o">-></span><span class="n">feedback_chunk_size</span><span class="p">);</span>
-
- <span class="c1">// audio processing of the feedback values:
-</span> <span class="c1">// process->input[fb_in][offset + i]
-</span> <span class="c1">// process->input[fb_in + 1][offset + i]
-</span> <span class="p">}</span>
-<span class="p">}</span>
-</pre>
-</div>
+<p>Only inputs can be repeatable.</p>
</div>
</div>
-<div class="section" id="threading">
-<h2><a class="toc-backref" href="#id25">Threading</a></h2>
-<p>The plugin must be thread safe.</p>
</div>
<div class="section" id="activation">
-<h2><a class="toc-backref" href="#id26">Activation</a></h2>
+<h2><a class="toc-backref" href="#id25">Activation</a></h2>
<p>Before doing any processing, the plugin must be activated by calling
<tt class="docutils literal">bool succeed = <span class="pre">plugin->activate(plugin);</span></tt>.</p>
<p>If <tt class="docutils literal">succeed == true</tt> then the activation succeed. If the activation failed,
@@ -635,46 +576,70 @@ then the plugin is unusable.</p>
<p>The host must not call <tt class="docutils literal">activate()</tt> if the plugin is already activated.
Yet the plugin should handle correctly double calls to <tt class="docutils literal">activate()</tt>.</p>
<p>The plugin activation could be nothing, or could be a task which takes time,
-like connecting a remote server. So the host should not activate plugins in
-the audio processing thread.</p>
+like connecting a remote server or device.
+So the host should not activate plugins in the audio processing thread.</p>
<p>To deactivate the plugin, just call <tt class="docutils literal"><span class="pre">plugin->deactivate(plugin)</span></tt>. Like
<tt class="docutils literal">activate()</tt>, <tt class="docutils literal">deactivate()</tt> should not be called from the audio processing
thread as it may take time.</p>
<p>Also <tt class="docutils literal">deactivate()</tt> should not be called if the plugin is not activated.
Yet the plugin should handle a call to <tt class="docutils literal">deactivate()</tt> even if it is
not activated.</p>
-<p>It is preferable to de-activate the plugin before destroying it.</p>
+<p>It is recommended (but not mandatory) to de-activate the plugin before
+destroying it.</p>
</div>
<div class="section" id="processing">
-<h2><a class="toc-backref" href="#id27">Processing</a></h2>
+<h2><a class="toc-backref" href="#id26">Processing</a></h2>
<p>The processing is done in one call: <tt class="docutils literal"><span class="pre">plugin->process(plugin,</span> process);</tt>.
The data structure process regroup everything needed by the plugin:</p>
<ul class="simple">
<li>audio buffers (in, out)</li>
-<li>feedback process callback</li>
<li>events (in)</li>
-<li>tempo, time, is offline? (in)</li>
-<li>more processing needed (out)</li>
+<li>some time info</li>
</ul>
+<p>Once the processing is finished, the methods returns a process status
+which can be:</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="27%" />
+<col width="73%" />
+</colgroup>
+<thead valign="bottom">
+<tr><th class="head">Status</th>
+<th class="head">Meaning</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr><td>CLAP_PROCESS_ERROR</td>
+<td>An error happened, and the buffers should be discarded</td>
+</tr>
+<tr><td>CLAP_PROCESS_CONTINUE</td>
+<td>Succeed, the plugins wants to process the next block</td>
+</tr>
+<tr><td>CLAP_PROCESS_STOP</td>
+<td>Succeed, every voices terminated, wake me up on a new event</td>
+</tr>
+</tbody>
+</table>
<div class="section" id="audio-buffers">
-<h3><a class="toc-backref" href="#id28">Audio buffers</a></h3>
+<h3><a class="toc-backref" href="#id27">Audio buffers</a></h3>
<ul class="simple">
<li>The audio buffers are allocated by the host. They must be aligned by the
maximum requirement of the vector instructions currently available.</li>
<li>In-place processing is not supported.</li>
-<li>The number of samples must be a multiple of <tt class="docutils literal"><span class="pre">plugin->chunk_size</span></tt>.</li>
+<li>The number of samples must be a multiple of the plugin chunk_size.</li>
<li>See <a class="reference internal" href="#pin-layout">Pin layout</a>.</li>
+<li>See <a class="reference internal" href="#plugin-description">Plugin description</a></li>
</ul>
</div>
<div class="section" id="events">
-<h3><a class="toc-backref" href="#id29">Events</a></h3>
+<h3><a class="toc-backref" href="#id28">Events</a></h3>
<ul class="simple">
<li>Event's time must be within the process duration:
<tt class="docutils literal"><span class="pre">[process->steady_time</span> .. <span class="pre">process->steady_time</span> + <span class="pre">process->nb_sambles]</span></tt>.</li>
-<li>The plugin must not modify the input events (<tt class="docutils literal">in_events</tt>).</li>
+<li>The plugin must not modify the events.</li>
</ul>
<div class="section" id="notes">
-<h4><a class="toc-backref" href="#id30">Notes</a></h4>
+<h4><a class="toc-backref" href="#id29">Notes</a></h4>
<p>Notes are represented as a pair <tt class="docutils literal">note, division</tt>.
Division is the number of intervals between one note and an other note with
half or the double frequency. A division by 12 must be supported.</p>
@@ -684,7 +649,7 @@ micro-tuned notes.</p>
<tt class="docutils literal"><span class="pre">plugin->supports_microtones</span> == false</tt>.</p>
</div>
<div class="section" id="parameters">
-<h4><a class="toc-backref" href="#id31">Parameters</a></h4>
+<h4><a class="toc-backref" href="#id30">Parameters</a></h4>
<p>Parameters can be automated by the host using <tt class="docutils literal">CLAP_EVENT_PARAM_SET</tt> or
<tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt>.</p>
<p>When using <tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt>, the value of the parameter has to be
@@ -692,14 +657,14 @@ incremented by <tt class="docutils literal"><span class="pre">event->param.in
occur on this parameter.</p>
</div>
<div class="section" id="pitch">
-<h4><a class="toc-backref" href="#id32">Pitch</a></h4>
+<h4><a class="toc-backref" href="#id31">Pitch</a></h4>
<p>The pitch is the frequency of the note A4. Its default value is 440Hz.
The pitch can be changed by the host using the <tt class="docutils literal">CLAP_EVENT_PITCH_SET</tt> event.</p>
</div>
</div>
</div>
<div class="section" id="id1">
-<h2><a class="toc-backref" href="#id33">Parameters</a></h2>
+<h2><a class="toc-backref" href="#id32">Parameters</a></h2>
<p>The host can get the plugin's parameters tree by calling:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">plugin->get_params_count(plugin);</span></tt> to know the number of parameters</li>
@@ -754,7 +719,7 @@ types.</td>
</tbody>
</table>
<div class="section" id="types">
-<h3><a class="toc-backref" href="#id34">Types</a></h3>
+<h3><a class="toc-backref" href="#id33">Types</a></h3>
<p>There are a few parameter types:</p>
<table border="1" class="docutils">
<colgroup>
@@ -796,14 +761,14 @@ should rely on <tt class="docutils literal">display_text</tt> to show its value.
</table>
</div>
<div class="section" id="scales">
-<h3><a class="toc-backref" href="#id35">Scales</a></h3>
+<h3><a class="toc-backref" href="#id34">Scales</a></h3>
<p>The plugin can inform the host, which scale to use for the parameter's UI
(knob, slider, ...). <tt class="docutils literal"><span class="pre">clap_param->scale</span></tt> can be set to <tt class="docutils literal">CLAP_PARAM_LINEAR</tt>
or <tt class="docutils literal">CLAP_PARAM_LOG</tt>. A logarithmic scale is convinient for a frequency
parameter.</p>
</div>
<div class="section" id="automation">
-<h3><a class="toc-backref" href="#id36">Automation</a></h3>
+<h3><a class="toc-backref" href="#id35">Automation</a></h3>
<p>When a parameter is modified by the GUI, the plugin should send a
<tt class="docutils literal">CLAP_EVENT_PARAM_SET</tt> event must be sent to the host, using
<tt class="docutils literal"><span class="pre">host->events(host,</span> plugin, events);</tt> so the host can record the automation.</p>
@@ -814,15 +779,15 @@ To do that the plugin uses <tt class="docutils literal"><span class="pre">clap_e
</div>
</div>
<div class="section" id="graphical-user-interface">
-<h2><a class="toc-backref" href="#id37">Graphical User Interface</a></h2>
+<h2><a class="toc-backref" href="#id36">Graphical User Interface</a></h2>
<div class="section" id="showing-the-gui">
-<h3><a class="toc-backref" href="#id38">Showing the GUI</a></h3>
+<h3><a class="toc-backref" href="#id37">Showing the GUI</a></h3>
<p>The plugin should show the GUI after a call to <tt class="docutils literal"><span class="pre">plugin->show_gui(plugin)</span></tt>.
If the plugin could successfully show the GUI, it returns <tt class="docutils literal">true</tt>, <tt class="docutils literal">false</tt>
otherwise.</p>
</div>
<div class="section" id="sending-events-to-the-host">
-<h3><a class="toc-backref" href="#id39">Sending events to the host</a></h3>
+<h3><a class="toc-backref" href="#id38">Sending events to the host</a></h3>
<p>The plugin can notify the host of parameter changes by sending events to:
<tt class="docutils literal"><span class="pre">host->events(host,</span> plugin, events);</tt>.</p>
<p>Events sent to the host should be stamped:</p>
@@ -834,7 +799,7 @@ otherwise.</p>
</pre>
</div>
<div class="section" id="hiding-the-gui">
-<h3><a class="toc-backref" href="#id40">Hiding the GUI</a></h3>
+<h3><a class="toc-backref" href="#id39">Hiding the GUI</a></h3>
<p>The plugin should hide the GUI after a call to <tt class="docutils literal"><span class="pre">plugin->hide_gui(plugin)</span></tt>.
If the plugin window has been closed by the user, then the plugin should
send an event <tt class="docutils literal">CLAP_EVENT_GUI_CLOSED</tt> to the host.</p>
@@ -847,16 +812,16 @@ send an event <tt class="docutils literal">CLAP_EVENT_GUI_CLOSED</tt> to the hos
</pre>
</div>
<div class="section" id="embedding">
-<h3><a class="toc-backref" href="#id41">Embedding</a></h3>
+<h3><a class="toc-backref" href="#id40">Embedding</a></h3>
<p>Some host are designed to embed plugin's window.
As embedding is not a Clap requirement, it is offered as an extension.
Also the OS dependency brought by this feature makes it ideal as an extension.</p>
<table border="1" class="docutils">
<colgroup>
<col width="16%" />
-<col width="32%" />
-<col width="30%" />
-<col width="22%" />
+<col width="35%" />
+<col width="29%" />
+<col width="21%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">GUI</th>
@@ -867,24 +832,24 @@ Also the OS dependency brought by this feature makes it ideal as an extension.</
</thead>
<tbody valign="top">
<tr><td>Generic</td>
-<td><a class="reference internal" href="#clap-embed-h">clap-embed.h</a></td>
+<td><a class="reference internal" href="#clap-ext-embed-h">clap/ext/embed.h</a></td>
<td><tt class="docutils literal">CLAP_EMBED</tt></td>
<td>For the host</td>
</tr>
<tr><td>Windows</td>
-<td><a class="reference internal" href="#clap-embed-win32-h">clap-embed-win32.h</a></td>
+<td><a class="reference internal" href="#clap-ext-embed-win32-h">clap/ext/embed-win32.h</a></td>
<td><tt class="docutils literal">CLAP_EMBED_WIN32</tt></td>
<td>For the plugin</td>
</tr>
<tr><td>X11</td>
-<td><a class="reference internal" href="#clap-embed-xlib-h">clap-embed-xlib.h</a></td>
+<td><a class="reference internal" href="#clap-ext-embed-xlib-h">clap/ext/embed-xlib.h</a></td>
<td><tt class="docutils literal">CLAP_EMBED_XLIB</tt></td>
<td>For the plugin</td>
</tr>
</tbody>
</table>
<div class="section" id="example-on-windows">
-<h4><a class="toc-backref" href="#id42">Example on Windows</a></h4>
+<h4><a class="toc-backref" href="#id41">Example on Windows</a></h4>
<pre class="code c literal-block">
<span class="cp">#include <clap/clap.h>
#include <clap/clap-embed-win32.h>
@@ -899,7 +864,7 @@ Also the OS dependency brought by this feature makes it ideal as an extension.</
</pre>
</div>
<div class="section" id="resizing-the-window">
-<h4><a class="toc-backref" href="#id43">Resizing the window</a></h4>
+<h4><a class="toc-backref" href="#id42">Resizing the window</a></h4>
<pre class="code c literal-block">
<span class="cp">#include <clap/clap.h>
#include <clap/clap-embed.h>
@@ -914,9 +879,9 @@ Also the OS dependency brought by this feature makes it ideal as an extension.</
</div>
</div>
<div class="section" id="presets">
-<h2><a class="toc-backref" href="#id44">Presets</a></h2>
+<h2><a class="toc-backref" href="#id43">Presets</a></h2>
<div class="section" id="list-plugin-s-presets">
-<h3><a class="toc-backref" href="#id45">List plugin's presets</a></h3>
+<h3><a class="toc-backref" href="#id44">List plugin's presets</a></h3>
<p>The host can browse the plugin's preset by calling:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">plugin->get_presets_count(plugin);</span></tt> to know how many presets it has.</li>
@@ -925,7 +890,7 @@ details.</li>
</ul>
</div>
<div class="section" id="load-a-preset">
-<h3><a class="toc-backref" href="#id46">Load a preset</a></h3>
+<h3><a class="toc-backref" href="#id45">Load a preset</a></h3>
<p>To load a preset, the host have to send an event <tt class="docutils literal">CLAP_EVENT_PRESET_SET</tt> to
the plugin.</p>
<p>When a preset is loaded from the plugin's GUI, the plugin must send a
@@ -933,7 +898,7 @@ the plugin.</p>
</div>
</div>
<div class="section" id="save-and-restore-plugin-s-state">
-<h2><a class="toc-backref" href="#id47">Save and restore plugin's state</a></h2>
+<h2><a class="toc-backref" href="#id46">Save and restore plugin's state</a></h2>
<p>Saving the plugin's state is done by:</p>
<pre class="code c literal-block">
<span class="kt">void</span> <span class="o">*</span><span class="n">buffer</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
@@ -953,7 +918,7 @@ plugin state on a little endian machine and send it through the network to a
big endian machine, it should load again successfully.</p>
</div>
<div class="section" id="extension-system">
-<h2><a class="toc-backref" href="#id48">Extension system</a></h2>
+<h2><a class="toc-backref" href="#id47">Extension system</a></h2>
<p>To extend clap's functionnality, there is a pretty simple mechanism:</p>
<pre class="code c literal-block">
<span class="kt">void</span> <span class="o">*</span><span class="n">plug_ext</span> <span class="o">=</span> <span class="n">plugin</span><span class="o">-></span><span class="n">extension</span><span class="p">(</span><span class="n">plug</span><span class="p">,</span> <span class="s">"company/ext-name"</span><span class="p">);</span>
@@ -963,9 +928,9 @@ big endian machine, it should load again successfully.</p>
</div>
</div>
<div class="section" id="examples">
-<h1><a class="toc-backref" href="#id49">Examples</a></h1>
+<h1><a class="toc-backref" href="#id48">Examples</a></h1>
<div class="section" id="examples-clap-info-clap-info-c">
-<h2><a class="toc-backref" href="#id50">examples/clap-info/clap-info.c</a></h2>
+<h2><a class="toc-backref" href="#id49">examples/clap-info/clap-info.c</a></h2>
<pre class="code c literal-block">
<span class="cp">#include <stdio.h>
#include <dlfcn.h>
@@ -1049,7 +1014,6 @@ big endian machine, it should load again successfully.</p>
<span class="n">print_attr</span><span class="p">(</span><span class="n">TYPE</span><span class="p">);</span>
<span class="n">print_attr</span><span class="p">(</span><span class="n">CHUNK_SIZE</span><span class="p">);</span>
<span class="n">print_attr</span><span class="p">(</span><span class="n">LATENCY</span><span class="p">);</span>
- <span class="n">print_attr</span><span class="p">(</span><span class="n">HAS_GUI</span><span class="p">);</span>
<span class="n">print_attr</span><span class="p">(</span><span class="n">SUPPORTS_TUNING</span><span class="p">);</span>
<span class="cp">#undef print_attr
@@ -1066,11 +1030,11 @@ big endian machine, it should load again successfully.</p>
</div>
</div>
<div class="section" id="references">
-<h1><a class="toc-backref" href="#id51">References</a></h1>
-<div class="section" id="clap-h">
-<h2><a class="toc-backref" href="#id52">clap.h</a></h2>
+<h1><a class="toc-backref" href="#id50">References</a></h1>
+<div class="section" id="clap-clap-h">
+<h2><a class="toc-backref" href="#id51">clap/clap.h</a></h2>
<pre class="code c literal-block">
-<span class="cm">/**
+<span class="cm">/*
* CLAP - CLever Audio Plugin (<--- needs to find a marketing ok name)
* ~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -1122,7 +1086,7 @@ big endian machine, it should load again successfully.</p>
<span class="k">enum</span> <span class="n">clap_string_size</span>
<span class="p">{</span>
- <span class="n">CLAP_ID_SIZE</span> <span class="o">=</span> <span class="mi">32</span><span class="p">,</span>
+ <span class="n">CLAP_ID_SIZE</span> <span class="o">=</span> <span class="mi">48</span><span class="p">,</span>
<span class="n">CLAP_NAME_SIZE</span> <span class="o">=</span> <span class="mi">32</span><span class="p">,</span>
<span class="n">CLAP_DESC_SIZE</span> <span class="o">=</span> <span class="mi">256</span><span class="p">,</span>
<span class="n">CLAP_DISPLAY_SIZE</span> <span class="o">=</span> <span class="mi">32</span><span class="p">,</span>
@@ -1151,62 +1115,16 @@ big endian machine, it should load again successfully.</p>
# define CLAP_ATTR_TYPE "clap/type"
# define CLAP_ATTR_CHUNK_SIZE "clap/chunk_size"
# define CLAP_ATTR_LATENCY "clap/latency"
-# define CLAP_ATTR_HAS_GUI "clap/has_gui"
-# define CLAP_ATTR_SUPPORTS_TUNING "clap/supports_tuning"
+</span><span class="c1">// Should be "1" if the plugin supports tunning.
+</span><span class="cp"># define CLAP_ATTR_SUPPORTS_TUNING "clap/supports_tuning"
+</span><span class="c1">// Shoudl be "1" if the plugin is doing remote processing.
+// This is a hint for the host to optimize task scheduling.
+</span><span class="cp"># define CLAP_ATTR_IS_REMOTE_PROCESSING "clap/is_remote_processing"
</span>
-<span class="c1">///////////
-// PORTS //
-///////////
-</span>
-<span class="k">enum</span> <span class="n">clap_port_type</span>
-<span class="p">{</span>
- <span class="n">CLAP_PORT_MONO</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
- <span class="n">CLAP_PORT_STEREO</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
- <span class="n">CLAP_PORT_SURROUND</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
-<span class="p">};</span>
-
-<span class="k">enum</span> <span class="n">clap_port_role</span>
-<span class="p">{</span>
- <span class="n">CLAP_PORT_INOUT</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
- <span class="n">CLAP_PORT_SIDECHAIN</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
- <span class="n">CLAP_PORT_FEEDBACK</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
-<span class="p">};</span>
-
-<span class="k">struct</span> <span class="n">clap_port_info</span>
-<span class="p">{</span>
- <span class="k">enum</span> <span class="n">clap_port_type</span> <span class="n">type</span><span class="p">;</span>
- <span class="k">enum</span> <span class="n">clap_port_role</span> <span class="n">role</span><span class="p">;</span>
- <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span>
- <span class="kt">uint32_t</span> <span class="n">stream_id</span><span class="p">;</span> <span class="c1">// used to connect feedback loops
-</span> <span class="kt">bool</span> <span class="n">is_repeatable</span><span class="p">;</span>
-<span class="p">};</span>
-
-<span class="k">struct</span> <span class="n">clap_ports_config</span>
-<span class="p">{</span>
- <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span>
- <span class="kt">uint32_t</span> <span class="n">inputs_count</span><span class="p">;</span>
- <span class="kt">uint32_t</span> <span class="n">outputs_count</span><span class="p">;</span>
-<span class="p">};</span>
-
<span class="c1">////////////////
// PARAMETERS //
////////////////
</span>
-<span class="k">enum</span> <span class="n">clap_param_type</span>
-<span class="p">{</span>
- <span class="n">CLAP_PARAM_GROUP</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// no value for this one
-</span> <span class="n">CLAP_PARAM_BOOL</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="c1">// uses value.b
-</span> <span class="n">CLAP_PARAM_FLOAT</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="c1">// uses value.f
-</span> <span class="n">CLAP_PARAM_INT</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="c1">// uses value.i
-</span> <span class="n">CLAP_PARAM_ENUM</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span> <span class="c1">// uses value.i
-</span><span class="p">};</span>
-
-<span class="k">enum</span> <span class="n">clap_param_scale</span>
-<span class="p">{</span>
- <span class="n">CLAP_PARAM_LINEAR</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
- <span class="n">CLAP_PARAM_LOG</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
-<span class="p">};</span>
-
<span class="k">union</span> <span class="n">clap_param_value</span>
<span class="p">{</span>
<span class="kt">bool</span> <span class="n">b</span><span class="p">;</span>
@@ -1214,102 +1132,88 @@ big endian machine, it should load again successfully.</p>
<span class="kt">int32_t</span> <span class="n">i</span><span class="p">;</span>
<span class="p">};</span>
-<span class="k">struct</span> <span class="n">clap_param</span>
-<span class="p">{</span>
- <span class="cm">/* tree fields */</span>
- <span class="kt">uint32_t</span> <span class="n">index</span><span class="p">;</span> <span class="c1">// parameter's index
-</span> <span class="kt">uint32_t</span> <span class="n">parent</span><span class="p">;</span> <span class="c1">// parent's index, -1 for no parent
-</span>
- <span class="cm">/* param info */</span>
- <span class="k">enum</span> <span class="n">clap_param_type</span> <span class="n">type</span><span class="p">;</span>
- <span class="kt">char</span> <span class="n">id</span><span class="p">[</span><span class="mi">32</span><span class="p">];</span> <span class="c1">// a string which identify the param
-</span> <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span> <span class="c1">// the display name
-</span> <span class="kt">char</span> <span class="n">desc</span><span class="p">[</span><span class="n">CLAP_DESC_SIZE</span><span class="p">];</span>
- <span class="kt">bool</span> <span class="n">is_per_note</span><span class="p">;</span>
- <span class="kt">char</span> <span class="n">display_text</span><span class="p">[</span><span class="n">CLAP_DISPLAY_SIZE</span><span class="p">];</span> <span class="c1">// the text used to display the value
-</span> <span class="kt">bool</span> <span class="n">is_used</span><span class="p">;</span> <span class="c1">// is this parameter used by the patch?
-</span> <span class="k">union</span> <span class="n">clap_param_value</span> <span class="n">value</span><span class="p">;</span>
- <span class="k">union</span> <span class="n">clap_param_value</span> <span class="n">min</span><span class="p">;</span>
- <span class="k">union</span> <span class="n">clap_param_value</span> <span class="n">max</span><span class="p">;</span>
- <span class="k">enum</span> <span class="n">clap_param_scale</span> <span class="n">scale</span><span class="p">;</span>
-<span class="p">};</span>
-
-<span class="c1">/////////////
-// PRESETS //
-/////////////
-</span>
-<span class="k">struct</span> <span class="n">clap_preset</span>
-<span class="p">{</span>
- <span class="kt">uint32_t</span> <span class="n">id</span><span class="p">;</span> <span class="c1">// preset id
-</span> <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span> <span class="c1">// display name
-</span> <span class="kt">char</span> <span class="n">desc</span><span class="p">[</span><span class="n">CLAP_DESC_SIZE</span><span class="p">];</span> <span class="c1">// desc and how to use it
-</span> <span class="kt">char</span> <span class="n">author</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span>
- <span class="kt">char</span> <span class="n">tags</span><span class="p">[</span><span class="n">CLAP_TAGS_SIZE</span><span class="p">];</span> <span class="c1">// "tag1;tag2;tag3;..."
-</span><span class="p">};</span>
-
<span class="c1">////////////
// EVENTS //
////////////
</span>
<span class="k">enum</span> <span class="n">clap_event_type</span>
<span class="p">{</span>
- <span class="n">CLAP_EVENT_NOTE_ON</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// note attribute
-</span> <span class="n">CLAP_EVENT_NOTE_MODULATION</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="c1">// note attribute
-</span> <span class="n">CLAP_EVENT_NOTE_OFF</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="c1">// note attribute
+ <span class="n">CLAP_EVENT_NOTE_ON</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// note attribute
+</span> <span class="n">CLAP_EVENT_NOTE_OFF</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="c1">// note attribute
</span>
- <span class="n">CLAP_EVENT_PARAM_SET</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="c1">// param attribute
-</span> <span class="n">CLAP_EVENT_PARAM_RAMP</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span> <span class="c1">// param attribute
-</span> <span class="n">CLAP_EVENT_PRESET_SET</span> <span class="o">=</span> <span class="mi">6</span><span class="p">,</span> <span class="c1">// preset attribute
+ <span class="n">CLAP_EVENT_PARAM_SET</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="c1">// param attribute
+</span> <span class="n">CLAP_EVENT_PARAM_RAMP</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="c1">// param attribute
+</span> <span class="n">CLAP_EVENT_PRESET_SET</span> <span class="o">=</span> <span class="mi">4</span><span class="p">,</span> <span class="c1">// preset attribute
</span>
- <span class="n">CLAP_EVENT_MIDI</span> <span class="o">=</span> <span class="mi">7</span><span class="p">,</span> <span class="c1">// midi attribute
-</span> <span class="n">CLAP_EVENT_CONTROL</span> <span class="o">=</span> <span class="mi">8</span><span class="p">,</span> <span class="c1">// control attribute
+ <span class="n">CLAP_EVENT_MIDI</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="c1">// midi attribute
+</span> <span class="n">CLAP_EVENT_CONTROL</span> <span class="o">=</span> <span class="mi">6</span><span class="p">,</span> <span class="c1">// control attribute
</span>
- <span class="n">CLAP_EVENT_GUI_OPENED</span> <span class="o">=</span> <span class="mi">9</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
-</span> <span class="n">CLAP_EVENT_GUI_CLOSED</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
+ <span class="n">CLAP_EVENT_GUI_OPENED</span> <span class="o">=</span> <span class="mi">7</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
+</span> <span class="n">CLAP_EVENT_GUI_CLOSED</span> <span class="o">=</span> <span class="mi">8</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
</span>
- <span class="n">CLAP_EVENT_NEW_PRESETS</span> <span class="o">=</span> <span class="mi">11</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
-</span> <span class="n">CLAP_EVENT_NEW_PORTS_CONFIGS</span> <span class="o">=</span> <span class="mi">12</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
+ <span class="n">CLAP_EVENT_NEW_PRESETS</span> <span class="o">=</span> <span class="mi">9</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
+</span> <span class="n">CLAP_EVENT_NEW_PORTS_CONFIGS</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> <span class="c1">// plugin to host, no attribute
</span>
- <span class="n">CLAP_EVENT_LATENCY_CHANGED</span> <span class="o">=</span> <span class="mi">13</span><span class="p">,</span> <span class="c1">// plugin to host, latency attribute
+ <span class="n">CLAP_EVENT_LATENCY_CHANGED</span> <span class="o">=</span> <span class="mi">11</span><span class="p">,</span> <span class="c1">// plugin to host, latency attribute
</span>
- <span class="n">CLAP_EVENT_PLAY</span> <span class="o">=</span> <span class="mi">14</span><span class="p">,</span> <span class="c1">// no attribute
-</span> <span class="n">CLAP_EVENT_PAUSE</span> <span class="o">=</span> <span class="mi">15</span><span class="p">,</span> <span class="c1">// no attribute
-</span> <span class="n">CLAP_EVENT_STOP</span> <span class="o">=</span> <span class="mi">16</span><span class="p">,</span> <span class="c1">// no attribute
+ <span class="n">CLAP_EVENT_PLAY</span> <span class="o">=</span> <span class="mi">12</span><span class="p">,</span> <span class="c1">// no attribute
+</span> <span class="n">CLAP_EVENT_PAUSE</span> <span class="o">=</span> <span class="mi">13</span><span class="p">,</span> <span class="c1">// no attribute
+</span> <span class="n">CLAP_EVENT_STOP</span> <span class="o">=</span> <span class="mi">14</span><span class="p">,</span> <span class="c1">// no attribute
+</span>
+ <span class="n">CLAP_EVENT_TEMPO_CHANGED</span> <span class="o">=</span> <span class="mi">15</span><span class="p">,</span> <span class="c1">// attribute tempo
+</span> <span class="n">CLAP_EVENT_JUMP</span> <span class="o">=</span> <span class="mi">16</span><span class="p">,</span> <span class="c1">// attribute jump
</span><span class="p">};</span>
<span class="k">struct</span> <span class="n">clap_event_note</span>
<span class="p">{</span>
<span class="kt">uint8_t</span> <span class="n">key</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">pitch</span><span class="p">;</span>
-
+ <span class="kt">float</span> <span class="n">velocity</span><span class="p">;</span> <span class="c1">// 0..1
+</span>
<span class="k">struct</span> <span class="n">clap_event</span> <span class="o">*</span><span class="n">events</span><span class="p">;</span> <span class="c1">// events specific to this note
</span><span class="p">};</span>
<span class="k">struct</span> <span class="n">clap_event_param</span>
<span class="p">{</span>
- <span class="kt">uint32_t</span> <span class="n">index</span><span class="p">;</span>
- <span class="k">union</span> <span class="n">clap_param_value</span> <span class="n">value</span><span class="p">;</span>
+ <span class="cm">/* key/voice index */</span>
+ <span class="kt">bool</span> <span class="n">is_global</span><span class="p">;</span> <span class="c1">// is this event global?
+</span> <span class="kt">uint8_t</span> <span class="n">key</span><span class="p">;</span> <span class="c1">// if !is_global, target key
+</span>
+ <span class="cm">/* parameter */</span>
+ <span class="kt">uint32_t</span> <span class="n">index</span><span class="p">;</span> <span class="c1">// parameter index
+</span> <span class="k">union</span> <span class="n">clap_param_value</span> <span class="n">value</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">increment</span><span class="p">;</span> <span class="c1">// for param ramp
-</span> <span class="kt">char</span> <span class="n">display_text</span><span class="p">[</span><span class="n">CLAP_DISPLAY_SIZE</span><span class="p">];</span> <span class="c1">// use this for display if not NULL.
+</span> <span class="kt">char</span> <span class="n">display_text</span><span class="p">[</span><span class="n">CLAP_DISPLAY_SIZE</span><span class="p">];</span> <span class="c1">// use this for display.
</span> <span class="kt">bool</span> <span class="n">is_recordable</span><span class="p">;</span> <span class="c1">// used to tell the host if this event
</span> <span class="c1">// can be recorded
+</span> <span class="kt">bool</span> <span class="n">is_used</span><span class="p">;</span> <span class="c1">// is the parameter used in the patch?
</span><span class="p">};</span>
<span class="k">struct</span> <span class="n">clap_event_control</span>
<span class="p">{</span>
+ <span class="cm">/* voice/key index */</span>
+ <span class="kt">bool</span> <span class="n">is_global</span><span class="p">;</span> <span class="c1">// is this event global?
+</span> <span class="kt">uint8_t</span> <span class="n">key</span><span class="p">;</span> <span class="c1">// if !is_global, target key
+</span>
+ <span class="cm">/* control */</span>
<span class="kt">uint32_t</span> <span class="n">index</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">value</span><span class="p">;</span> <span class="c1">// 0 .. 1.0f
</span><span class="p">};</span>
<span class="k">struct</span> <span class="n">clap_event_preset</span>
<span class="p">{</span>
- <span class="kt">uint32_t</span> <span class="n">id</span><span class="p">;</span> <span class="c1">// the preset id
+ <span class="kt">char</span> <span class="n">url</span><span class="p">[</span><span class="n">CLAP_URL_SIZE</span><span class="p">];</span> <span class="c1">// the url to the preset
</span><span class="p">};</span>
<span class="k">struct</span> <span class="n">clap_event_midi</span>
<span class="p">{</span>
- <span class="kt">uint32_t</span> <span class="n">size</span><span class="p">;</span>
- <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">buffer</span><span class="p">;</span>
+ <span class="cm">/* voice/key index */</span>
+ <span class="kt">bool</span> <span class="n">is_global</span><span class="p">;</span> <span class="c1">// is this event global?
+</span> <span class="kt">uint8_t</span> <span class="n">key</span><span class="p">;</span> <span class="c1">// if !is_global, target key
+</span>
+ <span class="cm">/* midi event */</span>
+ <span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span><span class="n">buffer</span><span class="p">;</span>
+ <span class="kt">uint32_t</span> <span class="n">size</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="n">clap_event_latency</span>
@@ -1317,6 +1221,17 @@ big endian machine, it should load again successfully.</p>
<span class="kt">uint32_t</span> <span class="n">latency</span><span class="p">;</span>
<span class="p">};</span>
+<span class="k">struct</span> <span class="n">clap_event_tempo</span>
+<span class="p">{</span>
+ <span class="kt">uint32_t</span> <span class="n">tempo</span><span class="p">;</span> <span class="c1">// tempo in samples
+</span> <span class="kt">uint32_t</span> <span class="n">phase</span><span class="p">;</span> <span class="c1">// the phase in samples
+</span><span class="p">};</span>
+
+<span class="k">struct</span> <span class="n">clap_event_jump</span>
+<span class="p">{</span>
+ <span class="kt">uint32_t</span> <span class="n">song_time</span><span class="p">;</span> <span class="c1">// song time in samples
+</span><span class="p">};</span>
+
<span class="k">struct</span> <span class="n">clap_event</span>
<span class="p">{</span>
<span class="k">struct</span> <span class="n">clap_event</span> <span class="o">*</span><span class="n">next</span><span class="p">;</span> <span class="c1">// linked list, NULL on end
@@ -1324,12 +1239,14 @@ big endian machine, it should load again successfully.</p>
<span class="kt">uint64_t</span> <span class="n">steady_time</span><span class="p">;</span> <span class="c1">// steady_time of the event, see host->steady_time(host)
</span>
<span class="k">union</span> <span class="p">{</span>
- <span class="k">struct</span> <span class="n">clap_event_note</span> <span class="n">note</span><span class="p">;</span>
- <span class="k">struct</span> <span class="n">clap_event_param</span> <span class="n">param</span><span class="p">;</span>
- <span class="k">struct</span> <span class="n">clap_event_preset</span> <span class="n">preset</span><span class="p">;</span>
- <span class="k">struct</span> <span class="n">clap_event_midi</span> <span class="n">midi</span><span class="p">;</span>
- <span class="k">struct</span> <span class="n">clap_event_control</span> <span class="n">control</span><span class="p">;</span>
- <span class="k">struct</span> <span class="n">clap_event_latency</span> <span class="n">latency</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_note</span> <span class="n">note</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_param</span> <span class="n">param</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_preset</span> <span class="n">preset</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_midi</span> <span class="n">midi</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_control</span> <span class="n">control</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_latency</span> <span class="n">latency</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_tempo</span> <span class="n">tempo</span><span class="p">;</span>
+ <span class="k">struct</span> <span class="n">clap_event_jump</span> <span class="n">jump</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">};</span>
@@ -1337,33 +1254,31 @@ big endian machine, it should load again successfully.</p>
// PROCESS //
/////////////
</span>
-<span class="k">struct</span> <span class="n">clap_process</span>
+<span class="k">enum</span> <span class="n">clap_process_status</span>
<span class="p">{</span>
- <span class="cm">/* host custom ptr */</span>
- <span class="kt">void</span> <span class="o">*</span><span class="n">host_data</span><span class="p">;</span>
+ <span class="cm">/* Processing failed. The output buffer must be discarded. */</span>
+ <span class="n">CLAP_PROCESS_ERROR</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
+
+ <span class="cm">/* Processing succeed. */</span>
+ <span class="n">CLAP_PROCESS_CONTINUE</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
+
+ <span class="cm">/* Processing succeed, but no more processing is required, until next event. */</span>
+ <span class="n">CLAP_PROCESS_STOP</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
+<span class="p">};</span>
+<span class="k">struct</span> <span class="n">clap_process</span>
+<span class="p">{</span>
<span class="cm">/* audio buffers */</span>
<span class="kt">float</span> <span class="o">**</span><span class="n">input</span><span class="p">;</span>
<span class="kt">float</span> <span class="o">**</span><span class="n">output</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">samples_count</span><span class="p">;</span>
- <span class="cm">/* feedback loops */</span>
- <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">feedback</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_process</span> <span class="o">*</span><span class="n">process</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">stream_id</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">nb_samples</span><span class="p">);</span>
- <span class="kt">uint32_t</span> <span class="n">feedback_chunk_size</span><span class="p">;</span>
-
<span class="cm">/* process info */</span>
- <span class="kt">bool</span> <span class="n">is_offline</span><span class="p">;</span>
- <span class="kt">uint32_t</span> <span class="n">tempo</span><span class="p">;</span> <span class="c1">// the tempo in samples
-</span> <span class="kt">uint64_t</span> <span class="n">song_time</span><span class="p">;</span> <span class="c1">// the song time in samples
+ <span class="kt">uint64_t</span> <span class="n">song_time</span><span class="p">;</span> <span class="c1">// the song time in samples
</span> <span class="kt">uint64_t</span> <span class="n">steady_time</span><span class="p">;</span> <span class="c1">// the steady time in samples
</span>
<span class="cm">/* events */</span>
<span class="k">struct</span> <span class="n">clap_event</span> <span class="o">*</span><span class="n">events</span><span class="p">;</span>
-
- <span class="cm">/* output values */</span>
- <span class="kt">bool</span> <span class="n">need_processing</span><span class="p">;</span>
<span class="p">};</span>
<span class="c1">//////////
@@ -1375,10 +1290,10 @@ big endian machine, it should load again successfully.</p>
<span class="kt">uint32_t</span> <span class="n">clap_version</span><span class="p">;</span> <span class="c1">// initialized to CLAP_VERSION
</span>
<span class="cm">/* returns the size of the original string, 0 if not string */</span>
- <span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_attribute</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">attr</span><span class="p">,</span>
- <span class="kt">char</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">size</span><span class="p">);</span>
+ <span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_attribute</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_host</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span>
+ <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">attr</span><span class="p">,</span>
+ <span class="kt">char</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">size</span><span class="p">);</span>
<span class="cm">/* for events generated by the plugin. */</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">events</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_host</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span>
@@ -1392,10 +1307,11 @@ big endian machine, it should load again successfully.</p>
<span class="cm">/* Log a message through the host. */</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">log</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_host</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span>
+ <span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
<span class="k">enum</span> <span class="n">clap_log_severity</span> <span class="n">severity</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span><span class="p">);</span>
- <span class="cm">/* future features */</span>
+ <span class="cm">/* feature extensions */</span>
<span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">extension</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_host</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">extention_id</span><span class="p">);</span>
<span class="p">};</span>
@@ -1419,64 +1335,28 @@ big endian machine, it should load again successfully.</p>
<span class="kt">void</span> <span class="o">*</span><span class="n">host_data</span><span class="p">;</span> <span class="c1">// reserved pointer for the host
</span> <span class="kt">void</span> <span class="o">*</span><span class="n">plugin_data</span><span class="p">;</span> <span class="c1">// reserved pointer for the plugin
</span>
- <span class="cm">/* free plugin's resources */</span>
+ <span class="cm">/* Free the plugin and its resources.
+ * It is not required to deactivate the plugin prior to this call. */</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">destroy</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
- <span class="cm">/* returns the size of the original string, 0 if not string */</span>
+ <span class="cm">/* Copy at most size of the attribute's value into buffer.
+ * This function must place a '\0' byte at the end of the string.
+ * Returns the size of the original string or 0 if there is no
+ * value for this attributes. */</span>
<span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_attribute</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">attr</span><span class="p">,</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span>
<span class="kt">uint32_t</span> <span class="n">size</span><span class="p">);</span>
- <span class="cm">/* Audio ports.
- * The port configuration has to be done while the plugin is deactivated. */</span>
- <span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_ports_configs_count</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">get_ports_config</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">config_index</span><span class="p">,</span>
- <span class="k">struct</span> <span class="n">clap_ports_config</span> <span class="o">*</span><span class="n">config</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">get_port_info</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">config_index</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">port_index</span><span class="p">,</span>
- <span class="k">struct</span> <span class="n">clap_port_info</span> <span class="o">*</span><span class="n">port</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">set_ports_config</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">config_index</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">set_port_repeat</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">port_index</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">count</span><span class="p">);</span>
-
- <span class="cm">/* Returns a newly allocated parameters tree. The caller has to free it. */</span>
- <span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_params_count</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">get_param</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">index</span><span class="p">,</span>
- <span class="k">struct</span> <span class="n">clap_param</span> <span class="o">*</span><span class="n">param</span><span class="p">);</span>
-
- <span class="cm">/* Returns a newly allocated preset list. The caller has to free it. */</span>
- <span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_presets_count</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">get_preset</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
- <span class="kt">uint32_t</span> <span class="n">index</span><span class="p">,</span>
- <span class="k">struct</span> <span class="n">clap_preset</span> <span class="o">*</span><span class="n">preset</span><span class="p">);</span>
-
<span class="cm">/* activation */</span>
<span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">activate</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">deactivate</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
- <span class="cm">/* work */</span>
- <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">process</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span> <span class="k">struct</span> <span class="n">clap_process</span> <span class="o">*</span><span class="n">process</span><span class="p">);</span>
+ <span class="cm">/* process */</span>
+ <span class="k">enum</span> <span class="nf">clap_process_status</span> <span class="p">(</span><span class="o">*</span><span class="n">process</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
+ <span class="k">struct</span> <span class="n">clap_process</span> <span class="o">*</span><span class="n">process</span><span class="p">);</span>
- <span class="cm">/* gui */</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">open_gui</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
- <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">close_gui</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
-
- <span class="cm">/* The plugin has to allocate and save its state into *buffer.
- * The plugin is also responsible to free the buffer on the
- * next call to save() or when the plugin is destroyed. */</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">save</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span> <span class="kt">void</span> <span class="o">**</span><span class="n">buffer</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="o">*</span><span class="n">size</span><span class="p">);</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">restore</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">size</span><span class="p">);</span>
-
- <span class="cm">/* Sets the locale to use */</span>
- <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">set_locale</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">locale</span><span class="p">);</span>
-
- <span class="cm">/* future features */</span>
+ <span class="cm">/* features extensions */</span>
<span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">extension</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">id</span><span class="p">);</span>
<span class="p">};</span>
@@ -1489,7 +1369,9 @@ big endian machine, it should load again successfully.</p>
<span class="cm">/* Plugin entry point. If plugins_count is not null, then clap_create has
* to store the number of plugins available in *plugins_count.
* If clap_create failed to create a plugin, it returns NULL.
- * The return value has to be freed by calling plugin->destroy(plugin). */</span>
+ * The return value has to be freed by calling plugin->destroy(plugin).
+ *
+ * This function must be thread-safe. */</span>
<span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span>
<span class="nf">clap_create</span><span class="p">(</span><span class="kt">uint32_t</span> <span class="n">plugin_index</span><span class="p">,</span>
<span class="k">struct</span> <span class="n">clap_host</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span>
@@ -1503,36 +1385,99 @@ big endian machine, it should load again successfully.</p>
<span class="cp">#endif </span><span class="cm">/* !CLAP_H */</span>
</pre>
</div>
-<div class="section" id="clap-embed-h">
-<h2><a class="toc-backref" href="#id53">clap-embed.h</a></h2>
+<div class="section" id="clap-ext-ports-h">
+<h2><a class="toc-backref" href="#id52">clap/ext/ports.h</a></h2>
+<pre class="code c literal-block">
+<span class="cp">#ifndef CLAP_EXT_PORTS_H
+# define CLAP_EXT_PORTS_H
+</span>
+<span class="cp"># include "../clap.h"
+</span>
+<span class="cp"># define CLAP_EXT_PORTS "clap/ports"
+</span>
+<span class="k">enum</span> <span class="n">clap_port_type</span>
+<span class="p">{</span>
+ <span class="n">CLAP_PORT_MONO</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">CLAP_PORT_STEREO</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
+ <span class="n">CLAP_PORT_SURROUND</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span>
+<span class="p">};</span>
+
+<span class="k">enum</span> <span class="n">clap_port_role</span>
+<span class="p">{</span>
+ <span class="n">CLAP_PORT_INOUT</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">CLAP_PORT_SIDECHAIN</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
+<span class="p">};</span>
+
+<span class="k">struct</span> <span class="n">clap_port_info</span>
+<span class="p">{</span>
+ <span class="k">enum</span> <span class="n">clap_port_type</span> <span class="n">type</span><span class="p">;</span>
+ <span class="k">enum</span> <span class="n">clap_port_role</span> <span class="n">role</span><span class="p">;</span>
+ <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span>
+ <span class="kt">bool</span> <span class="n">is_repeatable</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="k">struct</span> <span class="n">clap_ports_config</span>
+<span class="p">{</span>
+ <span class="kt">char</span> <span class="n">name</span><span class="p">[</span><span class="n">CLAP_NAME_SIZE</span><span class="p">];</span>
+ <span class="kt">uint32_t</span> <span class="n">inputs_count</span><span class="p">;</span>
+ <span class="kt">uint32_t</span> <span class="n">outputs_count</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="cm">/* The audio ports configuration has to be done while the plugin is
+ * deactivated. */</span>
+<span class="k">struct</span> <span class="n">clap_plugin_ports</span>
+<span class="p">{</span>
+ <span class="cm">/* Returns the number of available configurations */</span>
+ <span class="kt">uint32_t</span> <span class="p">(</span><span class="o">*</span><span class="n">get_configs_count</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
+ <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">get_config</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">config_index</span><span class="p">,</span>
+ <span class="k">struct</span> <span class="n">clap_ports_config</span> <span class="o">*</span><span class="n">config</span><span class="p">);</span>
+ <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">get_info</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">config_index</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">port_index</span><span class="p">,</span>
+ <span class="k">struct</span> <span class="n">clap_port_info</span> <span class="o">*</span><span class="n">port</span><span class="p">);</span>
+ <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">set_config</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">config_index</span><span class="p">);</span>
+ <span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">set_repeat</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">port_index</span><span class="p">,</span>
+ <span class="kt">uint32_t</span> <span class="n">count</span><span class="p">);</span>
+<span class="p">};</span>
+
+<span class="cp">#endif </span><span class="cm">/* !CLAP_EXT_PORT_H */</span>
+</pre>
+</div>
+<div class="section" id="clap-ext-embed-h">
+<h2><a class="toc-backref" href="#id53">clap/ext/embed.h</a></h2>
<pre class="code c literal-block">
-<span class="cp">#ifndef CLAP_EMBED_H
-# define CLAP_EMBED_H
+<span class="cp">#ifndef CLAP_EXT_EMBED_H
+# define CLAP_EXT_EMBED_H
</span>
-<span class="cp"># include "clap.h"
+<span class="cp"># include "../clap.h"
</span>
-<span class="cp"># define CLAP_EMBED "clap/embed"
+<span class="cp"># define CLAP_EXT_EMBED "clap/embed"
</span>
<span class="k">struct</span> <span class="n">clap_host_embed</span>
<span class="p">{</span>
+ <span class="cm">/* Request the host to resize the client area to width, height.
+ * Return true on success, false otherwise. */</span>
<span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">resize</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_host</span> <span class="o">*</span><span class="n">host</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">width</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="n">height</span><span class="p">);</span>
<span class="p">};</span>
-<span class="cp">#endif </span><span class="cm">/* !CLAP_EMBED_H */</span>
+<span class="cp">#endif </span><span class="cm">/* !CLAP_EXT_EMBED_H */</span>
</pre>
</div>
-<div class="section" id="clap-embed-win32-h">
-<h2><a class="toc-backref" href="#id54">clap-embed-win32.h</a></h2>
+<div class="section" id="clap-ext-embed-win32-h">
+<h2><a class="toc-backref" href="#id54">clap/ext/embed-win32.h</a></h2>
<pre class="code c literal-block">
-<span class="cp">#ifndef CLAP_EMBED_WIN32_H
-# define CLAP_EMBED_WIN32_H
+<span class="cp">#ifndef CLAP_EXT_EMBED_WIN32_H
+# define CLAP_EXT_EMBED_WIN32_H
</span>
<span class="cp"># include <windows.h>
</span>
-<span class="cp"># include "clap.h"
-# include "clap-embed.h"
+<span class="cp"># include "../clap.h"
+# include "embed.h"
</span>
-<span class="cp"># define CLAP_EMBED_WIN32 "clap/embed/win32"
+<span class="cp"># define CLAP_EXT_EMBED_WIN32 "clap/embed/win32"
</span>
<span class="k">struct</span> <span class="n">clap_plugin_embed_win32</span>
<span class="p">{</span>
@@ -1541,27 +1486,30 @@ big endian machine, it should load again successfully.</p>
<span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">disembed</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">);</span>
<span class="p">};</span>
-<span class="cp">#endif </span><span class="cm">/* !CLAP_EMBED_WIN32_H */</span>
+<span class="cp">#endif </span><span class="cm">/* !CLAP_EXT_EMBED_WIN32_H */</span>
</pre>
</div>
-<div class="section" id="clap-embed-xlib-h">
-<h2><a class="toc-backref" href="#id55">clap-embed-xlib.h</a></h2>
+<div class="section" id="clap-ext-embed-xlib-h">
+<h2><a class="toc-backref" href="#id55">clap/ext/embed-xlib.h</a></h2>
<pre class="code c literal-block">
-<span class="cp">#ifndef CLAP_EMBED_XLIB_H
-# define CLAP_EMBED_XLIB_H
+<span class="cp">#ifndef CLAP_EXT_EMBED_XLIB_H
+# define CLAP_EXT_EMBED_XLIB_H
</span>
<span class="cp"># include <X11/Xlib.h>
</span>
-<span class="cp"># include "clap.h"
-# include "clap-embed.h"
+<span class="cp"># include "../clap.h"
+# include "embed.h"
</span>
-<span class="cp"># define CLAP_EMBED_XLIB "clap/embed/xlib"
+<span class="cp"># define CLAP_EXT_EMBED_XLIB "clap/embed/xlib"
</span>
<span class="k">struct</span> <span class="n">clap_plugin_embed_xlib</span>
<span class="p">{</span>
<span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">get_size</span><span class="p">)(</span><span class="kt">uint32_t</span> <span class="o">*</span><span class="n">width</span><span class="p">,</span> <span class="kt">uint32_t</span> <span class="o">*</span><span class="n">height</span><span class="p">);</span>
- <span class="cm">/* the display_name can be retrieved from your own
+ <span class="cm">/* Note for the client, you can get a Display* by calling
+ * XOpenDisplay(display_name).
+ *
+ * Note for the host, the display_name can be retrieved from your own
* display->display_name. */</span>
<span class="kt">bool</span> <span class="p">(</span><span class="o">*</span><span class="n">embed</span><span class="p">)(</span><span class="k">struct</span> <span class="n">clap_plugin</span> <span class="o">*</span><span class="n">plugin</span><span class="p">,</span>
<span class="n">Window</span> <span class="n">window</span><span class="p">,</span>
diff --git a/spec.rst b/spec.rst
@@ -11,43 +11,22 @@ A free audio plugin format
Goals
=====
-- Make a free audio plugin format
+- Make a free digital instrument and effect plugin format
- Be easy to understand and implement
- Bring new features missed in VST 2.4
-- Designed to work on any operating system
+- Designed to work on any operating system and processor architecture
- Be event oriented
-- Be extensible without breaking existing plugins
+- Be extensible without breaking existing interface
- Be easy to bridge
-
-Later goals
------------
-
-- Provide a reference host
-- Provide some reference plugins
-- Provide a validation plugin, which should signal anything wrong the host does
-- Provide a validation host, which should give hard time to the plugin and
- ensure that basic functionnality are working
-- Provide a libclap2vst, which adapts a clap plugin interface to a vst plugin
- interface
-- Provide a remote plugin/host library
-- Provide a libvst2clap, which adapts a vst plugin interface to a clap plugin
- interface
+- Support dynamic configuration: let a modular plugin dynamically
+ add new parameters, new outputs/inputs, etc...
Design choice
-------------
-- The plugin and the host interface must be thread-safe.
-- Avoid pointer exchange between the host and the plugin
- whenever it is possible. The chosen way is to pass a buffer
- as a parameter and let the host/plugin copy/read data from it.
- Rationale: as the host and the plugin can be multi-threaded,
- keeping pointers to the plugin or host internal memory can lead
- to race conditions. Also it can lead to ambiguities about who's
- responsible to free the memory. Also the host and the plugin
- may use custom allocator.
-- Use the C language.
-- Have support for dynamic configuration, to let a modular plugin
- add new parameters, new outputs/inputs, etc... dynamically.
+- Use the C language for the interface.
+- The host interface must be thread-safe.
+- The plugin interface is not thread-safe.
Specification
=============
@@ -56,7 +35,7 @@ How to read the specification
-----------------------------
The specification should be read along the reference headers.
-https://abique.github.io/clap/ gives a convinient view for that.
+https://free-audio.github.io/clap/ gives a convinient view for that.
Encoding
--------
@@ -123,9 +102,9 @@ built for the native/current architecture.
Instantiate a plugin
--------------------
-Plugin instantiating can be done in a few steps:
+Plugin instantiation can be done in a few steps:
-- load the plugin library
+- load the plugin library with ``dlopen`` or symilar functions
- find the symbol ``clap_create``
- instantiate the plugin by calling ``clap_create``
@@ -136,12 +115,21 @@ Precautions
- It must not throw exceptions.
- It can return ``NULL``.
+Release a plugin
+~~~~~~~~~~~~~~~~
+
+To release a plugin, call ``plugin->destroy(plugin);``.
+It is not required to deactivate the plugin prior to destroy it.
+
Plugins collection
~~~~~~~~~~~~~~~~~~
-A single dynamic library can contains multiple clap plugins.
-To list them, you have to call ``clap_create`` with an index of 0 and increment
-the index until you reach ``plugin_count``.
+A single shared library can contains multiple clap plugins.
+To list them, you have to call ``clap_create`` with an index of 0.
+``clap_create`` will store the number of plugins in the collection
+into the parameter ``*plugins_count``. After that you can create any
+of them by using an ``index`` between ``0`` and ``*plugins_count``.
+
``clap_create`` returns ``NULL`` if the plugin creation failed or if
``plugin_index >= plugin_count``.
@@ -150,60 +138,53 @@ Sample plugin loader
See `examples/clap-info/clap-info.c`_
-Description
-~~~~~~~~~~~
+Plugin description
+~~~~~~~~~~~~~~~~~~
-Both the ``struct clap_plugin;`` and ``struct clap_host;`` have a few attribute giving
-general plugin/host information.
-
-+---------------------+---------------------------------------------------------------+
-| Attribute | Description |
-+=====================+===============================================================+
-| clap_version | Described the plugin format version implemented. Should be |
-| | initialized with CLAP_PLUGIN_VERSION, |
-| | or CLAP_VERSION_MAKE(1, 0, 0) if you want to only support |
-| | version 1.0.0 |
-+---------------------+---------------------------------------------------------------+
-| id | Unique identifier of the plugin. It should never change. It |
-| | should be the same on any plateform. |
-+---------------------+---------------------------------------------------------------+
-| name | The name of the product. |
-+---------------------+---------------------------------------------------------------+
-| description | A brief description of the product. |
-+---------------------+---------------------------------------------------------------+
-| manufacturer | Which company made the plugin. |
-+---------------------+---------------------------------------------------------------+
-| version | A string describing the product version. |
-+---------------------+---------------------------------------------------------------+
-| url | An URL to the product homepage. |
-+---------------------+---------------------------------------------------------------+
-| license | The plugin license type, Custom, GPLv3, MIT, ... |
-+---------------------+---------------------------------------------------------------+
-| support | A link to the support, it can be |
-| | ``mailto:support@company.com`` or |
-| | ``http://company.com/support``. |
-+---------------------+---------------------------------------------------------------+
-| categories | A string containing a list of categories, joined with ``;``. |
-| | For example: ``fm;analogue;delay``. |
-+---------------------+---------------------------------------------------------------+
-| type | Bitfield describing what the plugin does. See |
-| | ``enum clap_plugin_type``. |
-+---------------------+---------------------------------------------------------------+
-| chunk_size | The process buffer, must have a number of sample multiple of |
-| | ``chunk_size``. |
-+---------------------+---------------------------------------------------------------+
-| latency | The latency introduced by the plugin. |
-+---------------------+---------------------------------------------------------------+
-| has_gui | True if the plugin can show a graphical user interface |
-+---------------------+---------------------------------------------------------------+
-| supports_tuning | True if the plugin supports tuning |
-+---------------------+---------------------------------------------------------------+
-| supports_microtones | True if the plugin supports micro tones |
-+---------------------+---------------------------------------------------------------+
-| host_data | Reserved pointer for the host. |
-+---------------------+---------------------------------------------------------------+
-| plugin_data | Reserved pointer for the plugin. |
-+---------------------+---------------------------------------------------------------+
+``struct clap_plugin`` only contains a interger ``clap_version`` which
+indicates which version of the clap interface has been used to build the plugin, and
+a few methods. This attribute must be initialized by the plugin with
+``CLAP_PLUGIN_VERSION``.
+
+Then to get plugin's attribute, you have to use ``plugin->get_attribute(plugin, ...)``.
+
++--------------------------------+---------------------------------------------------------------+
+| Attribute | Description |
++================================+===============================================================+
+| CLAP_ATTR_ID | Unique identifier of the plugin. It should never change. It |
+| | should be the same on any plateform. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_NAME | The name of the product. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_DESCRIPTION | A brief description of the product. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_MANUFACTURER | Which company made the plugin. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_VERSION | A string describing the product version. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_URL | An URL to the product homepage. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_LICENSE | The plugin license type, Custom, GPLv3, MIT, ... |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_SUPPORT | A link to the support, it can be |
+| | ``mailto:support@company.com`` or |
+| | ``http://company.com/support``. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_CATEGORIES | A string containing a list of categories, joined with ``;``. |
+| | For example: ``fm;analogue;delay``. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_TYPE | Bitfield describing what the plugin does. See |
+| | ``enum clap_plugin_type``. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_CHUNK_SIZE | The process buffer, must have a number of sample multiple of |
+| | ``chunk_size``. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_LATENCY | The latency introduced by the plugin. |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_SUPPORTS_TUNING | True if the plugin supports tuning |
++--------------------------------+---------------------------------------------------------------+
+| CLAP_ATTR_IS_REMOTE_PROCESSING | True if the plugin supports tuning |
++--------------------------------+---------------------------------------------------------------+
Audio ports configuration
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -212,7 +193,8 @@ A plugin may have multiple audio ports, and so multiple audio ports
layout or configurations.
An audio port has a type: mono, stereo, surround and a role: main
-input/output, sidechain, feedback.
+input/output or sidechain. We might add a feedback role in the futur
+if there is a need for it.
Pin layout
``````````
@@ -243,7 +225,24 @@ Pin layout
| | 7 | surround back right |
+----------+-----+---------------------+
-So for the following configuration:
+Configurations
+``````````````
+
+After the call to ``clap_create()`` the new plugin uses the default ports
+configuration: 1 stereo input and 1 stereo output. So if you're fine with
+it, there is nothing more to do.
+
+If a plugins wants to offer more ports configuration to the host/user, it
+has to use ports extension. See `clap/ext/ports.h`_.
+
+The host can select a ports configuration only if the plugin is in
+the deactivated state.
+
+Note that if the plugin does not support the default configuration
+which is stereo input and stereo output, then it must return false
+during the plugin activation (``plugin->activate(plugin)``).
+
+Here is a configuration for a stereo sidechain compressor:
+--------+----------+------------+---------------------+-----------------+
| in/out | type | role | buffer | desc |
@@ -256,29 +255,36 @@ So for the following configuration:
| | | +---------------------+-----------------+
| | | | process->inputs[3] | right sidechain |
+--------+----------+------------+---------------------+-----------------+
-| input | stereo | feedback | process->inputs[4] | left feedback |
-| | | +---------------------+-----------------+
-| | | | process->inputs[5] | right feedback |
-+--------+----------+------------+---------------------+-----------------+
| output | stereo | inout | process->outputs[0] | left input |
| | | +---------------------+-----------------+
| | | | process->outputs[1] | right input |
+--------+----------+------------+---------------------+-----------------+
-| output | stereo | feedback | process->outputs[2] | left feedback |
-| | | +---------------------+-----------------+
-| | | | process->outputs[3] | right feedback |
-+--------+----------+------------+---------------------+-----------------+
-Available configurations
-````````````````````````
+Getting the ports configurations
+````````````````````````````````
+
+.. code:: c
+
+ #include <clap/ext/ports.h>
+
+ struct clap_plugin_ports *ports = plugin->extension(plugin, CLAP_EXT_PORTS);
+ if (!ports)
+ return; // no ports extensions
+ uint32_t count = ports->get_configs_count(plugin);
+ for (uint32_t i = 0; i < count; ++i) {
+ struct clap_ports_config config;
+ if (!ports->get_config(plugin, i, &config))
+ continue;
+ // ...
+ }
It is possible to discover a plugin's port configurations by calling
-``plugin->get_ports_configs_count(plugin);``. It returns the number of
+``ports->get_configs_count(plugin);``. It returns the number of
configurations. Then for each configuration you have to call
-``plugin->get_ports_config(plugin, config_index, &config);`` which will
+``ports->get_config(plugin, config_index, &config);`` which will
tell you the number of input and output ports. Then to get the port details,
you have to call
-``plugin->get_port_info(plugin, config_index, port_index, &port);``.
+``ports->get_info(plugin, config_index, port_index, &port);``.
Selecting a configuration
`````````````````````````
@@ -300,58 +306,11 @@ spectroscope.
For the special case of repeatable side chain input, the host
has to tell the plugin how many times the port should be repeated.
-To do that it has to call ``plugin->set_port_repeat(plugin, port_index, count)``.
+To do that it has to call ``plugin->set_repeat(plugin, port_index, count)``.
If it returns ``false`` then the plugin is in the same state as before
the call.
-Feedback stream
-```````````````
-
-Feedback stream are used to plug external audio processing into one
-of the plugin feedback loop.
-
-A practical usage is to put an effect in a delay feedback loop.
-
-A feedback loop has it's both ends identified by ``clap_channel->stream_id``.
-
-During the audio processing, ``struct clap_process`` contains a callback which
-is used to process the feedback stream:
-
-.. code:: c
-
- void my_plugin_process(struct clap_plugin *plugin, struct clap_process *process)
- {
- uint32_t fb_in; // index to the stereo feedback input buffer
- uint32_t fb_out; // index to the stereo feedback output buffer
- uint32_t stream_id; // the feedback stream id
- uint32_t offset;
-
- // process all the buffer
- for (offset = 0; offset < process->samples_count;
- offset += process->feedback_chunk_size)
- {
-
- // ...
-
- // prepare feedback output buffer
- for (uint32_t i = 0; i < process->feedback_chunk_size; ++i) {
- process->output[fb_out][offset + i] = XXX;
- process->output[fb_out + 1][offset + i] = XXX;
- }
-
- // process one sample feedback
- process->feedback(process, stream_id, process->feedback_chunk_size);
-
- // audio processing of the feedback values:
- // process->input[fb_in][offset + i]
- // process->input[fb_in + 1][offset + i]
- }
- }
-
-Threading
----------
-
-The plugin must be thread safe.
+Only inputs can be repeatable.
Activation
----------
@@ -366,8 +325,8 @@ The host must not call ``activate()`` if the plugin is already activated.
Yet the plugin should handle correctly double calls to ``activate()``.
The plugin activation could be nothing, or could be a task which takes time,
-like connecting a remote server. So the host should not activate plugins in
-the audio processing thread.
+like connecting a remote server or device.
+So the host should not activate plugins in the audio processing thread.
To deactivate the plugin, just call ``plugin->deactivate(plugin)``. Like
``activate()``, ``deactivate()`` should not be called from the audio processing
@@ -377,7 +336,8 @@ Also ``deactivate()`` should not be called if the plugin is not activated.
Yet the plugin should handle a call to ``deactivate()`` even if it is
not activated.
-It is preferable to de-activate the plugin before destroying it.
+It is recommended (but not mandatory) to de-activate the plugin before
+destroying it.
Processing
----------
@@ -386,10 +346,23 @@ The processing is done in one call: ``plugin->process(plugin, process);``.
The data structure process regroup everything needed by the plugin:
- audio buffers (in, out)
-- feedback process callback
- events (in)
-- tempo, time, is offline? (in)
-- more processing needed (out)
+- some time info
+
+Once the processing is finished, the methods returns a process status
+which can be:
+
+
++-----------------------+-------------------------------------------------------------+
+| Status | Meaning |
++=======================+=============================================================+
+| CLAP_PROCESS_ERROR | An error happened, and the buffers should be discarded |
++-----------------------+-------------------------------------------------------------+
+| CLAP_PROCESS_CONTINUE | Succeed, the plugins wants to process the next block |
++-----------------------+-------------------------------------------------------------+
+| CLAP_PROCESS_STOP | Succeed, every voices terminated, wake me up on a new event |
++-----------------------+-------------------------------------------------------------+
+
Audio buffers
~~~~~~~~~~~~~
@@ -397,15 +370,16 @@ Audio buffers
- The audio buffers are allocated by the host. They must be aligned by the
maximum requirement of the vector instructions currently available.
- In-place processing is not supported.
-- The number of samples must be a multiple of ``plugin->chunk_size``.
+- The number of samples must be a multiple of the plugin chunk_size.
- See `Pin layout`_.
+- See `Plugin description`_
Events
~~~~~~
- Event's time must be within the process duration:
``[process->steady_time .. process->steady_time + process->nb_sambles]``.
-- The plugin must not modify the input events (``in_events``).
+- The plugin must not modify the events.
Notes
`````
@@ -562,15 +536,15 @@ Some host are designed to embed plugin's window.
As embedding is not a Clap requirement, it is offered as an extension.
Also the OS dependency brought by this feature makes it ideal as an extension.
-+------------+-----------------------+----------------------+----------------+
-| GUI | header | extension | comment |
-+============+=======================+======================+================+
-| Generic | `clap-embed.h`_ | ``CLAP_EMBED`` | For the host |
-+------------+-----------------------+----------------------+----------------+
-| Windows | `clap-embed-win32.h`_ | ``CLAP_EMBED_WIN32`` | For the plugin |
-+------------+-----------------------+----------------------+----------------+
-| X11 | `clap-embed-xlib.h`_ | ``CLAP_EMBED_XLIB`` | For the plugin |
-+------------+-----------------------+----------------------+----------------+
++------------+---------------------------+----------------------+----------------+
+| GUI | header | extension | comment |
++============+===========================+======================+================+
+| Generic | `clap/ext/embed.h`_ | ``CLAP_EMBED`` | For the host |
++------------+---------------------------+----------------------+----------------+
+| Windows | `clap/ext/embed-win32.h`_ | ``CLAP_EMBED_WIN32`` | For the plugin |
++------------+---------------------------+----------------------+----------------+
+| X11 | `clap/ext/embed-xlib.h`_ | ``CLAP_EMBED_XLIB`` | For the plugin |
++------------+---------------------------+----------------------+----------------+
Example on Windows
``````````````````
@@ -673,26 +647,32 @@ examples/clap-info/clap-info.c
References
==========
-clap.h
-------
+clap/clap.h
+-----------
.. include:: include/clap/clap.h
:code: c
-clap-embed.h
-------------
+clap/ext/ports.h
+----------------
+
+.. include:: include/clap/ext/ports.h
+ :code: c
+
+clap/ext/embed.h
+----------------
-.. include:: include/clap/clap-embed.h
+.. include:: include/clap/ext/embed.h
:code: c
-clap-embed-win32.h
-------------------
+clap/ext/embed-win32.h
+----------------------
-.. include:: include/clap/clap-embed-win32.h
+.. include:: include/clap/ext/embed-win32.h
:code: c
-clap-embed-xlib.h
------------------
+clap/ext/embed-xlib.h
+---------------------
-.. include:: include/clap/clap-embed-xlib.h
+.. include:: include/clap/ext/embed-xlib.h
:code: c