clap

CLAP Audio Plugin API
Log | Files | Refs | README | LICENSE

commit 3ee5b72ff7f16309e4d378af232d70727891343d
parent b63b1146467c47d0680971bfff5721ab454418b6
Author: Alexandre Bique <bique.alexandre@gmail.com>
Date:   Wed,  8 Oct 2014 19:13:49 +0200

Update

Diffstat:
Minclude/clap/clap.h | 22++++++++++++++--------
Mspec.html | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mspec.rst | 46++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 169 insertions(+), 44 deletions(-)

diff --git a/include/clap/clap.h b/include/clap/clap.h @@ -81,6 +81,7 @@ struct clap_channels_config enum clap_param_type { + CLAP_PARAM_GROUP, CLAP_PARAM_BOOL, CLAP_PARAM_FLOAT, CLAP_PARAM_INT, @@ -112,6 +113,7 @@ struct clap_param char *name; // the display name char *desc; bool is_per_note; + char *display_text; // use this for display if not NULL. union clap_param_value value; union clap_param_value min; union clap_param_value max; @@ -154,8 +156,8 @@ enum clap_event_type struct clap_event_note { - uint16_t division; // 12 for a standard octave - uint16_t note; // starts from 0 + uint32_t division; // 12 for a standard octave + uint32_t note; // starts from 0 float velocity; // 0 .. 1.0f struct clap_event *events; // events specific to this note @@ -163,9 +165,12 @@ struct clap_event_note struct clap_event_param { - uint32_t index; - union clap_param_value value; - float increment; // for param ramp + uint32_t index; + union clap_param_value value; + float increment; // for param ramp + char *display_text; // use this for display if not NULL. + bool is_recordable; // used to tell the host if this event + // can be recorded }; struct clap_event_pitch @@ -286,10 +291,10 @@ struct clap_plugin bool (*set_channels_config)(struct clap_plugin *plugin, struct clap_channels_config *config); - /* parameters */ + /* Returns a newly allocated parameters tree. The caller has to free it. */ struct clap_param *(*get_params)(struct clap_plugin *plugin); - /* params */ + /* Returns a newly allocated preset list. The caller has to free it. */ struct clap_preset *(*get_presets)(struct clap_plugin *plugin); /* activation */ @@ -303,7 +308,8 @@ struct clap_plugin bool (*open_gui)(struct clap_plugin *plugin); void (*close_gui)(struct clap_plugin *plugin); - /* state */ + /* The plugin has to allocate and save its state into *buffer. + * The host has to free *buffer after that. */ void (*save)(struct clap_plugin *plugin, void **buffer, size_t *size); void (*restore)(struct clap_plugin *plugin, const void *buffer, size_t size); diff --git a/spec.html b/spec.html @@ -149,26 +149,31 @@ tt.docutils { </li> </ul> </li> -<li><a class="reference internal" href="#id1" id="id30">Parameters</a></li> -<li><a class="reference internal" href="#graphical-user-interface" id="id31">Graphical User Interface</a><ul> -<li><a class="reference internal" href="#showing-the-gui" id="id32">Showing the GUI</a></li> -<li><a class="reference internal" href="#sending-events-to-the-host" id="id33">Sending events to the host</a></li> -<li><a class="reference internal" href="#hiding-the-gui" id="id34">Hiding the GUI</a></li> +<li><a class="reference internal" href="#id1" id="id30">Parameters</a><ul> +<li><a class="reference internal" href="#types" id="id31">Types</a></li> +<li><a class="reference internal" href="#scales" id="id32">Scales</a></li> +<li><a class="reference internal" href="#automations" id="id33">Automations</a></li> </ul> </li> -<li><a class="reference internal" href="#presets" id="id35">Presets</a><ul> -<li><a class="reference internal" href="#list-plugin-s-presets" id="id36">List plugin's presets</a></li> -<li><a class="reference internal" href="#load-a-preset" id="id37">Load a preset</a></li> +<li><a class="reference internal" href="#graphical-user-interface" id="id34">Graphical User Interface</a><ul> +<li><a class="reference internal" href="#showing-the-gui" id="id35">Showing the GUI</a></li> +<li><a class="reference internal" href="#sending-events-to-the-host" id="id36">Sending events to the host</a></li> +<li><a class="reference internal" href="#hiding-the-gui" id="id37">Hiding the GUI</a></li> </ul> </li> -<li><a class="reference internal" href="#save-and-restore-plugin-s-state" id="id38">Save and restore plugin's state</a></li> -<li><a class="reference internal" href="#extension-system" id="id39">Extension system</a></li> +<li><a class="reference internal" href="#presets" id="id38">Presets</a><ul> +<li><a class="reference internal" href="#list-plugin-s-presets" id="id39">List plugin's presets</a></li> +<li><a class="reference internal" href="#load-a-preset" id="id40">Load a preset</a></li> </ul> </li> -<li><a class="reference internal" href="#examples" id="id40">Examples</a></li> -<li><a class="reference internal" href="#references" id="id41">References</a><ul> -<li><a class="reference internal" href="#clap-c" id="id42">clap.c</a></li> -<li><a class="reference internal" href="#samples-clap-info-c" id="id43">samples/clap-info.c</a></li> +<li><a class="reference internal" href="#save-and-restore-plugin-s-state" id="id41">Save and restore plugin's state</a></li> +<li><a class="reference internal" href="#extension-system" id="id42">Extension system</a></li> +</ul> +</li> +<li><a class="reference internal" href="#examples" id="id43">Examples</a></li> +<li><a class="reference internal" href="#references" id="id44">References</a><ul> +<li><a class="reference internal" href="#clap-c" id="id45">clap.c</a></li> +<li><a class="reference internal" href="#samples-clap-info-c" id="id46">samples/clap-info.c</a></li> </ul> </li> </ul> @@ -596,22 +601,84 @@ The pitch can be changed by the host using the <tt class="docutils literal">CLAP </div> <div class="section" id="id1"> <h2><a class="toc-backref" href="#id30">Parameters</a></h2> +<p>The host can get the plugin's parameters tree by calling +<tt class="docutils literal"><span class="pre">plugin-&gt;get_params(plugin)</span></tt>. The host is responsible to free the return +value.</p> +<div class="section" id="types"> +<h3><a class="toc-backref" href="#id31">Types</a></h3> +<p>There are a few parameter types:</p> +<table border="1" class="docutils"> +<colgroup> +<col width="9%" /> +<col width="22%" /> +<col width="69%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">type</th> +<th class="head">value attribute</th> +<th class="head">description</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td>group</td> +<td>none</td> +<td>not a value, but the only parameter which can have +childs. It should be used to organise parameters in +the host GUI.</td> +</tr> +<tr><td>bool</td> +<td><tt class="docutils literal">value.b</tt></td> +<td>a boolean value, can be true or false</td> +</tr> +<tr><td>float</td> +<td><tt class="docutils literal">value.f</tt></td> +<td>a float value</td> +</tr> +<tr><td>int</td> +<td><tt class="docutils literal">value.i</tt></td> +<td>an integer value</td> +</tr> +<tr><td>enum</td> +<td><tt class="docutils literal">value.i</tt></td> +<td>an enumeration, it uses integer values, and the host +should rely on <tt class="docutils literal">display_text</tt> to show its value.</td> +</tr> +</tbody> +</table> +</div> +<div class="section" id="scales"> +<h3><a class="toc-backref" href="#id32">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-&gt;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="automations"> +<h3><a class="toc-backref" href="#id33">Automations</a></h3> +<p>When a parameter is modified by the GUI, the plugin should send a +<tt class="docutils literal">CLAP_EVENT_SET</tt> event must be sent to the host, using +<tt class="docutils literal"><span class="pre">host-&gt;events(host,</span> plugin, events);</tt> so the host can record the automation.</p> +<p>When a parameter is modified by an other parameter, for exemple imagine you +have a parameter modulating &quot;absolutely&quot; an other one through an XY mapping. +The host should record the modulation source but not the modulation target. +To do that the plugin uses <tt class="docutils literal"><span class="pre">clap_event_param-&gt;is_recordable</span></tt>.</p> +</div> </div> <div class="section" id="graphical-user-interface"> -<h2><a class="toc-backref" href="#id31">Graphical User Interface</a></h2> +<h2><a class="toc-backref" href="#id34">Graphical User Interface</a></h2> <div class="section" id="showing-the-gui"> -<h3><a class="toc-backref" href="#id32">Showing the GUI</a></h3> +<h3><a class="toc-backref" href="#id35">Showing the GUI</a></h3> <p>The plugin should show the GUI after a call to <tt class="docutils literal"><span class="pre">plugin-&gt;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="#id33">Sending events to the host</a></h3> +<h3><a class="toc-backref" href="#id36">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-&gt;events(host,</span> plugin, events);</tt>.</p> </div> <div class="section" id="hiding-the-gui"> -<h3><a class="toc-backref" href="#id34">Hiding the GUI</a></h3> +<h3><a class="toc-backref" href="#id37">Hiding the GUI</a></h3> <p>The plugin should hide the GUI after a call to <tt class="docutils literal"><span class="pre">plugin-&gt;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> @@ -624,21 +691,21 @@ send an event <tt class="docutils literal">CLAP_EVENT_GUI_CLOSED</tt> to the hos </div> </div> <div class="section" id="presets"> -<h2><a class="toc-backref" href="#id35">Presets</a></h2> +<h2><a class="toc-backref" href="#id38">Presets</a></h2> <div class="section" id="list-plugin-s-presets"> -<h3><a class="toc-backref" href="#id36">List plugin's presets</a></h3> +<h3><a class="toc-backref" href="#id39">List plugin's presets</a></h3> <p>The host can browse the plugin's preset by callign <tt class="docutils literal"><span class="pre">plugin-&gt;get_presets(plugin);</span></tt>. This function returns a newly allocated preset linked list. It is the responsibility of the host to free the linked list.</p> </div> <div class="section" id="load-a-preset"> -<h3><a class="toc-backref" href="#id37">Load a preset</a></h3> +<h3><a class="toc-backref" href="#id40">Load a preset</a></h3> <p>To load a preset, the host should send an event <tt class="docutils literal">CLAP_EVENT_PRESET_SET</tt> to the plugin.</p> </div> </div> <div class="section" id="save-and-restore-plugin-s-state"> -<h2><a class="toc-backref" href="#id38">Save and restore plugin's state</a></h2> +<h2><a class="toc-backref" href="#id41">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> @@ -656,7 +723,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="#id39">Extension system</a></h2> +<h2><a class="toc-backref" href="#id42">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">-&gt;</span><span class="n">extension</span><span class="p">(</span><span class="n">plug</span><span class="p">,</span> <span class="s">&quot;company/ext-name&quot;</span><span class="p">);</span> @@ -666,12 +733,12 @@ big endian machine, it should load again successfully.</p> </div> </div> <div class="section" id="examples"> -<h1><a class="toc-backref" href="#id40">Examples</a></h1> +<h1><a class="toc-backref" href="#id43">Examples</a></h1> </div> <div class="section" id="references"> -<h1><a class="toc-backref" href="#id41">References</a></h1> +<h1><a class="toc-backref" href="#id44">References</a></h1> <div class="section" id="clap-c"> -<h2><a class="toc-backref" href="#id42">clap.c</a></h2> +<h2><a class="toc-backref" href="#id45">clap.c</a></h2> <pre class="code c literal-block"> <span class="cm">/** * CLAP - CLever Audio Plugin (&lt;--- needs to find a marketing ok name) @@ -756,6 +823,7 @@ big endian machine, it should load again successfully.</p> </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="p">,</span> <span class="n">CLAP_PARAM_BOOL</span><span class="p">,</span> <span class="n">CLAP_PARAM_FLOAT</span><span class="p">,</span> <span class="n">CLAP_PARAM_INT</span><span class="p">,</span> @@ -787,7 +855,8 @@ big endian machine, it should load again successfully.</p> </span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span> <span class="c1">// the display name </span> <span class="kt">char</span> <span class="o">*</span><span class="n">desc</span><span class="p">;</span> <span class="kt">bool</span> <span class="n">is_per_note</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="kt">char</span> <span class="o">*</span><span class="n">display_text</span><span class="p">;</span> <span class="c1">// use this for display if not NULL. +</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> @@ -829,8 +898,8 @@ big endian machine, it should load again successfully.</p> <span class="k">struct</span> <span class="n">clap_event_note</span> <span class="p">{</span> - <span class="kt">uint16_t</span> <span class="n">division</span><span class="p">;</span> <span class="c1">// 12 for a standard octave -</span> <span class="kt">uint16_t</span> <span class="n">note</span><span class="p">;</span> <span class="c1">// starts from 0 + <span class="kt">uint32_t</span> <span class="n">division</span><span class="p">;</span> <span class="c1">// 12 for a standard octave +</span> <span class="kt">uint32_t</span> <span class="n">note</span><span class="p">;</span> <span class="c1">// starts from 0 </span> <span class="kt">float</span> <span class="n">velocity</span><span class="p">;</span> <span class="c1">// 0 .. 1.0f </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 @@ -838,9 +907,12 @@ big endian machine, it should load again successfully.</p> <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="kt">float</span> <span class="n">increment</span><span class="p">;</span> <span class="c1">// for param ramp + <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="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="o">*</span><span class="n">display_text</span><span class="p">;</span> <span class="c1">// use this for display if not NULL. +</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="p">};</span> <span class="k">struct</span> <span class="n">clap_event_pitch</span> @@ -961,10 +1033,10 @@ 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">set_channels_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="k">struct</span> <span class="n">clap_channels_config</span> <span class="o">*</span><span class="n">config</span><span class="p">);</span> - <span class="cm">/* parameters */</span> + <span class="cm">/* Returns a newly allocated parameters tree. The caller has to free it. */</span> <span class="k">struct</span> <span class="n">clap_param</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">get_params</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">/* params */</span> + <span class="cm">/* Returns a newly allocated preset list. The caller has to free it. */</span> <span class="k">struct</span> <span class="n">clap_preset</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">get_presets</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">/* activation */</span> @@ -978,7 +1050,8 @@ 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">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">/* state */</span> + <span class="cm">/* The plugin has to allocate and save its state into *buffer. + * The host has to free *buffer after that. */</span> <span class="kt">void</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">size_t</span> <span class="o">*</span><span class="n">size</span><span class="p">);</span> <span class="kt">void</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">size_t</span> <span class="n">size</span><span class="p">);</span> @@ -1007,7 +1080,7 @@ big endian machine, it should load again successfully.</p> </pre> </div> <div class="section" id="samples-clap-info-c"> -<h2><a class="toc-backref" href="#id43">samples/clap-info.c</a></h2> +<h2><a class="toc-backref" href="#id46">samples/clap-info.c</a></h2> <pre class="code c literal-block"> <span class="cp">#include &lt;stdio.h&gt; #include &lt;dlfcn.h&gt; diff --git a/spec.rst b/spec.rst @@ -371,6 +371,52 @@ The pitch can be changed by the host using the ``CLAP_EVENT_PITCH_SET`` event. Parameters ---------- +The host can get the plugin's parameters tree by calling +``plugin->get_params(plugin)``. The host is responsible to free the return +value. + +Types +~~~~~ + +There are a few parameter types: + ++-------+-----------------+------------------------------------------------------+ +| type | value attribute | description | ++=======+=================+======================================================+ +| group | none | not a value, but the only parameter which can have | +| | | childs. It should be used to organise parameters in | +| | | the host GUI. | ++-------+-----------------+------------------------------------------------------+ +| bool | ``value.b`` | a boolean value, can be true or false | ++-------+-----------------+------------------------------------------------------+ +| float | ``value.f`` | a float value | ++-------+-----------------+------------------------------------------------------+ +| int | ``value.i`` | an integer value | ++-------+-----------------+------------------------------------------------------+ +| enum | ``value.i`` | an enumeration, it uses integer values, and the host | +| | | should rely on ``display_text`` to show its value. | ++-------+-----------------+------------------------------------------------------+ + +Scales +~~~~~~ + +The plugin can inform the host, which scale to use for the parameter's UI +(knob, slider, ...). ``clap_param->scale`` can be set to ``CLAP_PARAM_LINEAR`` +or ``CLAP_PARAM_LOG``. A logarithmic scale is convinient for a frequency +parameter. + +Automations +~~~~~~~~~~~ + +When a parameter is modified by the GUI, the plugin should send a +``CLAP_EVENT_SET`` event must be sent to the host, using +``host->events(host, plugin, events);`` so the host can record the automation. + +When a parameter is modified by an other parameter, for exemple imagine you +have a parameter modulating "absolutely" an other one through an XY mapping. +The host should record the modulation source but not the modulation target. +To do that the plugin uses ``clap_event_param->is_recordable``. + Graphical User Interface ------------------------