commit 075d5b000b32166993d07e6025430a6fe5a502cd
parent bf3e6e5532ff4937cad88627cda2c6f99f29b6ec
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date: Thu, 13 Oct 2016 07:32:05 +0200
Update the spec
Diffstat:
M | include/clap/clap.h | | | 6 | +++--- |
M | spec.html | | | 173 | +++++++++++++++++++++++++++++++------------------------------------------------ |
M | spec.rst | | | 113 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
3 files changed, 121 insertions(+), 171 deletions(-)
diff --git a/include/clap/clap.h b/include/clap/clap.h
@@ -274,7 +274,7 @@ struct clap_host
const char *msg);
/* query an extension */
- void *(*extension)(struct clap_host *host, const char *extention_id);
+ const void *(*extension)(struct clap_host *host, const char *extention_id);
};
////////////
@@ -323,7 +323,7 @@ struct clap_plugin
struct clap_process *process);
/* query an extension */
- void *(*extension)(struct clap_plugin *plugin, const char *id);
+ const void *(*extension)(struct clap_plugin *plugin, const char *id);
};
/* This interface is the entry point of the dynamic library.
@@ -354,7 +354,7 @@ struct clap_plugin_factory
};
/* Entry point */
-CLAP_EXPORT extern struct clap_plugin_factory *clap_plugin_factory;
+CLAP_EXPORT extern const struct clap_plugin_factory *clap_plugin_factory;
# ifdef __cplusplus
}
diff --git a/spec.html b/spec.html
@@ -111,7 +111,7 @@ tt.docutils {
<li><a class="reference internal" href="#specification" id="id3">Specification</a><ul>
<li><a class="reference internal" href="#how-to-read-the-specification" id="id4">How to read the specification</a></li>
<li><a class="reference internal" href="#encoding" id="id5">Encoding</a></li>
-<li><a class="reference internal" href="#c-execptions" id="id6">C++ execptions</a></li>
+<li><a class="reference internal" href="#c-exceptions" id="id6">C++ exceptions</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>
@@ -184,21 +184,25 @@ tt.docutils {
<ul class="simple">
<li>Make a free digital instrument and effect plugin interface</li>
<li>Be easy to understand and implement</li>
-<li>Don't require alien technology, or masoshist design
-- Based on C, not Objective-C or C++
-- No dependancy on external libraries
-- No serialization format
-- No C++ multiple inheritence
-- No macro obfuscation
-- No object file to compile in the SDK, CLAP is an interface only.
-- Simple resource management mechanism</li>
+<li>Don't require alien technology, or masoshist design<ul>
+<li>Based on C, not Objective-C or C++</li>
+<li>No dependancy on external libraries</li>
+<li>No serialization format</li>
+<li>No C++ multiple inheritence</li>
+<li>No macro obfuscation</li>
+<li>No object file to compile in the SDK, CLAP is an interface only.</li>
+<li>Simple resource management mechanism</li>
+</ul>
+</li>
<li>Designed to work on any operating system and processor architecture</li>
<li>Be event oriented</li>
<li>Be extensible</li>
<li>Be easy to bridge</li>
-<li>Dynamics
-- dynamic ports
-- dynamic parameters</li>
+<li>Dynamics<ul>
+<li>dynamic ports</li>
+<li>dynamic parameters</li>
+</ul>
+</li>
<li>Full MIDI</li>
</ul>
</div>
@@ -214,8 +218,8 @@ tt.docutils {
<p>All the strings exchanged through the CLAP interface must be encoded
in valid UTF-8.</p>
</div>
-<div class="section" id="c-execptions">
-<h2><a class="toc-backref" href="#id6">C++ execptions</a></h2>
+<div class="section" id="c-exceptions">
+<h2><a class="toc-backref" href="#id6">C++ exceptions</a></h2>
<p>A CLAP interface must not send exception.</p>
</div>
<div class="section" id="plugins-location">
@@ -236,7 +240,7 @@ in valid UTF-8.</p>
<div class="section" id="windows">
<h3><a class="toc-backref" href="#id10">Windows</a></h3>
<ul class="simple">
-<li>Plugins installed in the user's home should be installed to: <tt class="docutils literal"><span class="pre">C:\Program</span> Files\clap\</tt></li>
+<li>Plugins should be installed to: <tt class="docutils literal"><span class="pre">C:\Program</span> Files\clap\</tt></li>
</ul>
</div>
<div class="section" id="mac">
@@ -250,9 +254,12 @@ in valid UTF-8.</p>
<ul class="simple">
<li>load the dynamic library with <tt class="docutils literal">dlopen</tt> or symilar functions</li>
<li>find the symbol <tt class="docutils literal">clap_plugin_factory</tt></li>
-<li>use the factory to get the number of plugins available and
-create plugins by index to enumerate the collection
-or create plugins by identifier to create a specific one</li>
+<li>use the factory to:<ul>
+<li>get the number of plugins available <tt class="docutils literal"><span class="pre">factory->get_plugin_count(...);</span></tt></li>
+<li>create plugins by index to enumerate the collection <tt class="docutils literal"><span class="pre">factory->create_plugin_by_index(...);</span></tt></li>
+<li>create plugins by identifier to create a specific one <tt class="docutils literal"><span class="pre">factory->create_plugin_by_id(...);</span></tt></li>
+</ul>
+</li>
</ul>
<div class="section" id="release-a-plugin">
<h3><a class="toc-backref" href="#id13">Release a plugin</a></h3>
@@ -260,25 +267,39 @@ or create plugins by identifier to create a specific one</li>
</div>
<div class="section" id="plugin-description">
<h3><a class="toc-backref" href="#id14">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
+<p><tt class="docutils literal">struct clap_plugin</tt> contains an 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. The attribute <tt class="docutils literal">clap_version</tt> 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
+<p>Then to get the plugin's name, you have to use
<tt class="docutils literal"><span class="pre">plugin->get_attribute(plugin,</span> CLAP_ATTR_NAME, <span class="pre">...);</span></tt>.</p>
-<p>See the <tt class="docutils literal">#include <clap/clap.h></tt> for more information.</p>
+<p>See <tt class="docutils literal">#include <clap/clap.h></tt> for more information.</p>
</div>
<div class="section" id="extension-system">
<h3><a class="toc-backref" href="#id15">Extension system</a></h3>
<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>
-<span class="kt">void</span> <span class="o">*</span><span class="n">host_ext</span> <span class="o">=</span> <span class="n">host</span><span class="o">-></span><span class="n">extension</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="s">"company/ext-name"</span><span class="p">);</span>
+<span class="c1">// query a plugin extension
+</span><span class="k">const</span> <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>
+<span class="k">if</span> <span class="p">(</span><span class="n">plug_ext</span><span class="p">)</span> <span class="c1">// check if the interface was implemented
+</span><span class="p">{</span>
+ <span class="c1">// cast to the concrete type
+</span> <span class="k">const</span> <span class="k">struct</span> <span class="n">interface_type</span> <span class="o">*</span><span class="n">plug_ext1</span> <span class="o">=</span> <span class="p">(</span><span class="k">const</span> <span class="k">struct</span> <span class="n">interface_type</span> <span class="o">*</span><span class="p">)</span><span class="n">plug_ext</span><span class="p">;</span>
+
+ <span class="c1">// use the interface ...
+</span> <span class="n">plug_ext1</span><span class="o">-></span><span class="n">my_fct</span><span class="p">(</span><span class="n">plug</span><span class="p">,</span> <span class="p">...);</span>
+<span class="p">}</span>
+
+<span class="c1">// For the host, this is similar:
+</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">host_ext</span> <span class="o">=</span> <span class="n">host</span><span class="o">-></span><span class="n">extension</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="s">"company/ext-name"</span><span class="p">);</span>
+<span class="p">...</span>
</pre>
<p>If the extension is not supported, the plugin should return <tt class="docutils literal">NULL</tt>.</p>
+<p>Extensions are interface, and <strong>there is no need for the caller to free the pointer</strong>.</p>
<p>By convention, extensions should provide a define for the extension name.</p>
<pre class="code c literal-block">
-<span class="cp"># define CLAP_EXT_AUDIO_PORTS "clap/audio-ports"</span>
+<span class="c1">// defined in <clap/ext/ports.h>
+</span><span class="cp"># define CLAP_EXT_AUDIO_PORTS "clap/audio-ports"</span>
</pre>
</div>
<div class="section" id="audio-ports-configuration">
@@ -290,11 +311,11 @@ flexible and dynamic.</p>
<dt>An audio port has:</dt>
<dd><ul class="first last simple">
<li>a direction (input or output)</li>
-<li>a channel count</li>
+<li>a channel count: the number of pin in the bus</li>
<li>a channel mapping (eg: stereo left then right)</li>
<li>a role (input or output, sidechain input, audio rate modulation signal)</li>
<li>a name</li>
-<li>repeatable: can be used as a template to create multiple instance of the
+<li>is repeatable: can be used as a template to create multiple instance of the
same port and so connect multiple signals to it. For example you have an
analyzer and you want a repeatable input port, so the user can connect
an arbitrary number of signals.</li>
@@ -371,15 +392,18 @@ 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><tt class="docutils literal">deactivate()</tt> must not be called if the plugin is not activated.</p>
-<p>The host must de-activate the plugin before destroying it.</p>
+<p><tt class="docutils literal">deactivate()</tt> must not be called if the plugin is not activated. Yet the
+plugin should handle this mis-usage.</p>
+<p>The host must de-activate the plugin before destroying it. Again, if
+deactivate was not called before destroy(), the plugin should handle it
+gracefully.</p>
</div>
<div class="section" id="processing">
<h2><a class="toc-backref" href="#id19">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>number of frames</li>
<li>events (in)</li>
<li>some time info</li>
</ul>
@@ -397,36 +421,32 @@ which can be:</p>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal">CLAP_PROCESS_ERROR</tt></td>
-<td>An error happened, and the buffers should be discarded</td>
+<td>An error happened, and the output should be discarded</td>
</tr>
<tr><td><tt class="docutils literal">CLAP_PROCESS_CONTINUE</tt></td>
<td>Succeed, the plugins wants to process the next block</td>
</tr>
-<tr><td><tt class="docutils literal">CLAP_PROCESS_STOP</tt></td>
+<tr><td><tt class="docutils literal">CLAP_PROCESS_SLEEP</tt></td>
<td>Succeed, every voices terminated, wake me up on a new event</td>
</tr>
</tbody>
</table>
-<p>If <tt class="docutils literal">process()</tt> returns <tt class="docutils literal">CLAP_PROCESS_STOP</tt> and some parameters were ramping
+<p>If <tt class="docutils literal">process()</tt> returns <tt class="docutils literal">CLAP_PROCESS_SLEEP</tt> and some parameters were ramping
(see <tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt> event), then the host must send a <tt class="docutils literal">CLAP_EVENT_PARAM_SET</tt>
or <tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt> for those parameters at the next call to process.</p>
<div class="section" id="audio-buffers">
<h3><a class="toc-backref" href="#id20">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>The audio buffers are allocated by the host.</li>
<li>In-place processing is not supported by default, yet the host can use it
if the plugin has the attribute <tt class="docutils literal">CLAP_ATTR_SUPPORTS_IN_PLACE_PROCESSING</tt>.</li>
-<li>The number of samples must be a multiple of the plugin chunk_size.</li>
-<li>See <a href="#id50"><span class="problematic" id="id51">`Pin layout`_</span></a>.</li>
-<li>See <a class="reference internal" href="#plugin-description">Plugin description</a></li>
+<li>See <a class="reference internal" href="#standard-channel-mappings">Standard channel mappings</a>.</li>
</ul>
</div>
<div class="section" id="events">
<h3><a class="toc-backref" href="#id21">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>Event's time is relative to the first sample of the processing block.</li>
<li>The plugin must not modify the events.</li>
</ul>
<div class="section" id="notes">
@@ -462,10 +482,11 @@ it can quickly figure which voice is playing the given key.</p>
<div class="section" id="parameters">
<h4><a class="toc-backref" href="#id23">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>
+<tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt>. Or they can be automated at audio rate by using
+an audio buffer.</p>
<p>When using <tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt>, the parameter is set to <tt class="docutils literal"><span class="pre">ev->param.value</span></tt>
and has to be incremented by <tt class="docutils literal"><span class="pre">event->param.increment</span></tt> for each samples, except
-for the sample at <tt class="docutils literal"><span class="pre">ev->steady_time</span></tt>, until an event <tt class="docutils literal">CLAP_EVENT_PARAM_SET</tt> or
+for the time of the event, and until an event <tt class="docutils literal">CLAP_EVENT_PARAM_SET</tt> or
<tt class="docutils literal">CLAP_EVENT_PARAM_RAMP</tt> occur for this parameter.</p>
</div>
</div>
@@ -475,7 +496,7 @@ for the sample at <tt class="docutils literal"><span class="pre">ev->steady_t
<p>The host can get the plugin's parameters tree by using the params extension:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">params->count(plugin);</span></tt> to know the number of parameters</li>
-<li><tt class="docutils literal"><span class="pre">params->get(plugin,</span> param_index, &param);</tt> to get the parameter
+<li><tt class="docutils literal"><span class="pre">params->get_param(plugin,</span> param_index, &param);</tt> to get the parameter
value and description</li>
</ul>
<pre class="code c literal-block">
@@ -487,66 +508,12 @@ value and description</li>
</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">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_param</span> <span class="n">param</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</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">param</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_param</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">param</span><span class="p">))</span>
<span class="k">continue</span><span class="p">;</span>
<span class="c1">// ...
</span><span class="p">}</span>
</pre>
<p>See <a class="reference internal" href="#clap-ext-params-h">clap/ext/params.h</a>.</p>
-<table border="1" class="docutils">
-<colgroup>
-<col width="24%" />
-<col width="76%" />
-</colgroup>
-<thead valign="bottom">
-<tr><th class="head">Attribute</th>
-<th class="head">Description</th>
-</tr>
-</thead>
-<tbody valign="top">
-<tr><td><tt class="docutils literal">type</tt></td>
-<td>The type of parameter. Must never change.</td>
-</tr>
-<tr><td><tt class="docutils literal">id</tt></td>
-<td>What identifies the parameter. Must never change.
-This field must be saved along automation.</td>
-</tr>
-<tr><td><tt class="docutils literal">name</tt></td>
-<td>The name of the parameter. This can change.
-Meant to be displayed.</td>
-</tr>
-<tr><td><tt class="docutils literal">desc</tt></td>
-<td>The description of the parameter. This can change.
-Meant to be displayed.</td>
-</tr>
-<tr><td><tt class="docutils literal">is_per_note</tt></td>
-<td><tt class="docutils literal">true</tt> if the parameter can be automated per voice.</td>
-</tr>
-<tr><td><tt class="docutils literal">display_text</tt></td>
-<td>How the value should be displayed. Only used for enum
-types.</td>
-</tr>
-<tr><td><tt class="docutils literal">is_used</tt></td>
-<td>True if the parameter is used by the current patch.</td>
-</tr>
-<tr><td><tt class="docutils literal">is_periodic</tt></td>
-<td>Means that the parameter is periodic, so
-<tt class="docutils literal">value = value % max</tt>.</td>
-</tr>
-<tr><td><tt class="docutils literal">value</tt></td>
-<td>The current value of the parameter.</td>
-</tr>
-<tr><td><tt class="docutils literal">min</tt></td>
-<td>The minimum value of the parameter.</td>
-</tr>
-<tr><td><tt class="docutils literal">max</tt></td>
-<td>The maximum value of the parameter.</td>
-</tr>
-<tr><td><tt class="docutils literal">scale</tt></td>
-<td>The scale to use when exposing the parameter to the user.</td>
-</tr>
-</tbody>
-</table>
<div class="section" id="types">
<h3><a class="toc-backref" href="#id25">Types</a></h3>
<p>There are a few parameter types:</p>
@@ -1067,7 +1034,7 @@ plugin's parameters and restore them.</p>
<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">/* query an extension */</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="k">const</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>
<span class="c1">////////////
@@ -1116,7 +1083,7 @@ plugin's parameters and restore them.</p>
<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">/* query an extension */</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="k">const</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>
<span class="cm">/* This interface is the entry point of the dynamic library.
@@ -1147,7 +1114,7 @@ plugin's parameters and restore them.</p>
<span class="p">};</span>
<span class="cm">/* Entry point */</span>
-<span class="n">CLAP_EXPORT</span> <span class="k">extern</span> <span class="k">struct</span> <span class="n">clap_plugin_factory</span> <span class="o">*</span><span class="n">clap_plugin_factory</span><span class="p">;</span>
+<span class="n">CLAP_EXPORT</span> <span class="k">extern</span> <span class="k">const</span> <span class="k">struct</span> <span class="n">clap_plugin_factory</span> <span class="o">*</span><span class="n">clap_plugin_factory</span><span class="p">;</span>
<span class="cp"># ifdef __cplusplus
</span><span class="p">}</span>
@@ -1625,12 +1592,6 @@ plugin's parameters and restore them.</p>
</pre>
</div>
</div>
-<div class="system-messages section">
-<h1>Docutils System Messages</h1>
-<div class="system-message" id="id50">
-<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">spec.rst</tt>, line 231); <em><a href="#id51">backlink</a></em></p>
-Unknown target name: "pin layout".</div>
-</div>
</div>
</body>
</html>
diff --git a/spec.rst b/spec.rst
@@ -14,6 +14,7 @@ Goals
- Make a free digital instrument and effect plugin interface
- Be easy to understand and implement
- Don't require alien technology, or masoshist design
+
- Based on C, not Objective-C or C++
- No dependancy on external libraries
- No serialization format
@@ -21,13 +22,16 @@ Goals
- No macro obfuscation
- No object file to compile in the SDK, CLAP is an interface only.
- Simple resource management mechanism
+
- Designed to work on any operating system and processor architecture
- Be event oriented
- Be extensible
- Be easy to bridge
- Dynamics
+
- dynamic ports
- dynamic parameters
+
- Full MIDI
Specification
@@ -45,7 +49,7 @@ Encoding
All the strings exchanged through the CLAP interface must be encoded
in valid UTF-8.
-C++ execptions
+C++ exceptions
--------------
A CLAP interface must not send exception.
@@ -67,7 +71,7 @@ Linux
Windows
~~~~~~~
-- Plugins installed in the user's home should be installed to: ``C:\Program Files\clap\``
+- Plugins should be installed to: ``C:\Program Files\clap\``
Mac
~~~
@@ -81,9 +85,11 @@ Plugin instantiation can be done in a few steps:
- load the dynamic library with ``dlopen`` or symilar functions
- find the symbol ``clap_plugin_factory``
-- use the factory to get the number of plugins available and
- create plugins by index to enumerate the collection
- or create plugins by identifier to create a specific one
+- use the factory to:
+
+ - get the number of plugins available ``factory->get_plugin_count(...);``
+ - create plugins by index to enumerate the collection ``factory->create_plugin_by_index(...);``
+ - create plugins by identifier to create a specific one ``factory->create_plugin_by_id(...);``
Release a plugin
~~~~~~~~~~~~~~~~
@@ -93,15 +99,15 @@ To release a plugin, call ``plugin->destroy(plugin);``.
Plugin description
~~~~~~~~~~~~~~~~~~
-``struct clap_plugin`` only contains a interger ``clap_version`` which
+``struct clap_plugin`` contains an interger ``clap_version`` which
indicates which version of the clap interface has been used to build the plugin, and
a few methods. The attribute ``clap_version`` must be initialized by the plugin with
``CLAP_PLUGIN_VERSION``.
-Then to get plugin's attribute, you have to use
+Then to get the plugin's name, you have to use
``plugin->get_attribute(plugin, CLAP_ATTR_NAME, ...);``.
-See the ``#include <clap/clap.h>`` for more information.
+See ``#include <clap/clap.h>`` for more information.
Extension system
~~~~~~~~~~~~~~~~
@@ -110,15 +116,31 @@ To extend clap's functionnality, there is a pretty simple mechanism:
.. code:: c
- void *plug_ext = plugin->extension(plug, "company/ext-name");
- void *host_ext = host->extension(host, "company/ext-name");
+ // query a plugin extension
+ const void *plug_ext = plugin->extension(plug, "company/ext-name");
+ if (plug_ext) // check if the interface was implemented
+ {
+ // cast to the concrete type
+ const struct interface_type *plug_ext1 = (const struct interface_type *)plug_ext;
+
+ // use the interface ...
+ plug_ext1->my_fct(plug, ...);
+ }
+
+ // For the host, this is similar:
+ const void *host_ext = host->extension(host, "company/ext-name");
+ ...
+
If the extension is not supported, the plugin should return ``NULL``.
+Extensions are interface, and **there is no need for the caller to free the pointer**.
+
By convention, extensions should provide a define for the extension name.
.. code:: c
+ // defined in <clap/ext/ports.h>
# define CLAP_EXT_AUDIO_PORTS "clap/audio-ports"
Audio ports configuration
@@ -130,11 +152,11 @@ flexible and dynamic.
An audio port has:
- a direction (input or output)
- - a channel count
+ - a channel count: the number of pin in the bus
- a channel mapping (eg: stereo left then right)
- a role (input or output, sidechain input, audio rate modulation signal)
- a name
- - repeatable: can be used as a template to create multiple instance of the
+ - is repeatable: can be used as a template to create multiple instance of the
same port and so connect multiple signals to it. For example you have an
analyzer and you want a repeatable input port, so the user can connect
an arbitrary number of signals.
@@ -188,9 +210,12 @@ To deactivate the plugin, just call ``plugin->deactivate(plugin)``. Like
``activate()``, ``deactivate()`` should not be called from the audio processing
thread as it may take time.
-``deactivate()`` must not be called if the plugin is not activated.
+``deactivate()`` must not be called if the plugin is not activated. Yet the
+plugin should handle this mis-usage.
-The host must de-activate the plugin before destroying it.
+The host must de-activate the plugin before destroying it. Again, if
+deactivate was not called before destroy(), the plugin should handle it
+gracefully.
Processing
----------
@@ -198,7 +223,7 @@ Processing
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)
+- number of frames
- events (in)
- some time info
@@ -209,33 +234,29 @@ which can be:
+---------------------------+-------------------------------------------------------------+
| Status | Meaning |
+===========================+=============================================================+
-| ``CLAP_PROCESS_ERROR`` | An error happened, and the buffers should be discarded |
+| ``CLAP_PROCESS_ERROR`` | An error happened, and the output 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 |
+| ``CLAP_PROCESS_SLEEP`` | Succeed, every voices terminated, wake me up on a new event |
+---------------------------+-------------------------------------------------------------+
-If ``process()`` returns ``CLAP_PROCESS_STOP`` and some parameters were ramping
+If ``process()`` returns ``CLAP_PROCESS_SLEEP`` and some parameters were ramping
(see ``CLAP_EVENT_PARAM_RAMP`` event), then the host must send a ``CLAP_EVENT_PARAM_SET``
or ``CLAP_EVENT_PARAM_RAMP`` for those parameters at the next call to process.
Audio buffers
~~~~~~~~~~~~~
-- The audio buffers are allocated by the host. They must be aligned by the
- maximum requirement of the vector instructions currently available.
+- The audio buffers are allocated by the host.
- In-place processing is not supported by default, yet the host can use it
if the plugin has the attribute ``CLAP_ATTR_SUPPORTS_IN_PLACE_PROCESSING``.
-- The number of samples must be a multiple of the plugin chunk_size.
-- See `Pin layout`_.
-- See `Plugin description`_
+- See `Standard channel mappings`_.
Events
~~~~~~
-- Event's time must be within the process duration:
- ``[process->steady_time .. process->steady_time + process->nb_sambles]``.
+- Event's time is relative to the first sample of the processing block.
- The plugin must not modify the events.
Notes
@@ -276,11 +297,12 @@ Parameters
``````````
Parameters can be automated by the host using ``CLAP_EVENT_PARAM_SET`` or
-``CLAP_EVENT_PARAM_RAMP``.
+``CLAP_EVENT_PARAM_RAMP``. Or they can be automated at audio rate by using
+an audio buffer.
When using ``CLAP_EVENT_PARAM_RAMP``, the parameter is set to ``ev->param.value``
and has to be incremented by ``event->param.increment`` for each samples, except
-for the sample at ``ev->steady_time``, until an event ``CLAP_EVENT_PARAM_SET`` or
+for the time of the event, and until an event ``CLAP_EVENT_PARAM_SET`` or
``CLAP_EVENT_PARAM_RAMP`` occur for this parameter.
Parameters
@@ -289,7 +311,7 @@ Parameters
The host can get the plugin's parameters tree by using the params extension:
- ``params->count(plugin);`` to know the number of parameters
-- ``params->get(plugin, param_index, ¶m);`` to get the parameter
+- ``params->get_param(plugin, param_index, ¶m);`` to get the parameter
value and description
.. code:: c
@@ -302,46 +324,13 @@ The host can get the plugin's parameters tree by using the params extension:
uint32_t count = ports->count(plugin);
for (uint32_t i = 0; i < count; ++i) {
struct clap_param param;
- if (!ports->get(plugin, i, ¶m))
+ if (!ports->get_param(plugin, i, ¶m))
continue;
// ...
}
See `clap/ext/params.h`_.
-+------------------+----------------------------------------------------------+
-| Attribute | Description |
-+==================+==========================================================+
-| ``type`` | The type of parameter. Must never change. |
-+------------------+----------------------------------------------------------+
-| ``id`` | What identifies the parameter. Must never change. |
-| | This field must be saved along automation. |
-+------------------+----------------------------------------------------------+
-| ``name`` | The name of the parameter. This can change. |
-| | Meant to be displayed. |
-+------------------+----------------------------------------------------------+
-| ``desc`` | The description of the parameter. This can change. |
-| | Meant to be displayed. |
-+------------------+----------------------------------------------------------+
-| ``is_per_note`` | ``true`` if the parameter can be automated per voice. |
-+------------------+----------------------------------------------------------+
-| ``display_text`` | How the value should be displayed. Only used for enum |
-| | types. |
-+------------------+----------------------------------------------------------+
-| ``is_used`` | True if the parameter is used by the current patch. |
-+------------------+----------------------------------------------------------+
-| ``is_periodic`` | Means that the parameter is periodic, so |
-| | ``value = value % max``. |
-+------------------+----------------------------------------------------------+
-| ``value`` | The current value of the parameter. |
-+------------------+----------------------------------------------------------+
-| ``min`` | The minimum value of the parameter. |
-+------------------+----------------------------------------------------------+
-| ``max`` | The maximum value of the parameter. |
-+------------------+----------------------------------------------------------+
-| ``scale`` | The scale to use when exposing the parameter to the user.|
-+------------------+----------------------------------------------------------+
-
Types
~~~~~