c++/lv2-demo-modul/amp.cpp
changeset 59 d6614ad97bed
     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 +}