LV2: modul zesilovače, dle oficiálního příkladu, ale bez závislosti na Pythonu – stačí gcc a make
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/c++/lv2-demo-modul/Makefile Fri May 15 20:32:37 2020 +0200
1.3 @@ -0,0 +1,20 @@
1.4 +all: amp.so
1.5 +
1.6 +amp.so: amp.cpp
1.7 + g++ -g -shared -fPIC amp.cpp -o amp.so
1.8 +
1.9 +clean:
1.10 + rm -f amp.so
1.11 +
1.12 +info: amp.so
1.13 + nm amp.so
1.14 + ldd amp.so
1.15 + file amp.so
1.16 +
1.17 +install: amp.so
1.18 + mkdir -p ~/.lv2/amp/
1.19 + cp amp.so amp.ttl manifest.ttl ~/.lv2/amp/
1.20 + lv2info http://lv2plug.in/plugins/eg-amp
1.21 +
1.22 +uninstall:
1.23 + rm -rf ~/.lv2/amp/
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/c++/lv2-demo-modul/amp.cpp Fri May 15 20:32:37 2020 +0200
2.3 @@ -0,0 +1,222 @@
2.4 +/*
2.5 + Copyright 2006-2016 David Robillard <d@drobilla.net>
2.6 + Copyright 2006 Steve Harris <steve@plugin.org.uk>
2.7 +
2.8 + Permission to use, copy, modify, and/or distribute this software for any
2.9 + purpose with or without fee is hereby granted, provided that the above
2.10 + copyright notice and this permission notice appear in all copies.
2.11 +
2.12 + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2.13 + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2.14 + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2.15 + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2.16 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2.17 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2.18 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2.19 + */
2.20 +
2.21 +/**
2.22 + LV2 headers are based on the URI of the specification they come from, so a
2.23 + consistent convention can be used even for unofficial extensions. The URI
2.24 + of the core LV2 specification is <http://lv2plug.in/ns/lv2core>, by
2.25 + replacing `http:/` with `lv2` any header in the specification bundle can be
2.26 + included, in this case `lv2.h`.
2.27 + */
2.28 +#include <lv2.h>
2.29 +
2.30 +/** Include standard C headers */
2.31 +#include <math.h>
2.32 +#include <stdint.h>
2.33 +#include <stdlib.h>
2.34 +
2.35 +/**
2.36 + The URI is the identifier for a plugin, and how the host associates this
2.37 + implementation in code with its description in data. In this plugin it is
2.38 + only used once in the code, but defining the plugin URI at the top of the
2.39 + file is a good convention to follow. If this URI does not match that used
2.40 + in the data files, the host will fail to load the plugin.
2.41 + */
2.42 +#define AMP_URI "http://lv2plug.in/plugins/eg-amp"
2.43 +
2.44 +/**
2.45 + In code, ports are referred to by index. An enumeration of port indices
2.46 + should be defined for readability.
2.47 + */
2.48 +typedef enum {
2.49 + AMP_GAIN = 0,
2.50 + AMP_INPUT = 1,
2.51 + AMP_OUTPUT = 2
2.52 +} PortIndex;
2.53 +
2.54 +/**
2.55 + Every plugin defines a private structure for the plugin instance. All data
2.56 + associated with a plugin instance is stored here, and is available to
2.57 + every instance method. In this simple plugin, only port buffers need to be
2.58 + stored, since there is no additional instance data.
2.59 + */
2.60 +typedef struct {
2.61 + // Port buffers
2.62 + const float* gain;
2.63 + const float* input;
2.64 + float* output;
2.65 +} Amp;
2.66 +
2.67 +/**
2.68 + The `instantiate()` function is called by the host to create a new plugin
2.69 + instance. The host passes the plugin descriptor, sample rate, and bundle
2.70 + path for plugins that need to load additional resources (e.g. waveforms).
2.71 + The features parameter contains host-provided features defined in LV2
2.72 + extensions, but this simple plugin does not use any.
2.73 +
2.74 + This function is in the ``instantiation'' threading class, so no other
2.75 + methods on this instance will be called concurrently with it.
2.76 + */
2.77 +static LV2_Handle
2.78 +instantiate(const LV2_Descriptor* descriptor,
2.79 + double rate,
2.80 + const char* bundle_path,
2.81 + const LV2_Feature * const* features) {
2.82 + Amp* amp = (Amp*) calloc(1, sizeof (Amp));
2.83 +
2.84 + return (LV2_Handle) amp;
2.85 +}
2.86 +
2.87 +/**
2.88 + The `connect_port()` method is called by the host to connect a particular
2.89 + port to a buffer. The plugin must store the data location, but data may not
2.90 + be accessed except in run().
2.91 +
2.92 + This method is in the ``audio'' threading class, and is called in the same
2.93 + context as run().
2.94 + */
2.95 +static void
2.96 +connect_port(LV2_Handle instance,
2.97 + uint32_t port,
2.98 + void* data) {
2.99 + Amp* amp = (Amp*) instance;
2.100 +
2.101 + switch ((PortIndex) port) {
2.102 + case AMP_GAIN:
2.103 + amp->gain = (const float*) data;
2.104 + break;
2.105 + case AMP_INPUT:
2.106 + amp->input = (const float*) data;
2.107 + break;
2.108 + case AMP_OUTPUT:
2.109 + amp->output = (float*) data;
2.110 + break;
2.111 + }
2.112 +}
2.113 +
2.114 +/**
2.115 + The `activate()` method is called by the host to initialise and prepare the
2.116 + plugin instance for running. The plugin must reset all internal state
2.117 + except for buffer locations set by `connect_port()`. Since this plugin has
2.118 + no other internal state, this method does nothing.
2.119 +
2.120 + This method is in the ``instantiation'' threading class, so no other
2.121 + methods on this instance will be called concurrently with it.
2.122 + */
2.123 +static void
2.124 +activate(LV2_Handle instance) {
2.125 +}
2.126 +
2.127 +/** Define a macro for converting a gain in dB to a coefficient. */
2.128 +#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
2.129 +
2.130 +/**
2.131 + The `run()` method is the main process function of the plugin. It processes
2.132 + a block of audio in the audio context. Since this plugin is
2.133 + `lv2:hardRTCapable`, `run()` must be real-time safe, so blocking (e.g. with
2.134 + a mutex) or memory allocation are not allowed.
2.135 + */
2.136 +static void
2.137 +run(LV2_Handle instance, uint32_t n_samples) {
2.138 + const Amp* amp = (const Amp*) instance;
2.139 +
2.140 + const float gain = *(amp->gain);
2.141 + const float* const input = amp->input;
2.142 + float* const output = amp->output;
2.143 +
2.144 + const float coef = DB_CO(gain);
2.145 +
2.146 + for (uint32_t pos = 0; pos < n_samples; pos++) {
2.147 + output[pos] = input[pos] * coef;
2.148 + }
2.149 +}
2.150 +
2.151 +/**
2.152 + The `deactivate()` method is the counterpart to `activate()`, and is called by
2.153 + the host after running the plugin. It indicates that the host will not call
2.154 + `run()` again until another call to `activate()` and is mainly useful for more
2.155 + advanced plugins with ``live'' characteristics such as those with auxiliary
2.156 + processing threads. As with `activate()`, this plugin has no use for this
2.157 + information so this method does nothing.
2.158 +
2.159 + This method is in the ``instantiation'' threading class, so no other
2.160 + methods on this instance will be called concurrently with it.
2.161 + */
2.162 +static void
2.163 +deactivate(LV2_Handle instance) {
2.164 +}
2.165 +
2.166 +/**
2.167 + Destroy a plugin instance (counterpart to `instantiate()`).
2.168 +
2.169 + This method is in the ``instantiation'' threading class, so no other
2.170 + methods on this instance will be called concurrently with it.
2.171 + */
2.172 +static void
2.173 +cleanup(LV2_Handle instance) {
2.174 + free(instance);
2.175 +}
2.176 +
2.177 +/**
2.178 + The `extension_data()` function returns any extension data supported by the
2.179 + plugin. Note that this is not an instance method, but a function on the
2.180 + plugin descriptor. It is usually used by plugins to implement additional
2.181 + interfaces. This plugin does not have any extension data, so this function
2.182 + returns NULL.
2.183 +
2.184 + This method is in the ``discovery'' threading class, so no other functions
2.185 + or methods in this plugin library will be called concurrently with it.
2.186 + */
2.187 +static const void*
2.188 +extension_data(const char* uri) {
2.189 + return NULL;
2.190 +}
2.191 +
2.192 +/**
2.193 + Every plugin must define an `LV2_Descriptor`. It is best to define
2.194 + descriptors statically to avoid leaking memory and non-portable shared
2.195 + library constructors and destructors to clean up properly.
2.196 + */
2.197 +static const LV2_Descriptor descriptor = {
2.198 + AMP_URI,
2.199 + instantiate,
2.200 + connect_port,
2.201 + activate,
2.202 + run,
2.203 + deactivate,
2.204 + cleanup,
2.205 + extension_data
2.206 +};
2.207 +
2.208 +/**
2.209 + The `lv2_descriptor()` function is the entry point to the plugin library. The
2.210 + host will load the library and call this function repeatedly with increasing
2.211 + indices to find all the plugins defined in the library. The index is not an
2.212 + indentifier, the URI of the returned descriptor is used to determine the
2.213 + identify of the plugin.
2.214 +
2.215 + This method is in the ``discovery'' threading class, so no other functions
2.216 + or methods in this plugin library will be called concurrently with it.
2.217 + */
2.218 +LV2_SYMBOL_EXPORT
2.219 +const LV2_Descriptor*
2.220 +lv2_descriptor(uint32_t index) {
2.221 + switch (index) {
2.222 + case 0: return &descriptor;
2.223 + default: return NULL;
2.224 + }
2.225 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/c++/lv2-demo-modul/amp.ttl Fri May 15 20:32:37 2020 +0200
3.3 @@ -0,0 +1,90 @@
3.4 +# The full description of the plugin is in this file, which is linked to from
3.5 +# `manifest.ttl`. This is done so the host only needs to scan the relatively
3.6 +# small `manifest.ttl` files to quickly discover all plugins.
3.7 +
3.8 +@prefix doap: <http://usefulinc.com/ns/doap#> .
3.9 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
3.10 +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
3.11 +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
3.12 +@prefix units: <http://lv2plug.in/ns/extensions/units#> .
3.13 +
3.14 +# First the type of the plugin is described. All plugins must explicitly list
3.15 +# `lv2:Plugin` as a type. A more specific type should also be given, where
3.16 +# applicable, so hosts can present a nicer UI for loading plugins. Note that
3.17 +# this URI is the identifier of the plugin, so if it does not match the one in
3.18 +# `manifest.ttl`, the host will not discover the plugin data at all.
3.19 +<http://lv2plug.in/plugins/eg-amp>
3.20 + a lv2:Plugin ,
3.21 + lv2:AmplifierPlugin ;
3.22 +# Plugins are associated with a project, where common information like
3.23 +# developers, home page, and so on are described. This plugin is part of the
3.24 +# LV2 project, which has URI <http://lv2plug.in/ns/lv2>, and is described
3.25 +# elsewhere. Typical plugin collections will describe the project in
3.26 +# manifest.ttl
3.27 + lv2:project <http://lv2plug.in/ns/lv2> ;
3.28 +# Every plugin must have a name, described with the doap:name property.
3.29 +# Translations to various languages can be added by putting a language tag
3.30 +# after strings as shown.
3.31 + doap:name "Simple Amplifier" ,
3.32 + "简单放大器"@zh ,
3.33 + "Einfacher Verstärker"@de ,
3.34 + "Simple Amplifier"@en-gb ,
3.35 + "Amplificador Simple"@es ,
3.36 + "Amplificateur de Base"@fr ,
3.37 + "Amplificatore Semplice"@it ,
3.38 + "簡単なアンプ"@jp ,
3.39 + "Просто Усилитель"@ru ;
3.40 + doap:license <http://opensource.org/licenses/isc> ;
3.41 + lv2:optionalFeature lv2:hardRTCapable ;
3.42 + lv2:port [
3.43 +# Every port must have at least two types, one that specifies direction
3.44 +# (lv2:InputPort or lv2:OutputPort), and another to describe the data type.
3.45 +# This port is a lv2:ControlPort, which means it contains a single float.
3.46 + a lv2:InputPort ,
3.47 + lv2:ControlPort ;
3.48 + lv2:index 0 ;
3.49 + lv2:symbol "gain" ;
3.50 + lv2:name "Gain" ,
3.51 + "收益"@zh ,
3.52 + "Verstärkung"@de ,
3.53 + "Gain"@en-gb ,
3.54 + "Aumento"@es ,
3.55 + "Gain"@fr ,
3.56 + "Guadagno"@it ,
3.57 + "利益"@jp ,
3.58 + "Увеличение"@ru ;
3.59 +# An lv2:ControlPort should always describe its default value, and usually a
3.60 +# minimum and maximum value. Defining a range is not strictly required, but
3.61 +# should be done wherever possible to aid host support, particularly for UIs.
3.62 + lv2:default 0.0 ;
3.63 + lv2:minimum -90.0 ;
3.64 + lv2:maximum 24.0 ;
3.65 +# Ports can describe units and control detents to allow better UI generation
3.66 +# and host automation.
3.67 + units:unit units:db ;
3.68 + lv2:scalePoint [
3.69 + rdfs:label "+5" ;
3.70 + rdf:value 5.0
3.71 + ] , [
3.72 + rdfs:label "0" ;
3.73 + rdf:value 0.0
3.74 + ] , [
3.75 + rdfs:label "-5" ;
3.76 + rdf:value -5.0
3.77 + ] , [
3.78 + rdfs:label "-10" ;
3.79 + rdf:value -10.0
3.80 + ]
3.81 + ] , [
3.82 + a lv2:AudioPort ,
3.83 + lv2:InputPort ;
3.84 + lv2:index 1 ;
3.85 + lv2:symbol "in" ;
3.86 + lv2:name "In"
3.87 + ] , [
3.88 + a lv2:AudioPort ,
3.89 + lv2:OutputPort ;
3.90 + lv2:index 2 ;
3.91 + lv2:symbol "out" ;
3.92 + lv2:name "Out"
3.93 + ] .
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/c++/lv2-demo-modul/manifest.ttl Fri May 15 20:32:37 2020 +0200
4.3 @@ -0,0 +1,68 @@
4.4 +# LV2 plugins are installed in a ``bundle'', a directory with a standard
4.5 +# structure. Each bundle has a Turtle file named `manifest.ttl` which lists
4.6 +# the contents of the bundle.
4.7 +#
4.8 +# Hosts typically read the manifest of every installed bundle to discover
4.9 +# plugins on start-up, so it should be as small as possible for performance
4.10 +# reasons. Details that are only useful if the host chooses to load the plugin
4.11 +# are stored in other files and linked to from `manifest.ttl`.
4.12 +#
4.13 +# ==== URIs ====
4.14 +#
4.15 +# LV2 makes use of URIs as globally-unique identifiers for resources. For
4.16 +# example, the ID of the plugin described here is
4.17 +# `<http://lv2plug.in/plugins/eg-amp>`. Note that URIs are only used as
4.18 +# identifiers and don't necessarily imply that something can be accessed at
4.19 +# that address on the web (though that may be the case).
4.20 +#
4.21 +# ==== Namespace Prefixes ====
4.22 +#
4.23 +# Turtle files contain many URIs, but prefixes can be defined to improve
4.24 +# readability. For example, with the `lv2:` prefix below, `lv2:Plugin` can be
4.25 +# written instead of `<http://lv2plug.in/ns/lv2core#Plugin>`.
4.26 +
4.27 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
4.28 +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4.29 +
4.30 +# ==== Describing a Plugin ====
4.31 +
4.32 +# Turtle files contain a set of ``statements'' which describe resources.
4.33 +# This file contains 3 statements:
4.34 +# [options="header"]
4.35 +# |================================================================
4.36 +# | Subject | Predicate | Object
4.37 +# | <http://lv2plug.in/plugins/eg-amp> | a | lv2:Plugin
4.38 +# | <http://lv2plug.in/plugins/eg-amp> | lv2:binary | <amp.so>
4.39 +# | <http://lv2plug.in/plugins/eg-amp> | rdfs:seeAlso | <amp.ttl>
4.40 +# |================================================================
4.41 +
4.42 +# Firstly, `<http://lv2plug.in/plugins/eg-amp>` is an LV2 plugin:
4.43 +<http://lv2plug.in/plugins/eg-amp> a lv2:Plugin .
4.44 +
4.45 +# The predicate ```a`'' is a Turtle shorthand for `rdf:type`.
4.46 +
4.47 +# The binary of that plugin can be found at `<amp.ext>`:
4.48 +<http://lv2plug.in/plugins/eg-amp> lv2:binary <amp.so> .
4.49 +
4.50 +# This file is a template; the token `@LIB_EXT@` is replaced by the build
4.51 +# system with the appropriate extension for the current platform before
4.52 +# installation. For example, in the output `manifest.ttl`, the binary would be
4.53 +# listed as `<amp.so>`. Relative URIs in manifests are relative to the bundle
4.54 +# directory, so this refers to a binary with the given name in the same
4.55 +# directory as this manifest.
4.56 +
4.57 +# Finally, more information about this plugin can be found in `<amp.ttl>`:
4.58 +<http://lv2plug.in/plugins/eg-amp> rdfs:seeAlso <amp.ttl> .
4.59 +
4.60 +# ==== Abbreviation ====
4.61 +#
4.62 +# This file shows these statements individually for instructive purposes, but
4.63 +# the subject `<http://lv2plug.in/plugins/eg-amp>` is repetitive. Turtle
4.64 +# allows the semicolon to be used as a delimiter that repeats the previous
4.65 +# subject. For example, this manifest would more realistically be written like
4.66 +# so:
4.67 +
4.68 +<http://lv2plug.in/plugins/eg-amp>
4.69 + a lv2:Plugin ;
4.70 + lv2:binary <amp.so> ;
4.71 + rdfs:seeAlso <amp.ttl> .