1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/c++/lv2-demo-modul/amp.cpp Fri May 15 20:32:37 2020 +0200
1.3 @@ -0,0 +1,222 @@
1.4 +/*
1.5 + Copyright 2006-2016 David Robillard <d@drobilla.net>
1.6 + Copyright 2006 Steve Harris <steve@plugin.org.uk>
1.7 +
1.8 + Permission to use, copy, modify, and/or distribute this software for any
1.9 + purpose with or without fee is hereby granted, provided that the above
1.10 + copyright notice and this permission notice appear in all copies.
1.11 +
1.12 + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1.13 + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1.14 + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1.15 + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1.16 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1.17 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1.18 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.19 + */
1.20 +
1.21 +/**
1.22 + LV2 headers are based on the URI of the specification they come from, so a
1.23 + consistent convention can be used even for unofficial extensions. The URI
1.24 + of the core LV2 specification is <http://lv2plug.in/ns/lv2core>, by
1.25 + replacing `http:/` with `lv2` any header in the specification bundle can be
1.26 + included, in this case `lv2.h`.
1.27 + */
1.28 +#include <lv2.h>
1.29 +
1.30 +/** Include standard C headers */
1.31 +#include <math.h>
1.32 +#include <stdint.h>
1.33 +#include <stdlib.h>
1.34 +
1.35 +/**
1.36 + The URI is the identifier for a plugin, and how the host associates this
1.37 + implementation in code with its description in data. In this plugin it is
1.38 + only used once in the code, but defining the plugin URI at the top of the
1.39 + file is a good convention to follow. If this URI does not match that used
1.40 + in the data files, the host will fail to load the plugin.
1.41 + */
1.42 +#define AMP_URI "http://lv2plug.in/plugins/eg-amp"
1.43 +
1.44 +/**
1.45 + In code, ports are referred to by index. An enumeration of port indices
1.46 + should be defined for readability.
1.47 + */
1.48 +typedef enum {
1.49 + AMP_GAIN = 0,
1.50 + AMP_INPUT = 1,
1.51 + AMP_OUTPUT = 2
1.52 +} PortIndex;
1.53 +
1.54 +/**
1.55 + Every plugin defines a private structure for the plugin instance. All data
1.56 + associated with a plugin instance is stored here, and is available to
1.57 + every instance method. In this simple plugin, only port buffers need to be
1.58 + stored, since there is no additional instance data.
1.59 + */
1.60 +typedef struct {
1.61 + // Port buffers
1.62 + const float* gain;
1.63 + const float* input;
1.64 + float* output;
1.65 +} Amp;
1.66 +
1.67 +/**
1.68 + The `instantiate()` function is called by the host to create a new plugin
1.69 + instance. The host passes the plugin descriptor, sample rate, and bundle
1.70 + path for plugins that need to load additional resources (e.g. waveforms).
1.71 + The features parameter contains host-provided features defined in LV2
1.72 + extensions, but this simple plugin does not use any.
1.73 +
1.74 + This function is in the ``instantiation'' threading class, so no other
1.75 + methods on this instance will be called concurrently with it.
1.76 + */
1.77 +static LV2_Handle
1.78 +instantiate(const LV2_Descriptor* descriptor,
1.79 + double rate,
1.80 + const char* bundle_path,
1.81 + const LV2_Feature * const* features) {
1.82 + Amp* amp = (Amp*) calloc(1, sizeof (Amp));
1.83 +
1.84 + return (LV2_Handle) amp;
1.85 +}
1.86 +
1.87 +/**
1.88 + The `connect_port()` method is called by the host to connect a particular
1.89 + port to a buffer. The plugin must store the data location, but data may not
1.90 + be accessed except in run().
1.91 +
1.92 + This method is in the ``audio'' threading class, and is called in the same
1.93 + context as run().
1.94 + */
1.95 +static void
1.96 +connect_port(LV2_Handle instance,
1.97 + uint32_t port,
1.98 + void* data) {
1.99 + Amp* amp = (Amp*) instance;
1.100 +
1.101 + switch ((PortIndex) port) {
1.102 + case AMP_GAIN:
1.103 + amp->gain = (const float*) data;
1.104 + break;
1.105 + case AMP_INPUT:
1.106 + amp->input = (const float*) data;
1.107 + break;
1.108 + case AMP_OUTPUT:
1.109 + amp->output = (float*) data;
1.110 + break;
1.111 + }
1.112 +}
1.113 +
1.114 +/**
1.115 + The `activate()` method is called by the host to initialise and prepare the
1.116 + plugin instance for running. The plugin must reset all internal state
1.117 + except for buffer locations set by `connect_port()`. Since this plugin has
1.118 + no other internal state, this method does nothing.
1.119 +
1.120 + This method is in the ``instantiation'' threading class, so no other
1.121 + methods on this instance will be called concurrently with it.
1.122 + */
1.123 +static void
1.124 +activate(LV2_Handle instance) {
1.125 +}
1.126 +
1.127 +/** Define a macro for converting a gain in dB to a coefficient. */
1.128 +#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
1.129 +
1.130 +/**
1.131 + The `run()` method is the main process function of the plugin. It processes
1.132 + a block of audio in the audio context. Since this plugin is
1.133 + `lv2:hardRTCapable`, `run()` must be real-time safe, so blocking (e.g. with
1.134 + a mutex) or memory allocation are not allowed.
1.135 + */
1.136 +static void
1.137 +run(LV2_Handle instance, uint32_t n_samples) {
1.138 + const Amp* amp = (const Amp*) instance;
1.139 +
1.140 + const float gain = *(amp->gain);
1.141 + const float* const input = amp->input;
1.142 + float* const output = amp->output;
1.143 +
1.144 + const float coef = DB_CO(gain);
1.145 +
1.146 + for (uint32_t pos = 0; pos < n_samples; pos++) {
1.147 + output[pos] = input[pos] * coef;
1.148 + }
1.149 +}
1.150 +
1.151 +/**
1.152 + The `deactivate()` method is the counterpart to `activate()`, and is called by
1.153 + the host after running the plugin. It indicates that the host will not call
1.154 + `run()` again until another call to `activate()` and is mainly useful for more
1.155 + advanced plugins with ``live'' characteristics such as those with auxiliary
1.156 + processing threads. As with `activate()`, this plugin has no use for this
1.157 + information so this method does nothing.
1.158 +
1.159 + This method is in the ``instantiation'' threading class, so no other
1.160 + methods on this instance will be called concurrently with it.
1.161 + */
1.162 +static void
1.163 +deactivate(LV2_Handle instance) {
1.164 +}
1.165 +
1.166 +/**
1.167 + Destroy a plugin instance (counterpart to `instantiate()`).
1.168 +
1.169 + This method is in the ``instantiation'' threading class, so no other
1.170 + methods on this instance will be called concurrently with it.
1.171 + */
1.172 +static void
1.173 +cleanup(LV2_Handle instance) {
1.174 + free(instance);
1.175 +}
1.176 +
1.177 +/**
1.178 + The `extension_data()` function returns any extension data supported by the
1.179 + plugin. Note that this is not an instance method, but a function on the
1.180 + plugin descriptor. It is usually used by plugins to implement additional
1.181 + interfaces. This plugin does not have any extension data, so this function
1.182 + returns NULL.
1.183 +
1.184 + This method is in the ``discovery'' threading class, so no other functions
1.185 + or methods in this plugin library will be called concurrently with it.
1.186 + */
1.187 +static const void*
1.188 +extension_data(const char* uri) {
1.189 + return NULL;
1.190 +}
1.191 +
1.192 +/**
1.193 + Every plugin must define an `LV2_Descriptor`. It is best to define
1.194 + descriptors statically to avoid leaking memory and non-portable shared
1.195 + library constructors and destructors to clean up properly.
1.196 + */
1.197 +static const LV2_Descriptor descriptor = {
1.198 + AMP_URI,
1.199 + instantiate,
1.200 + connect_port,
1.201 + activate,
1.202 + run,
1.203 + deactivate,
1.204 + cleanup,
1.205 + extension_data
1.206 +};
1.207 +
1.208 +/**
1.209 + The `lv2_descriptor()` function is the entry point to the plugin library. The
1.210 + host will load the library and call this function repeatedly with increasing
1.211 + indices to find all the plugins defined in the library. The index is not an
1.212 + indentifier, the URI of the returned descriptor is used to determine the
1.213 + identify of the plugin.
1.214 +
1.215 + This method is in the ``discovery'' threading class, so no other functions
1.216 + or methods in this plugin library will be called concurrently with it.
1.217 + */
1.218 +LV2_SYMBOL_EXPORT
1.219 +const LV2_Descriptor*
1.220 +lv2_descriptor(uint32_t index) {
1.221 + switch (index) {
1.222 + case 0: return &descriptor;
1.223 + default: return NULL;
1.224 + }
1.225 +}