aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/README.txt2
-rw-r--r--plugins/eg01-amp.lv2/README.txt18
-rw-r--r--plugins/eg01-amp.lv2/manifest.ttl.in30
-rw-r--r--plugins/eg04-sampler.lv2/sampler_ui.c4
-rw-r--r--plugins/eg05-scope.lv2/README.txt10
-rw-r--r--plugins/eg05-scope.lv2/examploscope.c82
-rw-r--r--plugins/eg05-scope.lv2/manifest.ttl.in3
-rwxr-xr-xplugins/literasc.py22
8 files changed, 101 insertions, 70 deletions
diff --git a/plugins/README.txt b/plugins/README.txt
index 7eb25d8..361460d 100644
--- a/plugins/README.txt
+++ b/plugins/README.txt
@@ -23,4 +23,4 @@ the first plugin describes the basics in detail.
This book is compiled from plugin source code into a single document for pleasant reading and ease of reference.
Each chapter corresponds to executable plugin code which can be found in the +plugins+ directory of the LV2 distribution.
-If you prefer to read actual source code, all the content here is also available there, where the book text is included in comments.
+If you prefer to read actual source code, all the content here is also available in the source code as comments.
diff --git a/plugins/eg01-amp.lv2/README.txt b/plugins/eg01-amp.lv2/README.txt
index f024a4d..41683d3 100644
--- a/plugins/eg01-amp.lv2/README.txt
+++ b/plugins/eg01-amp.lv2/README.txt
@@ -2,20 +2,18 @@
This plugin is a simple example of a basic LV2 plugin with no additional features.
It has audio ports which contain an array of `float`,
-and a control port which contain a single `float`.
+and a control port which contains a single `float`.
LV2 plugins are defined in two parts: code and data.
The code is written in C, or any C compatible language such as C++.
Static data is described separately in the human and machine friendly http://www.w3.org/TeamSubmission/turtle/[Turtle] syntax.
-Turtle is a syntax for the RDF data model,
-but familiarity with RDF is not required to understand this documentation.
-Generally, code is kept minimal,
-and all static information is described in the data.
+Generally, the goal is to keep code minimal,
+and describe as much as possible in the static data.
There are several advantages to this approach:
- * Hosts can discover and inspect plugins without loading or executing any plugin code
- * It is simple to work with plugin data using scripting languages, command line tools, etc.
- * The standard format allow the use of existing vocabularies to describe plugins and related information
- * The data inherently integrates with the web, databases, etc.
- * Labels and documentation are translatable, and available to hosts for display in user interfaces
+ * Hosts can discover and inspect plugins without loading or executing any plugin code.
+ * Plugin data can be used from a wide range of generic tools like scripting languages and command line utilities.
+ * The standard data model allows the use of existing vocabularies to describe plugins and related information.
+ * The language is extensible, so authors may describe any data without requiring changes to the LV2 specification.
+ * Labels and documentation are translatable, and available to hosts for display in user interfaces.
diff --git a/plugins/eg01-amp.lv2/manifest.ttl.in b/plugins/eg01-amp.lv2/manifest.ttl.in
index 0da78b0..8a1f696 100644
--- a/plugins/eg01-amp.lv2/manifest.ttl.in
+++ b/plugins/eg01-amp.lv2/manifest.ttl.in
@@ -1,27 +1,27 @@
-# LV2 Bundle Manifest
+# ==== Bundles ====
#
-# All LV2 plugins are installed as "bundles", a directory with a particular
-# format. Inside the bundle, the entry point is a file called "manifest.ttl".
-# This file lists what plugins are in this bundle, and which files are (.so,
-# .ttl, etc.) are associated with those plugins.
+# LV2 plugins are installed in ``bundles'', a directory with a particular
+# format. Inside the bundle, the entry point is a file called `manifest.ttl`.
+# The manifest lists the plugins (or other resources) that are in this bundle,
+# and the files that contain further information.
#
-# Hosts read bundles' manifest.ttl to discover what plugins (and other
-# resources) are available. Manifest files should be as small as possible for
-# performance reasons.
+# Hosts typically read the `manifest.ttl` of every bundle when starting up to
+# discover what LV2 plugins and other resources are present. Accordingly,
+# manifest files should be as small as possible for performance reasons.
#
#
# ==== Namespace Prefixes ====
#
-# Turtle files contain many URIs. To make this more readable, prefixes
-# can be defined. For example, with the `lv2:` prefix below, instead of
+# Turtle files contain many URIs. To make this more readable, prefixes can be
+# defined. For example, with the `lv2:` prefix below, instead of
# <http://lv2plug.in/ns/lv2core#Plugin> the shorter form `lv2:Plugin` can be
-# used. This is just a shorthand for URIs within a file, the prefixes are not
-# significant otherwise.
+# used. This is just a shorthand for URIs within one file, the prefixes are
+# not significant otherwise.
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
-# ==== Data ====
+# ==== A Plugin Entry ====
<http://lv2plug.in/plugins/eg-amp>
a lv2:Plugin ;
@@ -36,8 +36,8 @@
# For reability, the following text will assume `.so` is the extension used.
#
# In short, this declares that the resource with URI
-# "http://lv2plug.in/plugins/eg-amp" is an LV2 plugin, with executable code in
-# the file "amp.so" and a full description in "amp.ttl". These paths are
+# `http://lv2plug.in/plugins/eg-amp` is an LV2 plugin, with executable code in
+# the file `amp.so` and a full description in `amp.ttl`. These paths are
# relative to the bundle directory.
#
# There are 3 statements in this description:
diff --git a/plugins/eg04-sampler.lv2/sampler_ui.c b/plugins/eg04-sampler.lv2/sampler_ui.c
index 2184fbf..3eb1279 100644
--- a/plugins/eg04-sampler.lv2/sampler_ui.c
+++ b/plugins/eg04-sampler.lv2/sampler_ui.c
@@ -15,10 +15,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/**
- @file ui.c Sampler Plugin UI
-*/
-
#include <stdlib.h>
#include <gtk/gtk.h>
diff --git a/plugins/eg05-scope.lv2/README.txt b/plugins/eg05-scope.lv2/README.txt
index ec3578b..122794c 100644
--- a/plugins/eg05-scope.lv2/README.txt
+++ b/plugins/eg05-scope.lv2/README.txt
@@ -1,17 +1,19 @@
== Simple Oscilloscope ==
-This plugin displays the wave-form of an incoming audio-signal using a simple
+This plugin displays the waveform of an incoming audio signal using a simple
GTK+Cairo GUI.
This plugin illustrates:
-- UI <==> Plugin communication via LV2 atom events
-- LV2 Atom vector usage and resize-port extension
+- UI <==> Plugin communication via http://lv2plug.in/ns/ext/atom/[LV2 Atom] events
+- Atom vector usage and resize-port extension
- Save/Restore UI state by communicating state to backend
+- Saving simple key/value state via the http://lv2plug.in/ns/ext/state/[LV2 State] extension
- Cairo drawing and partial exposure
This plugin intends to outline the basics for building visualization plugins
-that rely on Atom communication. The UI looks likean oscilloscope, but is not a real oscilloscope implementation:
+that rely on atom communication. The UI looks like an oscilloscope, but is not
+a real oscilloscope implementation:
- There is no display synchronisation, results will depend on LV2 host.
- It displays raw audio samples, which a proper scope must not do.
diff --git a/plugins/eg05-scope.lv2/examploscope.c b/plugins/eg05-scope.lv2/examploscope.c
index ff64866..31e757a 100644
--- a/plugins/eg05-scope.lv2/examploscope.c
+++ b/plugins/eg05-scope.lv2/examploscope.c
@@ -25,7 +25,14 @@
#include "./uris.h"
-/** Private plugin instance structure. */
+/**
+ ==== Private Plugin Instance Structure ====
+
+ In addition to the usual port buffers and features, this plugin stores the
+ state of the UI here, so it can be opened and closed without losing the
+ current settings. The UI state is communicated between the plugin and the
+ UI using atom messages via a sequence port, similarly to MIDI I/O.
+*/
typedef struct {
// Port buffers
float* input[2];
@@ -47,27 +54,24 @@ typedef struct {
uint32_t n_channels;
double rate;
- /* The state of the UI is stored here, so that the GUI can be displayed and
- closed without losing the current settings. It is communicated to the
- UI using atom messages.
- */
+ // UI state
bool ui_active;
bool send_settings_to_ui;
float ui_amp;
uint32_t ui_spp;
} EgScope;
-/** Port indices. */
+/** ==== Port Indices ==== */
typedef enum {
- SCO_CONTROL = 0,
- SCO_NOTIFY = 1,
- SCO_INPUT0 = 2,
- SCO_OUTPUT0 = 3,
- SCO_INPUT1 = 4,
- SCO_OUTPUT1 = 5,
+ SCO_CONTROL = 0, // Event input
+ SCO_NOTIFY = 1, // Event output
+ SCO_INPUT0 = 2, // Audio input 0
+ SCO_OUTPUT0 = 3, // Audio output 0
+ SCO_INPUT1 = 4, // Audio input 1 (stereo variant)
+ SCO_OUTPUT1 = 5, // Audio input 2 (stereo variant)
} PortIndex;
-/** Create plugin instance. */
+/** ==== Instantiate Method ==== */
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double rate,
@@ -125,7 +129,7 @@ instantiate(const LV2_Descriptor* descriptor,
return (LV2_Handle)self;
}
-/** Connect a port to a buffer. */
+/** ==== Connect Port Method ==== */
static void
connect_port(LV2_Handle handle,
uint32_t port,
@@ -156,41 +160,49 @@ connect_port(LV2_Handle handle,
}
/**
- Forge vector of raw data.
-
- @param forge Forge to use.
- @param uris Mapped URI identifiers.
- @param channel Channel ID to transmit.
- @param n_samples Number of audio samples to transmit.
- @param data Actual audio data.
+ ==== Utility Function: `tx_rawaudio` ====
+
+ This function forges a message for sending a vector of raw data. The object
+ is a http://lv2plug.in/ns/ext/atom#Blank[Blank] with a few properties, like:
+ [source,txt]
+ --------
+ []
+ a sco:RawAudio ;
+ sco:channelID 0 ;
+ sco:audioData [ 0.0, 0.0, ... ] .
+ --------
+
+ where the value of the `sco:audioData` property, `[ 0.0, 0.0, ... ]`, is a
+ http://lv2plug.in/ns/ext/atom#Vector[Vector] of
+ http://lv2plug.in/ns/ext/atom#Float[Float].
*/
static void
tx_rawaudio(LV2_Atom_Forge* forge,
ScoLV2URIs* uris,
const int32_t channel,
const size_t n_samples,
- void* data)
+ const float* data)
{
LV2_Atom_Forge_Frame frame;
- // Forge container object of type 'rawaudio'
+ // Forge container object of type 'RawAudio'
lv2_atom_forge_frame_time(forge, 0);
lv2_atom_forge_blank(forge, &frame, 1, uris->RawAudio);
- // Add integer attribute 'channelid'
+ // Add integer 'channelID' property
lv2_atom_forge_property_head(forge, uris->channelID, 0);
lv2_atom_forge_int(forge, channel);
- // Add vector of floats raw 'audiodata'
+ // Add vector of floats 'audioData' property
lv2_atom_forge_property_head(forge, uris->audioData, 0);
lv2_atom_forge_vector(
forge, sizeof(float), uris->atom_Float, n_samples, data);
- // Close off atom-object
+ // Close off object
lv2_atom_forge_pop(forge, &frame);
}
-/** Process a block of audio */
+/** ==== Run Method ==== */
static void
run(LV2_Handle handle, uint32_t n_samples)
{
@@ -298,6 +310,16 @@ cleanup(LV2_Handle handle)
free(handle);
}
+
+/**
+ ==== State Methods ====
+
+ This plugin's state consists of two basic properties: one `int` and one
+ `float`. No files are used. Note these values are POD, but not portable,
+ since different machines may have a different integer endianness or floating
+ point format. However, since standard Atom types are used, a good host will
+ be able to save them portably as text anyway.
+*/
static LV2_State_Status
state_save(LV2_Handle instance,
LV2_State_Store_Function store,
@@ -310,11 +332,6 @@ state_save(LV2_Handle instance,
return LV2_STATE_SUCCESS;
}
- /* Store state values. Note these values are POD, but not portable, since
- different machines may have a different integer endianness or floating
- point format. However, since standard Atom types are used, a good host
- will be able to save them portably as text anyway. */
-
store(handle, self->uris.ui_spp,
(void*)&self->ui_spp, sizeof(uint32_t),
self->uris.atom_Int,
@@ -368,6 +385,7 @@ extension_data(const char* uri)
return NULL;
}
+/** ==== Plugin Descriptors ==== */
static const LV2_Descriptor descriptor_mono = {
SCO_URI "#Mono",
instantiate,
diff --git a/plugins/eg05-scope.lv2/manifest.ttl.in b/plugins/eg05-scope.lv2/manifest.ttl.in
index 028a673..a64aff1 100644
--- a/plugins/eg05-scope.lv2/manifest.ttl.in
+++ b/plugins/eg05-scope.lv2/manifest.ttl.in
@@ -2,16 +2,19 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
+# ==== Mono plugin variant ====
<http://lv2plug.in/plugins/eg-scope#Mono>
a lv2:Plugin ;
lv2:binary <examploscope@LIB_EXT@> ;
rdfs:seeAlso <examploscope.ttl> .
+# ==== Stereo plugin variant ====
<http://lv2plug.in/plugins/eg-scope#Stereo>
a lv2:Plugin ;
lv2:binary <examploscope@LIB_EXT@> ;
rdfs:seeAlso <examploscope.ttl> .
+# ==== Gtk 2.0 UI ====
<http://lv2plug.in/plugins/eg-scope#ui>
a ui:GtkUI ;
ui:binary <examploscope_ui@LIB_EXT@> ;
diff --git a/plugins/literasc.py b/plugins/literasc.py
index b7b65cd..7638e6f 100755
--- a/plugins/literasc.py
+++ b/plugins/literasc.py
@@ -36,16 +36,30 @@ def format_c_source(filename, file):
for line in file:
code += line
+ # Skip initial license comment
+ if code[0:2] == '/*':
+ code = code[code.find('*/') + 2:]
+
for c in code:
if prev_c == '/' and c == '*':
- output += format_code('c', chunk[0:len(chunk)-1])
- in_comment = True
in_comment_start = True
n_stars = 1
- chunk = ''
+ elif in_comment_start:
+ if c == '*':
+ n_stars += 1
+ else:
+ if n_stars > 1:
+ output += format_code('c', chunk[0:len(chunk)-1])
+ chunk = ''
+ in_comment = True
+ else:
+ chunk += '*' + c
+ in_comment_start = False
elif in_comment and prev_c == '*' and c == '/':
- if n_stars > 2:
+ if n_stars > 1:
output += format_text(chunk[0:len(chunk)-1])
+ else:
+ output += format_code('c', '/* ' + chunk[0:len(chunk)-1] + '*/')
in_comment = False
in_comment_start = False
chunk = ''