diff options
| author | David Robillard <d@drobilla.net> | 2013-12-25 17:59:16 +0000 | 
|---|---|---|
| committer | David Robillard <d@drobilla.net> | 2013-12-25 17:59:16 +0000 | 
| commit | 8b1275387c758c1ee894647517e5fb30adaa3ea4 (patch) | |
| tree | 8f498ea7f856c3acf20c30caeea89ba37036ceec /plugins | |
| parent | 74c991974146ab389d66052de904a84b44adf3ad (diff) | |
| download | lv2-8b1275387c758c1ee894647517e5fb30adaa3ea4.tar.xz | |
Bookify examploscope documentation.
Fix book generator to include single-star C comments in code blocks.
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/README.txt | 2 | ||||
| -rw-r--r-- | plugins/eg01-amp.lv2/README.txt | 18 | ||||
| -rw-r--r-- | plugins/eg01-amp.lv2/manifest.ttl.in | 30 | ||||
| -rw-r--r-- | plugins/eg04-sampler.lv2/sampler_ui.c | 4 | ||||
| -rw-r--r-- | plugins/eg05-scope.lv2/README.txt | 10 | ||||
| -rw-r--r-- | plugins/eg05-scope.lv2/examploscope.c | 82 | ||||
| -rw-r--r-- | plugins/eg05-scope.lv2/manifest.ttl.in | 3 | ||||
| -rwxr-xr-x | plugins/literasc.py | 22 | 
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 = ''  |