aboutsummaryrefslogtreecommitdiffstats
path: root/lv2/lv2plug.in/ns/extensions
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-03-23 19:25:11 +0000
committerDavid Robillard <d@drobilla.net>2012-03-23 19:25:11 +0000
commit2b0b027a6d240865dad7ed668ea821e00738823c (patch)
tree9e99b17883f138d7a8a4f9112d10c4fb8b6fdd0d /lv2/lv2plug.in/ns/extensions
parent5e56795dd315bb4c9aa4ad3cc051a3314e7d3afd (diff)
downloadlv2-2b0b027a6d240865dad7ed668ea821e00738823c.tar.xz
Duplicate new functionality in pui extension as features in the ui extension.
Diffstat (limited to 'lv2/lv2plug.in/ns/extensions')
-rw-r--r--lv2/lv2plug.in/ns/extensions/ui/lv2-ui.doap.ttl6
-rw-r--r--lv2/lv2plug.in/ns/extensions/ui/ui.h220
-rw-r--r--lv2/lv2plug.in/ns/extensions/ui/ui.ttl147
3 files changed, 300 insertions, 73 deletions
diff --git a/lv2/lv2plug.in/ns/extensions/ui/lv2-ui.doap.ttl b/lv2/lv2plug.in/ns/extensions/ui/lv2-ui.doap.ttl
index 796b828..2edddda 100644
--- a/lv2/lv2plug.in/ns/extensions/ui/lv2-ui.doap.ttl
+++ b/lv2/lv2plug.in/ns/extensions/ui/lv2-ui.doap.ttl
@@ -29,6 +29,12 @@
rdfs:label "Add ui:parent and ui:resize." ;
] , [
rdfs:label "Add support for referring to ports by symbol." ;
+ ] , [
+ rdfs:label "Add ui:portMap for accessing ports by symbol, allowing for UIs to be distributed separately from plugins." ;
+ ] , [
+ rdfs:label "Add port protocols and a dynamic notification subscription mechanism, for more flexible communication, and audio port metering without control port kludges." ;
+ ] , [
+ rdfs:label "Add touch feature to notify the host that the user has grabbed a control." ;
] ;
] ;
] , [
diff --git a/lv2/lv2plug.in/ns/extensions/ui/ui.h b/lv2/lv2plug.in/ns/extensions/ui/ui.h
index 8716291..f394eb6 100644
--- a/lv2/lv2plug.in/ns/extensions/ui/ui.h
+++ b/lv2/lv2plug.in/ns/extensions/ui/ui.h
@@ -1,7 +1,7 @@
/*
LV2 UI Extension
- Copyright 2009-2011 David Robillard <d@drobilla.net>
- Copyright 2006-2008 Lars Luthman <lars.luthman@gmail.com>
+ Copyright 2009-2012 David Robillard <d@drobilla.net>
+ Copyright 2006-2011 Lars Luthman <lars.luthman@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -17,48 +17,56 @@
*/
/**
- * @file
- * C header for the LV2 UI extension <http://lv2plug.in/ns/extensions/ui>.
- */
+ @file ui.h
+ C header for the LV2 UI extension <http://lv2plug.in/ns/extensions/ui>.
+*/
#ifndef LV2_UI_H
#define LV2_UI_H
+#include <stdint.h>
+
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#define LV2_UI_URI "http://lv2plug.in/ns/extensions/ui"
#define LV2_UI_PREFIX LV2_UI_URI "#"
-#define LV2_UI__UI LV2_UI_PREFIX "UI"
#define LV2_UI__GtkUI LV2_UI_PREFIX "GtkUI"
+#define LV2_UI__PortNotification LV2_UI_PREFIX "PortNotification"
#define LV2_UI__Qt4UI LV2_UI_PREFIX "Qt4UI"
+#define LV2_UI__UI LV2_UI_PREFIX "UI"
#define LV2_UI__X11UI LV2_UI_PREFIX "X11UI"
-#define LV2_UI__noUserResize LV2_UI_PREFIX "noUserResize"
#define LV2_UI__fixedSize LV2_UI_PREFIX "fixedSize"
+#define LV2_UI__noUserResize LV2_UI_PREFIX "noUserResize"
+#define LV2_UI__notifyType LV2_UI_PREFIX "notifyType"
#define LV2_UI__parent LV2_UI_PREFIX "parent"
-#define LV2_UI__PortNotification LV2_UI_PREFIX "PortNotification"
-#define LV2_UI__portNotification LV2_UI_PREFIX "portNotification"
#define LV2_UI__plugin LV2_UI_PREFIX "plugin"
#define LV2_UI__portIndex LV2_UI_PREFIX "portIndex"
-#define LV2_UI__notifyType LV2_UI_PREFIX "notifyType"
+#define LV2_UI__portMap LV2_UI_PREFIX "portMap"
+#define LV2_UI__portNotification LV2_UI_PREFIX "portNotification"
#define LV2_UI__resize LV2_UI_PREFIX "resize"
+#define LV2_UI__touch LV2_UI_PREFIX "touch"
+
+/**
+ The index returned by LV2_UI_Port_Port::port_index() for unknown ports.
+*/
+#define LV2UI_INVALID_PORT_INDEX ((uint32_t)-1)
#ifdef __cplusplus
extern "C" {
+#else
+# include <stdbool.h>
#endif
/**
A pointer to some widget or other type of UI handle.
- The actual type is defined by the type URI of the UI. All the functionality
- provided by this extension is toolkit independent, the host only needs to
- pass the necessary callbacks and display the widget, if possible. Plugins
- may have several UIs, in various toolkits.
+ The actual type is defined by the type of the UI.
*/
typedef void* LV2UI_Widget;
/**
- A pointer to a particular instance of a UI.
+ A pointer to an instance of a UI.
It is valid to compare this to NULL (0 for C++) but otherwise the host MUST
not attempt to interpret it. The UI plugin may use it to reference internal
@@ -67,7 +75,7 @@ typedef void* LV2UI_Widget;
typedef void* LV2UI_Handle;
/**
- A pointer to a particular plugin controller, provided by the host.
+ A pointer to a controller provided by the host.
It is valid to compare this to NULL (0 for C++) but otherwise the UI plugin
MUST NOT attempt to interpret it. The host may use it to reference internal
@@ -80,41 +88,23 @@ typedef void* LV2UI_Controller;
send data to a plugin's input ports.
The @c buffer parameter must point to a block of data, @c buffer_size bytes
- large. The contents of this buffer and what the host should do with it
- depends on the value of the @c format parameter.
-
- The @c format parameter should either be 0 or a numeric ID for a "Transfer
- mechanism". Transfer mechanisms are Features and may be defined in
- meta-extensions. They specify how to translate the data buffers passed to
- this function to input data for the plugin ports. If a UI wishes to write
- data to an input port, it must list a transfer mechanism Feature for that
- port's class as an optional or required feature (depending on whether the UI
- will work without being able to write to that port or not). The only
- exception is when the UI wants to write single float values to input ports
- of the class lv2:ControlPort, in which case @c buffer_size should always be
- 4, the buffer should always contain a single IEEE-754 float, and @c format
- should be 0.
-
- The numeric IDs for the transfer mechanisms are provided by a URI-to-integer
- mapping function provided by the host, using the URI Map feature
- <http://lv2plug.in/ns/ext/uri-map> with the map URI
- "http://lv2plug.in/ns/extensions/ui". Thus a UI that requires transfer
- mechanism features also requires the URI Map feature, but this is implicit -
- the UI does not have to list the URI map feature as a required or optional
- feature in it's RDF data.
-
- An UI MUST NOT pass a @c format parameter value (except 0) that has not been
- returned by the host-provided URI mapping function for a host-supported
- transfer mechanism feature URI.
-
- The UI MUST NOT try to write to a port for which there is no specified
- transfer mechanism, or to an output port. The UI is responsible for
- allocating the buffer and deallocating it after the call.
+ large. The format of this data and how the host should use it is defined by
+ the @c port_protocol. This buffer is owned by the UI and is only valid for
+ the duration of this call.
+
+ The @c port_protocol parameter should either be 0 or the URID for a
+ ui:PortProtocol. If it is 0, the protocol is implicitly ui:floatProtocol,
+ the port must be an lv2:ControlPort input, @c buffer must point to a single
+ float value, and @c buffer_size must be sizeof(float).
+
+ The UI SHOULD NOT use a PortProtocol not supported by the host (i.e. one not
+ passed by the host as a feature), but the host MUST gracefully ignore any
+ port_protocol it does not understand.
*/
typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
uint32_t port_index,
uint32_t buffer_size,
- uint32_t format,
+ uint32_t port_protocol,
const void* buffer);
/**
@@ -232,48 +222,138 @@ typedef struct _LV2UI_Descriptor {
similar to the extension_data() member in LV2_Descriptor.
*/
const void* (*extension_data)(const char* uri);
-
} LV2UI_Descriptor;
-typedef void* LV2_UI_Resize_Handle;
-
/**
UI Resize Feature (LV2_UI__resize)
- This structure may be used in two ways: as a feature passed by the host
- (e.g. via the features parameter of LV2UI_Descriptor::instantiate()) or
- as a feature exposed by a UI (e.g. via LV2UI_Descriptor::extension_data()).
+ This structure may be used in two ways: as a feature passed by the host via
+ LV2UI_Descriptor::instantiate(), or as extension data provided by a UI via
+ LV2UI_Descriptor::extension_data()).
*/
-typedef struct {
-
- LV2_UI_Resize_Handle handle;
-
+typedef struct _LV2UI_Resize {
/**
- Request or notify a size change.
+ Request or advertise a size change.
When this struct is provided by the host, the UI may call this
- function to notify the host that a size change is desired, or notify
- the host of the initial size of the UI.
+ function to inform the host about the size of the UI.
- When this struct is provided by the plugin, the host may call this
- function in the UI thread to notify the UI that it should change its
- size to the given dimensions.
+ When this struct is provided by the UI, the host may call this
+ function to notify the UI that it should change its size accordingly.
@return 0 on success.
*/
- int (*ui_resize)(LV2_UI_Resize_Handle handle,
- int width,
- int height);
+ int (*ui_resize)(LV2UI_Controller controller, int width, int height);
+} LV2UI_Resize;
+
+/**
+ Port Map Feature (LV2_UI__portMap).
+
+ This feature can be used by the UI to get the index for a port with the
+ given symbol. This makes it possible to implement and distribute a UI
+ separately from the plugin (since symbol is a guaranteed stable port
+ identifier while index is not).
+*/
+typedef struct _LV2UI_Port_Map {
+ /**
+ Get the index for the port with the given @p symbol.
+
+ @return The index of the port, or LV2_UI_INVALID_PORT_INDEX if no such
+ port is found.
+ */
+ uint32_t (*port_index)(LV2UI_Controller controller, const char* symbol);
+} LV2UI_Port_Map;
+
+/**
+ Port subscription feature (LV2_UI__portSubscribe);
+*/
+typedef struct _LV2UI_Port_Subscribe {
+ /**
+ Subscribe to updates for a port.
+
+ This means that the host will call the UI's port_event() function when
+ the port value changes (as defined by protocol).
+
+ Calling this function with the same @c port_index and @c port_protocol
+ as an already active subscription has no effect.
+
+ @param controller The @c controller passed to the UI's instantiate().
+ @param port_index The index of the port.
+ @param port_protocol The URID of the ui:PortProtocol.
+ @param data Extra data as defined by the port protocol, or NULL.
+ */
+ void (*subscribe)(LV2UI_Controller controller,
+ uint32_t port_index,
+ uint32_t port_protocol,
+ const void* options);
+
+ /**
+ Unsubscribe from updates for a port.
+
+ This means that the host will cease calling calling port_event() when
+ the port value changes.
+
+ Calling this function with a @c port_index and @c port_protocol that
+ does not refer to an active port subscription has no effect.
+
+ @param controller The @c controller passed to the UI's instantiate().
+ @param port_index The index of the port.
+ @param port_protocol The URID of the ui:PortProtocol.
+ @param data Extra data as defined by the port protocol, or NULL.
+ */
+ void (*unsubscribe)(LV2UI_Controller controller,
+ uint32_t port_index,
+ uint32_t port_protocol,
+ const void* options);
+} LV2UI_Port_Subscribe;
+
+/**
+ A feature to notify the host the user has grabbed a UI control.
+*/
+typedef struct _LV2UI_Touch {
+ /**
+ Notify the host that a control has been grabbed or released.
+
+ @param controller The @c controller passed to the UI's instantiate().
+ @param port_index The index of the port associated with the control.
+ @param grabbed If true, the control has been grabbed, otherwise the
+ control has been released.
+ */
+ void (*touch)(LV2UI_Controller controller,
+ uint32_t port_index,
+ bool grabbed);
+} LV2UI_Touch;
+
+/**
+ Peak data for a slice of time, the update format for ui:peakProtocol.
+*/
+typedef struct _LV2UI_Peak_Data {
+ /**
+ The start of the measurement period. This is just a running counter
+ that is only meaningful in comparison to previous values and must not be
+ interpreted as an absolute time.
+ */
+ uint32_t period_start;
-} LV2_UI_Resize;
+ /**
+ The size of the measurement period, in the same units as period_start.
+ */
+ uint32_t period_size;
+
+ /**
+ The peak value for the measurement period. This should be the maximal
+ value for abs(sample) over all the samples in the period.
+ */
+ float peak;
+} LV2UI_Peak_Data;
/**
A plugin UI programmer must include a function called "lv2ui_descriptor"
with the following function prototype within the shared object file. This
function will have C-style linkage (if you are using C++ this is taken care
- of by the 'extern "C"' clause at the top of the file). This function will
- be accessed by the UI host using the @c dlsym() function and called to get a
- LV2UI_UIDescriptor for the wanted plugin.
+ of by the 'extern "C"' clause at the top of the file). This function is
+ loaded from the library by the UI host and called to get a
+ LV2UI_Descriptor for the wanted plugin.
Just like lv2_descriptor(), this function takes an index parameter. The
index should only be used for enumeration and not as any sort of ID number -
diff --git a/lv2/lv2plug.in/ns/extensions/ui/ui.ttl b/lv2/lv2plug.in/ns/extensions/ui/ui.ttl
index fa07e0b..382f854 100644
--- a/lv2/lv2plug.in/ns/extensions/ui/ui.ttl
+++ b/lv2/lv2plug.in/ns/extensions/ui/ui.ttl
@@ -216,6 +216,17 @@ ui:portNotification
lv2:documentation """
<p>Indicates that a UI should receive notification (via
LV2UI_Descriptor::port_event()) when a particular port's value changes.</p>
+
+<p>For example:</p>
+<pre class="turtle-code">
+eg:ui
+ a ui:GtkUI ;
+ ui:portNotification [
+ ui:plugin eg:plugin ;
+ lv2:symbol "gain" ;
+ ui:protocol ui:floatProtocol
+ ] .
+</pre>
""" .
ui:plugin
@@ -239,7 +250,7 @@ The index of the port a portNotification applies to.
ui:notifyType
a rdf:Property ;
rdfs:domain ui:PortNotification ;
- lv2:comment """
+ lv2:documentation """
<p>Indicates a particular type that the UI should be notified of. In the case
of ports where several types of data can be present (e.g. event ports), this
can be used to indicate that only a particular type of data should cause
@@ -251,9 +262,139 @@ ui:resize
a lv2:Feature ;
lv2:documentation """
<p>A feature that allows the UI to notify the host about its current size, or
-request a size change. This feature corresponds to the LV2_UI_Resize struct,
+request a size change. This feature corresponds to the LV2UI_Resize struct,
which should be passed with the URI LV2_UI__resize. This struct may also be
provided by the UI as extension data using the same URI, in which case it is
used by the host to request that the UI change its size.</p>
""" .
-o \ No newline at end of file
+
+ui:portMap
+ a lv2:Feature ;
+ lv2:documentation """
+<p>A feature for accessing the index of a port by symbol. This makes it
+possible to implement and distribute UIs separately from the plugin binaries
+they control. This feature corresponds to the LV2UI_Port_Index struct, which
+should be passed with the URI LV2_UI__portIndex.</p>
+""" .
+
+ui:touch
+ a lv2:Feature ;
+ lv2:documentation """
+<p>A feature to notify the host that the user has grabbed a particular port
+control. This is useful for automation, so the host can allow the user to take
+control of a port, even if that port would otherwise be automated (much like
+grabbing a physical morotised fader). It can also be used for MIDI learn or in
+any other situation where the host needs to do something with a particular
+control and it would be convenient for the user to select it directroy from the
+plugin UI. This feature corresponds to the LV2UI_Touch struct, which
+should be passed with the URI LV2_UI__touch.</p>
+""" .
+
+ui:PortProtocol
+ a rdfs:Class ;
+ rdfs:subClassOf lv2:Feature ;
+ rdfs:label "Port protocol" ;
+ lv2:documentation """
+<p>A PortProtocol defines a method to communicate port data between a UI and
+plugin.</p>
+
+<p>Any PortProtocol MUST define:</p>
+<table>
+<tr><th>Port Type</th>
+ <td>Which plugin port types the buffer type is valid for.</td></tr>
+<tr><th>Feature Data</th>
+ <td>What data (if any) should be passed in the LV2_Feature.</td></tr>
+</table>
+
+<p>Any PortProtocol for an output port MUST define:</p>
+<table>
+<tr><th>Update Frequency</th>
+ <td>When the host should call port_event().</td></tr>
+<tr><th>Update Format</th>
+ <td>The format of the data in the buffer passed to port_event().</td></tr>
+<tr><th>Options</th>
+ <td>The format of the options passed to subscribe() and unsubscribe().</td>
+</tr></table>
+
+<p>Any PortProtocol for an input port MUST define:</p>
+<table>
+<tr><th>Write Format</th>
+ <td>The format of the data in the buffer passed to write_port().</td></tr>
+<tr><th>Write Effect</th>
+ <td>What happens when the UI calls write_port().</td></tr>
+</table>
+
+<p>For an example, see ui:floatProtocol or ui:peakProtocol.
+</p>
+
+<p>PortProtocol is a subclass of lv2:Feature, so UIs use lv2:optionalFeature and
+lv2:requiredFeature to specify which PortProtocols they want to use.
+</p>
+""" .
+
+ui:floatProtocol
+ a ui:PortProtocol ;
+ rdfs:label "Floating point value" ;
+ lv2:documentation """
+
+<p>A protocol for transferring single floating point values. The rules for
+this protocol are:</p>
+<table>
+<tr><th>Port Type</th>
+ <td>lv2:ControlPort</td></tr>
+<tr><th>Feature Data</th>
+ <td>None.</td></tr>
+<tr><th>Update Frequency</th>
+ <td>The host SHOULD call port_event() as soon as possible when the port
+ value has changed, but there are no timing guarantees.</td></tr>
+<tr><th>Update Format</th>
+ <td>A single <code>float</code>.</td></tr>
+<tr><th>Options</th>
+ <td>None.</td></tr>
+<tr><th>Write Format</th>
+ <td>A single <code>float</code>.</td></tr>
+<tr><th>Write Effect</th>
+ <td>The host SHOULD set the port to the received value as soon as possible,
+ but there is no guarantee that run() actually sees this value.</td></tr>
+</table>
+""" .
+
+ui:peakProtocol
+ a ui:PortProtocol ;
+ rdfs:label "Peak measurement for a period of audio" ;
+ lv2:documentation """
+<p>This port protocol defines a way for the host to send continuous peak
+measurements of the audio signal at a certain port to the UI. The
+intended use is visualisation, e.g. an animated meter widget that shows
+the level of the audio input or output.</p>
+
+<p>A contiguous sequence of audio samples for which a peak value has been
+computed is called a <em>measurement period</em>.</p>
+
+<p>The rules for this protocol are:</p>
+<table>
+<tr><th>Port Type</th>
+ <td>lv2:AudioPort</td></tr>
+<tr><th>Feature Data</th>
+ <td>None.</td></tr>
+<tr><th>Update Frequency</th>
+ <td>The host SHOULD call port_event() at regular intervals. The
+ measurement periods used for calls to port_event() for the same port SHOULD
+ be contiguous (i.e. the measurement period for one call should begin right
+ after the end of the measurement period for the previous call ends) unless
+ the UI has removed and re-added the port subscription between those calls.
+ However, UIs MUST NOT depend on either the regularity of the calls or the
+ contiguity of the measurement periods; hosts may change the call rate or
+ skip calls for performance or other reasons. Measurement periods for
+ different calls to port_event() for the same port MUST NOT
+ overlap.</td></tr>
+<tr><th>Update Format</th>
+ <td>A single LV2UI_Peak_Data object.</td></tr>
+<tr><th>Options</th>
+ <td>None.</td></tr>
+<tr><th>Write Format</th>
+ <td>None.</td></tr>
+<tr><th>Write Effect</th>
+ <td>None.</td></tr>
+</table>
+""" .