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/.hgignore Fri May 15 20:32:37 2020 +0200
1.3 @@ -0,0 +1,2 @@
1.4 +syntax: glob
1.5 +*.so
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/Makefile Fri May 15 20:32:37 2020 +0200
2.3 @@ -0,0 +1,20 @@
2.4 +all: amp.so
2.5 +
2.6 +amp.so: amp.cpp
2.7 + g++ -g -shared -fPIC amp.cpp -o amp.so
2.8 +
2.9 +clean:
2.10 + rm -f amp.so
2.11 +
2.12 +info: amp.so
2.13 + nm amp.so
2.14 + ldd amp.so
2.15 + file amp.so
2.16 +
2.17 +install: amp.so
2.18 + mkdir -p ~/.lv2/amp/
2.19 + cp amp.so amp.ttl manifest.ttl ~/.lv2/amp/
2.20 + lv2info http://lv2plug.in/plugins/eg-amp
2.21 +
2.22 +uninstall:
2.23 + rm -rf ~/.lv2/amp/
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/amp.cpp Fri May 15 20:32:37 2020 +0200
3.3 @@ -0,0 +1,222 @@
3.4 +/*
3.5 + Copyright 2006-2016 David Robillard <d@drobilla.net>
3.6 + Copyright 2006 Steve Harris <steve@plugin.org.uk>
3.7 +
3.8 + Permission to use, copy, modify, and/or distribute this software for any
3.9 + purpose with or without fee is hereby granted, provided that the above
3.10 + copyright notice and this permission notice appear in all copies.
3.11 +
3.12 + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3.13 + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3.14 + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3.15 + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3.16 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3.17 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3.18 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3.19 + */
3.20 +
3.21 +/**
3.22 + LV2 headers are based on the URI of the specification they come from, so a
3.23 + consistent convention can be used even for unofficial extensions. The URI
3.24 + of the core LV2 specification is <http://lv2plug.in/ns/lv2core>, by
3.25 + replacing `http:/` with `lv2` any header in the specification bundle can be
3.26 + included, in this case `lv2.h`.
3.27 + */
3.28 +#include <lv2.h>
3.29 +
3.30 +/** Include standard C headers */
3.31 +#include <math.h>
3.32 +#include <stdint.h>
3.33 +#include <stdlib.h>
3.34 +
3.35 +/**
3.36 + The URI is the identifier for a plugin, and how the host associates this
3.37 + implementation in code with its description in data. In this plugin it is
3.38 + only used once in the code, but defining the plugin URI at the top of the
3.39 + file is a good convention to follow. If this URI does not match that used
3.40 + in the data files, the host will fail to load the plugin.
3.41 + */
3.42 +#define AMP_URI "http://lv2plug.in/plugins/eg-amp"
3.43 +
3.44 +/**
3.45 + In code, ports are referred to by index. An enumeration of port indices
3.46 + should be defined for readability.
3.47 + */
3.48 +typedef enum {
3.49 + AMP_GAIN = 0,
3.50 + AMP_INPUT = 1,
3.51 + AMP_OUTPUT = 2
3.52 +} PortIndex;
3.53 +
3.54 +/**
3.55 + Every plugin defines a private structure for the plugin instance. All data
3.56 + associated with a plugin instance is stored here, and is available to
3.57 + every instance method. In this simple plugin, only port buffers need to be
3.58 + stored, since there is no additional instance data.
3.59 + */
3.60 +typedef struct {
3.61 + // Port buffers
3.62 + const float* gain;
3.63 + const float* input;
3.64 + float* output;
3.65 +} Amp;
3.66 +
3.67 +/**
3.68 + The `instantiate()` function is called by the host to create a new plugin
3.69 + instance. The host passes the plugin descriptor, sample rate, and bundle
3.70 + path for plugins that need to load additional resources (e.g. waveforms).
3.71 + The features parameter contains host-provided features defined in LV2
3.72 + extensions, but this simple plugin does not use any.
3.73 +
3.74 + This function is in the ``instantiation'' threading class, so no other
3.75 + methods on this instance will be called concurrently with it.
3.76 + */
3.77 +static LV2_Handle
3.78 +instantiate(const LV2_Descriptor* descriptor,
3.79 + double rate,
3.80 + const char* bundle_path,
3.81 + const LV2_Feature * const* features) {
3.82 + Amp* amp = (Amp*) calloc(1, sizeof (Amp));
3.83 +
3.84 + return (LV2_Handle) amp;
3.85 +}
3.86 +
3.87 +/**
3.88 + The `connect_port()` method is called by the host to connect a particular
3.89 + port to a buffer. The plugin must store the data location, but data may not
3.90 + be accessed except in run().
3.91 +
3.92 + This method is in the ``audio'' threading class, and is called in the same
3.93 + context as run().
3.94 + */
3.95 +static void
3.96 +connect_port(LV2_Handle instance,
3.97 + uint32_t port,
3.98 + void* data) {
3.99 + Amp* amp = (Amp*) instance;
3.100 +
3.101 + switch ((PortIndex) port) {
3.102 + case AMP_GAIN:
3.103 + amp->gain = (const float*) data;
3.104 + break;
3.105 + case AMP_INPUT:
3.106 + amp->input = (const float*) data;
3.107 + break;
3.108 + case AMP_OUTPUT:
3.109 + amp->output = (float*) data;
3.110 + break;
3.111 + }
3.112 +}
3.113 +
3.114 +/**
3.115 + The `activate()` method is called by the host to initialise and prepare the
3.116 + plugin instance for running. The plugin must reset all internal state
3.117 + except for buffer locations set by `connect_port()`. Since this plugin has
3.118 + no other internal state, this method does nothing.
3.119 +
3.120 + This method is in the ``instantiation'' threading class, so no other
3.121 + methods on this instance will be called concurrently with it.
3.122 + */
3.123 +static void
3.124 +activate(LV2_Handle instance) {
3.125 +}
3.126 +
3.127 +/** Define a macro for converting a gain in dB to a coefficient. */
3.128 +#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
3.129 +
3.130 +/**
3.131 + The `run()` method is the main process function of the plugin. It processes
3.132 + a block of audio in the audio context. Since this plugin is
3.133 + `lv2:hardRTCapable`, `run()` must be real-time safe, so blocking (e.g. with
3.134 + a mutex) or memory allocation are not allowed.
3.135 + */
3.136 +static void
3.137 +run(LV2_Handle instance, uint32_t n_samples) {
3.138 + const Amp* amp = (const Amp*) instance;
3.139 +
3.140 + const float gain = *(amp->gain);
3.141 + const float* const input = amp->input;
3.142 + float* const output = amp->output;
3.143 +
3.144 + const float coef = DB_CO(gain);
3.145 +
3.146 + for (uint32_t pos = 0; pos < n_samples; pos++) {
3.147 + output[pos] = input[pos] * coef;
3.148 + }
3.149 +}
3.150 +
3.151 +/**
3.152 + The `deactivate()` method is the counterpart to `activate()`, and is called by
3.153 + the host after running the plugin. It indicates that the host will not call
3.154 + `run()` again until another call to `activate()` and is mainly useful for more
3.155 + advanced plugins with ``live'' characteristics such as those with auxiliary
3.156 + processing threads. As with `activate()`, this plugin has no use for this
3.157 + information so this method does nothing.
3.158 +
3.159 + This method is in the ``instantiation'' threading class, so no other
3.160 + methods on this instance will be called concurrently with it.
3.161 + */
3.162 +static void
3.163 +deactivate(LV2_Handle instance) {
3.164 +}
3.165 +
3.166 +/**
3.167 + Destroy a plugin instance (counterpart to `instantiate()`).
3.168 +
3.169 + This method is in the ``instantiation'' threading class, so no other
3.170 + methods on this instance will be called concurrently with it.
3.171 + */
3.172 +static void
3.173 +cleanup(LV2_Handle instance) {
3.174 + free(instance);
3.175 +}
3.176 +
3.177 +/**
3.178 + The `extension_data()` function returns any extension data supported by the
3.179 + plugin. Note that this is not an instance method, but a function on the
3.180 + plugin descriptor. It is usually used by plugins to implement additional
3.181 + interfaces. This plugin does not have any extension data, so this function
3.182 + returns NULL.
3.183 +
3.184 + This method is in the ``discovery'' threading class, so no other functions
3.185 + or methods in this plugin library will be called concurrently with it.
3.186 + */
3.187 +static const void*
3.188 +extension_data(const char* uri) {
3.189 + return NULL;
3.190 +}
3.191 +
3.192 +/**
3.193 + Every plugin must define an `LV2_Descriptor`. It is best to define
3.194 + descriptors statically to avoid leaking memory and non-portable shared
3.195 + library constructors and destructors to clean up properly.
3.196 + */
3.197 +static const LV2_Descriptor descriptor = {
3.198 + AMP_URI,
3.199 + instantiate,
3.200 + connect_port,
3.201 + activate,
3.202 + run,
3.203 + deactivate,
3.204 + cleanup,
3.205 + extension_data
3.206 +};
3.207 +
3.208 +/**
3.209 + The `lv2_descriptor()` function is the entry point to the plugin library. The
3.210 + host will load the library and call this function repeatedly with increasing
3.211 + indices to find all the plugins defined in the library. The index is not an
3.212 + indentifier, the URI of the returned descriptor is used to determine the
3.213 + identify of the plugin.
3.214 +
3.215 + This method is in the ``discovery'' threading class, so no other functions
3.216 + or methods in this plugin library will be called concurrently with it.
3.217 + */
3.218 +LV2_SYMBOL_EXPORT
3.219 +const LV2_Descriptor*
3.220 +lv2_descriptor(uint32_t index) {
3.221 + switch (index) {
3.222 + case 0: return &descriptor;
3.223 + default: return NULL;
3.224 + }
3.225 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/amp.ttl Fri May 15 20:32:37 2020 +0200
4.3 @@ -0,0 +1,90 @@
4.4 +# The full description of the plugin is in this file, which is linked to from
4.5 +# `manifest.ttl`. This is done so the host only needs to scan the relatively
4.6 +# small `manifest.ttl` files to quickly discover all plugins.
4.7 +
4.8 +@prefix doap: <http://usefulinc.com/ns/doap#> .
4.9 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
4.10 +@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
4.11 +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4.12 +@prefix units: <http://lv2plug.in/ns/extensions/units#> .
4.13 +
4.14 +# First the type of the plugin is described. All plugins must explicitly list
4.15 +# `lv2:Plugin` as a type. A more specific type should also be given, where
4.16 +# applicable, so hosts can present a nicer UI for loading plugins. Note that
4.17 +# this URI is the identifier of the plugin, so if it does not match the one in
4.18 +# `manifest.ttl`, the host will not discover the plugin data at all.
4.19 +<http://lv2plug.in/plugins/eg-amp>
4.20 + a lv2:Plugin ,
4.21 + lv2:AmplifierPlugin ;
4.22 +# Plugins are associated with a project, where common information like
4.23 +# developers, home page, and so on are described. This plugin is part of the
4.24 +# LV2 project, which has URI <http://lv2plug.in/ns/lv2>, and is described
4.25 +# elsewhere. Typical plugin collections will describe the project in
4.26 +# manifest.ttl
4.27 + lv2:project <http://lv2plug.in/ns/lv2> ;
4.28 +# Every plugin must have a name, described with the doap:name property.
4.29 +# Translations to various languages can be added by putting a language tag
4.30 +# after strings as shown.
4.31 + doap:name "Simple Amplifier" ,
4.32 + "简单放大器"@zh ,
4.33 + "Einfacher Verstärker"@de ,
4.34 + "Simple Amplifier"@en-gb ,
4.35 + "Amplificador Simple"@es ,
4.36 + "Amplificateur de Base"@fr ,
4.37 + "Amplificatore Semplice"@it ,
4.38 + "簡単なアンプ"@jp ,
4.39 + "Просто Усилитель"@ru ;
4.40 + doap:license <http://opensource.org/licenses/isc> ;
4.41 + lv2:optionalFeature lv2:hardRTCapable ;
4.42 + lv2:port [
4.43 +# Every port must have at least two types, one that specifies direction
4.44 +# (lv2:InputPort or lv2:OutputPort), and another to describe the data type.
4.45 +# This port is a lv2:ControlPort, which means it contains a single float.
4.46 + a lv2:InputPort ,
4.47 + lv2:ControlPort ;
4.48 + lv2:index 0 ;
4.49 + lv2:symbol "gain" ;
4.50 + lv2:name "Gain" ,
4.51 + "收益"@zh ,
4.52 + "Verstärkung"@de ,
4.53 + "Gain"@en-gb ,
4.54 + "Aumento"@es ,
4.55 + "Gain"@fr ,
4.56 + "Guadagno"@it ,
4.57 + "利益"@jp ,
4.58 + "Увеличение"@ru ;
4.59 +# An lv2:ControlPort should always describe its default value, and usually a
4.60 +# minimum and maximum value. Defining a range is not strictly required, but
4.61 +# should be done wherever possible to aid host support, particularly for UIs.
4.62 + lv2:default 0.0 ;
4.63 + lv2:minimum -90.0 ;
4.64 + lv2:maximum 24.0 ;
4.65 +# Ports can describe units and control detents to allow better UI generation
4.66 +# and host automation.
4.67 + units:unit units:db ;
4.68 + lv2:scalePoint [
4.69 + rdfs:label "+5" ;
4.70 + rdf:value 5.0
4.71 + ] , [
4.72 + rdfs:label "0" ;
4.73 + rdf:value 0.0
4.74 + ] , [
4.75 + rdfs:label "-5" ;
4.76 + rdf:value -5.0
4.77 + ] , [
4.78 + rdfs:label "-10" ;
4.79 + rdf:value -10.0
4.80 + ]
4.81 + ] , [
4.82 + a lv2:AudioPort ,
4.83 + lv2:InputPort ;
4.84 + lv2:index 1 ;
4.85 + lv2:symbol "in" ;
4.86 + lv2:name "In"
4.87 + ] , [
4.88 + a lv2:AudioPort ,
4.89 + lv2:OutputPort ;
4.90 + lv2:index 2 ;
4.91 + lv2:symbol "out" ;
4.92 + lv2:name "Out"
4.93 + ] .
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/manifest.ttl Fri May 15 20:32:37 2020 +0200
5.3 @@ -0,0 +1,68 @@
5.4 +# LV2 plugins are installed in a ``bundle'', a directory with a standard
5.5 +# structure. Each bundle has a Turtle file named `manifest.ttl` which lists
5.6 +# the contents of the bundle.
5.7 +#
5.8 +# Hosts typically read the manifest of every installed bundle to discover
5.9 +# plugins on start-up, so it should be as small as possible for performance
5.10 +# reasons. Details that are only useful if the host chooses to load the plugin
5.11 +# are stored in other files and linked to from `manifest.ttl`.
5.12 +#
5.13 +# ==== URIs ====
5.14 +#
5.15 +# LV2 makes use of URIs as globally-unique identifiers for resources. For
5.16 +# example, the ID of the plugin described here is
5.17 +# `<http://lv2plug.in/plugins/eg-amp>`. Note that URIs are only used as
5.18 +# identifiers and don't necessarily imply that something can be accessed at
5.19 +# that address on the web (though that may be the case).
5.20 +#
5.21 +# ==== Namespace Prefixes ====
5.22 +#
5.23 +# Turtle files contain many URIs, but prefixes can be defined to improve
5.24 +# readability. For example, with the `lv2:` prefix below, `lv2:Plugin` can be
5.25 +# written instead of `<http://lv2plug.in/ns/lv2core#Plugin>`.
5.26 +
5.27 +@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
5.28 +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
5.29 +
5.30 +# ==== Describing a Plugin ====
5.31 +
5.32 +# Turtle files contain a set of ``statements'' which describe resources.
5.33 +# This file contains 3 statements:
5.34 +# [options="header"]
5.35 +# |================================================================
5.36 +# | Subject | Predicate | Object
5.37 +# | <http://lv2plug.in/plugins/eg-amp> | a | lv2:Plugin
5.38 +# | <http://lv2plug.in/plugins/eg-amp> | lv2:binary | <amp.so>
5.39 +# | <http://lv2plug.in/plugins/eg-amp> | rdfs:seeAlso | <amp.ttl>
5.40 +# |================================================================
5.41 +
5.42 +# Firstly, `<http://lv2plug.in/plugins/eg-amp>` is an LV2 plugin:
5.43 +<http://lv2plug.in/plugins/eg-amp> a lv2:Plugin .
5.44 +
5.45 +# The predicate ```a`'' is a Turtle shorthand for `rdf:type`.
5.46 +
5.47 +# The binary of that plugin can be found at `<amp.ext>`:
5.48 +<http://lv2plug.in/plugins/eg-amp> lv2:binary <amp.so> .
5.49 +
5.50 +# This file is a template; the token `@LIB_EXT@` is replaced by the build
5.51 +# system with the appropriate extension for the current platform before
5.52 +# installation. For example, in the output `manifest.ttl`, the binary would be
5.53 +# listed as `<amp.so>`. Relative URIs in manifests are relative to the bundle
5.54 +# directory, so this refers to a binary with the given name in the same
5.55 +# directory as this manifest.
5.56 +
5.57 +# Finally, more information about this plugin can be found in `<amp.ttl>`:
5.58 +<http://lv2plug.in/plugins/eg-amp> rdfs:seeAlso <amp.ttl> .
5.59 +
5.60 +# ==== Abbreviation ====
5.61 +#
5.62 +# This file shows these statements individually for instructive purposes, but
5.63 +# the subject `<http://lv2plug.in/plugins/eg-amp>` is repetitive. Turtle
5.64 +# allows the semicolon to be used as a delimiter that repeats the previous
5.65 +# subject. For example, this manifest would more realistically be written like
5.66 +# so:
5.67 +
5.68 +<http://lv2plug.in/plugins/eg-amp>
5.69 + a lv2:Plugin ;
5.70 + lv2:binary <amp.so> ;
5.71 + rdfs:seeAlso <amp.ttl> .