From d7c3eb0dbf928c0ea7e1ab6af9633efd6372f6ad Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 18 Aug 2014 20:05:44 +0100 Subject: [PATCH] Add parameters example --- dpf | 2 +- plugins/Parameters/DistrhoPluginInfo.h | 35 +++ .../Parameters/ExamplePluginParameters.cpp | 224 ++++++++++++++++++ plugins/Parameters/ExampleUIParameters.cpp | 222 +++++++++++++++++ plugins/Parameters/Makefile | 35 +++ plugins/Parameters/README.md | 9 + 6 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 plugins/Parameters/DistrhoPluginInfo.h create mode 100644 plugins/Parameters/ExamplePluginParameters.cpp create mode 100644 plugins/Parameters/ExampleUIParameters.cpp create mode 100644 plugins/Parameters/Makefile create mode 100644 plugins/Parameters/README.md diff --git a/dpf b/dpf index e06cb84..b9dcf5c 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit e06cb84757bc45c6e682d4e228c46e3d3d0f432e +Subproject commit b9dcf5ca9f18801d1411525d3672628c08b84871 diff --git a/plugins/Parameters/DistrhoPluginInfo.h b/plugins/Parameters/DistrhoPluginInfo.h new file mode 100644 index 0000000..cbc1d9e --- /dev/null +++ b/plugins/Parameters/DistrhoPluginInfo.h @@ -0,0 +1,35 @@ +/* + * DISTRHO 3BandEQ Plugin, based on 3BandEQ by Michael Gruhn + * Copyright (C) 2012-2014 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * For a full copy of the license see the LICENSE file. + */ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_NAME "Parameters" + +#define DISTRHO_PLUGIN_HAS_UI 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 + +#define DISTRHO_PLUGIN_NUM_INPUTS 2 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 + +#define DISTRHO_PLUGIN_WANT_LATENCY 0 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 +#define DISTRHO_PLUGIN_WANT_STATE 0 +#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 + +#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Parameters" + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/plugins/Parameters/ExamplePluginParameters.cpp b/plugins/Parameters/ExamplePluginParameters.cpp new file mode 100644 index 0000000..5308e8c --- /dev/null +++ b/plugins/Parameters/ExamplePluginParameters.cpp @@ -0,0 +1,224 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "DistrhoPlugin.hpp" + +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------------------------------------------- + +/** + Simple plugin to demonstrate parameter usage (including UI). + The plugin will be treated as an effect, but it will not change the host audio. + */ +class ExamplePluginParameters : public Plugin +{ +public: + ExamplePluginParameters() + : Plugin(9, 0, 0) // 9 parameters, 0 programs, 0 states + { + /** + Initialize all our parameters to their defaults. + In this example all parameters have 0 as default, so we can simply zero them. + */ + std::memset(fParamGrid, 0, sizeof(float)*9); + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers. + */ + const char* d_getLabel() const override + { + return "parameters"; + } + + /** + Get the plugin author/maker. + */ + const char* d_getMaker() const override + { + return "DISTRHO"; + } + + /** + Get the plugin license name (a single line of text). + */ + const char* d_getLicense() const override + { + return "ISC"; + } + + /** + Get the plugin version, in hexadecimal. + TODO format to be defined + */ + uint32_t d_getVersion() const override + { + return 0x1000; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t d_getUniqueId() const override + { + return d_cconst('d', 'P', 'r', 'm'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void d_initParameter(uint32_t index, Parameter& parameter) override + { + /** + All parameters in this plugin are similar except for name. + As such, we initialize the common details first, then set the unique name later. + */ + + /** + Changing parameters does not cause any realtime-unsafe operations, so we can mark them as automable. + Also set as boolean because they work are on/off switches. + */ + parameter.hints = kParameterIsAutomable|kParameterIsBoolean; + + /** + Minimum 0 (off), maximum 1 (on). + Default is off. + */ + parameter.ranges.min = 0.0f; + parameter.ranges.max = 1.0f; + parameter.ranges.def = 0.0f; + + /** + Set the (unique) parameter name. + @see fParamGrid + */ + switch (index) + { + case 0: + parameter.name = "top-left"; + break; + case 1: + parameter.name = "top-center"; + break; + case 2: + parameter.name = "top-right"; + break; + case 3: + parameter.name = "middle-left"; + break; + case 4: + parameter.name = "middle-center"; + break; + case 5: + parameter.name = "middle-right"; + break; + case 6: + parameter.name = "bottom-left"; + break; + case 7: + parameter.name = "bottom-center"; + break; + case 8: + parameter.name = "bottom-right"; + break; + } + + /** + Our parameter names are unique valid symbols, so we can just re-use them. + */ + parameter.symbol = parameter.name; + } + + /* -------------------------------------------------------------------------------------------------------- + * Internal data */ + + /** + Get the current value of a parameter. + */ + float d_getParameterValue(uint32_t index) const override + { + return fParamGrid[index]; + } + + /** + Change a parameter value. + */ + void d_setParameterValue(uint32_t index, float value) override + { + fParamGrid[index] = value; + } + + /* -------------------------------------------------------------------------------------------------------- + * Process */ + + /** + Run/process function for plugins without MIDI input. + */ + void d_run(const float** inputs, float** outputs, uint32_t frames) override + { + /** + This plugin does nothing, it just demonstrates parameter usage. + So here we directly copy inputs over outputs, leaving the audio untouched. + We need to be careful in case the host re-uses the same buffer for both ins and outs. + */ + if (outputs[0] != inputs[0]) + std::memcpy(outputs[0], inputs[0], sizeof(float)*frames); + + if (outputs[1] != inputs[1]) + std::memcpy(outputs[1], inputs[1], sizeof(float)*frames); + } + + // ------------------------------------------------------------------------------------------------------- + +private: + /** + Our parameters are used to display a 3x3 grid like this: + 0 1 2 + 3 4 5 + 6 7 8 + + The index matches its grid position. + */ + float fParamGrid[9]; + + /** + Set our plugin class as non-copyable and add a leak detector just in case. + */ + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginParameters) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Plugin entry point, called by DPF to create a new plugin instance. */ + +Plugin* createPlugin() +{ + return new ExamplePluginParameters(); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/plugins/Parameters/ExampleUIParameters.cpp b/plugins/Parameters/ExampleUIParameters.cpp new file mode 100644 index 0000000..d6dd7a7 --- /dev/null +++ b/plugins/Parameters/ExampleUIParameters.cpp @@ -0,0 +1,222 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * Permission to use, copy, modify, and/or distribute this software for any purpose with + * or without fee is hereby granted, provided that the above copyright notice and this + * permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "DistrhoUI.hpp" + +START_NAMESPACE_DISTRHO + +/** + For simplicity this UI will be of constant size. + */ +static const int kUIWidth = 512; +static const int kUIHeight = 512; + +/** + We need the rectangle class from DGL. + */ +using DGL::Rectangle; + +// ----------------------------------------------------------------------------------------------------------- + +class ExampleUIParameters : public UI +{ +public: + ExampleUIParameters() + : UI() + { + /** + Initialize all our parameters to their defaults. + In this example all default values are false, so we can simply zero them. + */ + std::memset(fParamGrid, 0, sizeof(bool)*9); + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Set the initial UI size. + This function will be called once, shortly after the UI is created. + */ + void d_initSize(uint& width, uint& height) + { + width = kUIWidth; + height = kUIHeight; + } + + /* -------------------------------------------------------------------------------------------------------- + * DSP/Plugin Callbacks */ + + /** + A parameter has changed on the plugin side. + This is called by the host to inform the UI about parameter changes. + */ + void d_parameterChanged(uint32_t index, float value) override + { + // update our grid state to match the plugin side + fParamGrid[index] = (value > 0.5f); + + // trigger repaint + repaint(); + } + + /* -------------------------------------------------------------------------------------------------------- + * Widget Callbacks */ + + /** + The OpenGL drawing function. + This UI will draw a 3x3 grid, with on/off states according to plugin parameters. + */ + void onDisplay() override + { + Rectangle r; + + r.setWidth(kUIWidth/3 - 6); + r.setHeight(kUIHeight/3 - 6); + + // draw left, center and right columns + for (int i=0; i<3; ++i) + { + r.setX(3 + i*kUIWidth/3); + + // top + r.setY(3); + + if (fParamGrid[0+i]) + glColor3f(0.8f, 0.5f, 0.3f); + else + glColor3f(0.3f, 0.5f, 0.8f); + + r.draw(); + + // middle + r.setY(3 + kUIHeight/3); + + if (fParamGrid[3+i]) + glColor3f(0.8f, 0.5f, 0.3f); + else + glColor3f(0.3f, 0.5f, 0.8f); + + r.draw(); + + // bottom + r.setY(3 + kUIHeight*2/3); + + if (fParamGrid[6+i]) + glColor3f(0.8f, 0.5f, 0.3f); + else + glColor3f(0.3f, 0.5f, 0.8f); + + r.draw(); + } + } + + /** + Mouse press event. + This UI will de/activate blocks when you click them and reports it as a parameter change to the plugin. + */ + bool onMouse(const MouseEvent& ev) override + { + // Test for left-clicked + pressed first. + if (ev.button != 1 || ! ev.press) + return false; + + Rectangle r; + + r.setWidth(kUIWidth/3 - 6); + r.setHeight(kUIHeight/3 - 6); + + // handle left, center and right columns + for (int i=0; i<3; ++i) + { + r.setX(3 + i*kUIWidth/3); + + // top + r.setY(3); + + if (r.contains(ev.pos)) + { + // parameter index that this block applies to + const uint32_t index = 0+i; + + // invert block state + fParamGrid[index] = !fParamGrid[index]; + + // report change to host (and thus plugin) + d_setParameterValue(index, fParamGrid[index] ? 1.0f : 0.0f); + + // trigger repaint + repaint(); + break; + } + + // middle + r.setY(3 + kUIHeight/3); + + if (r.contains(ev.pos)) + { + // same as before + const uint32_t index = 3+i; + fParamGrid[index] = !fParamGrid[index]; + d_setParameterValue(index, fParamGrid[index] ? 1.0f : 0.0f); + repaint(); + break; + } + + // bottom + r.setY(3 + kUIHeight*2/3); + + if (r.contains(ev.pos)) + { + // same as before + const uint32_t index = 6+i; + fParamGrid[index] = !fParamGrid[index]; + d_setParameterValue(index, fParamGrid[index] ? 1.0f : 0.0f); + repaint(); + break; + } + } + + return true; + } + + // ------------------------------------------------------------------------------------------------------- + +private: + /** + Our parameters used to display the grid on/off states. + They match the parameters on the plugin side, but here we define them as booleans. + */ + bool fParamGrid[9]; + + /** + Set our UI class as non-copyable and add a leak detector just in case. + */ + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExampleUIParameters) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * UI entry point, called by DPF to create a new UI instance. */ + +UI* createUI() +{ + return new ExampleUIParameters(); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/plugins/Parameters/Makefile b/plugins/Parameters/Makefile new file mode 100644 index 0000000..19fb2da --- /dev/null +++ b/plugins/Parameters/Makefile @@ -0,0 +1,35 @@ +#!/usr/bin/make -f +# Makefile for DISTRHO Plugins # +# ---------------------------- # +# Created by falkTX +# + +# -------------------------------------------------------------- +# Project name, used for binaries + +NAME = d_parameters + +# -------------------------------------------------------------- +# Files to build + +OBJS_DSP = \ + ExamplePluginParameters.cpp.o + +OBJS_UI = \ + ExampleUIParameters.cpp.o + +# -------------------------------------------------------------- +# Do some magic + +include ../Makefile.mk + +# -------------------------------------------------------------- +# Enable all possible plugin types + +ifeq ($(LINUX),true) +all: jack ladspa dssi lv2_sep vst +else +all: ladspa dssi lv2_sep vst +endif + +# -------------------------------------------------------------- diff --git a/plugins/Parameters/README.md b/plugins/Parameters/README.md new file mode 100644 index 0000000..36f6d03 --- /dev/null +++ b/plugins/Parameters/README.md @@ -0,0 +1,9 @@ +# Parameters example + +This example will show how parameters work in DPF.
+The plugin will not do any audio processing.
+ +In this example the UI will display a 3x3 grid of colors which can be changed or automated by the host.
+There are 2 colors: blue and orange. Blue means off, orange means on.
+When a grid block is clicked its color will change and the host will receive a parameter change.
+When the host changes a plugin parameter the UI will update accordingly.