| @@ -0,0 +1,47 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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. | |||
| */ | |||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "Info" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Info" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_TIMEPOS 1 | |||
| #define DISTRHO_UI_USE_NANOVG 1 | |||
| enum Parameters { | |||
| kParameterBufferSize = 0, | |||
| kParameterTimePlaying, | |||
| kParameterTimeFrame, | |||
| kParameterTimeValidBBT, | |||
| kParameterTimeBar, | |||
| kParameterTimeBeat, | |||
| kParameterTimeTick, | |||
| kParameterTimeBarStartTick, | |||
| kParameterTimeBeatsPerBar, | |||
| kParameterTimeBeatType, | |||
| kParameterTimeTicksPerBeat, | |||
| kParameterTimeBeatsPerMinute, | |||
| kParameterCount | |||
| }; | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -0,0 +1,288 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| Plugin to show how to get some basic information sent to the UI. | |||
| */ | |||
| class InfoExamplePlugin : public Plugin | |||
| { | |||
| public: | |||
| InfoExamplePlugin() | |||
| : Plugin(kParameterCount, 0, 0) | |||
| { | |||
| // clear all parameters | |||
| std::memset(fParameters, 0, sizeof(float)*kParameterCount); | |||
| // we can know buffer-size right at the start | |||
| fParameters[kParameterBufferSize] = getBufferSize(); | |||
| } | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Information */ | |||
| /** | |||
| Get the plugin label. | |||
| This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. | |||
| */ | |||
| const char* getLabel() const override | |||
| { | |||
| return "Info"; | |||
| } | |||
| /** | |||
| Get an extensive comment/description about the plugin. | |||
| */ | |||
| const char* getDescription() const override | |||
| { | |||
| return "Plugin to show how to get some basic information sent to the UI."; | |||
| } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| const char* getMaker() const override | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| /** | |||
| Get the plugin homepage. | |||
| */ | |||
| const char* getHomePage() const override | |||
| { | |||
| return "https://github.com/DISTRHO/plugin-examples"; | |||
| } | |||
| /** | |||
| Get the plugin license name (a single line of text). | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| const char* getLicense() const override | |||
| { | |||
| return "ISC"; | |||
| } | |||
| /** | |||
| Get the plugin version, in hexadecimal. | |||
| */ | |||
| uint32_t getVersion() const override | |||
| { | |||
| return d_version(1, 0, 0); | |||
| } | |||
| /** | |||
| Get the plugin unique Id. | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| */ | |||
| int64_t getUniqueId() const override | |||
| { | |||
| return d_cconst('d', 'N', 'f', 'o'); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Init */ | |||
| /** | |||
| Initialize the parameter @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initParameter(uint32_t index, Parameter& parameter) override | |||
| { | |||
| parameter.hints = kParameterIsAutomable|kParameterIsOutput; | |||
| parameter.ranges.def = 0.0f; | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 16777216.0f; | |||
| switch (index) | |||
| { | |||
| case kParameterBufferSize: | |||
| parameter.name = "BufferSize"; | |||
| parameter.symbol = "buffer_size"; | |||
| break; | |||
| case kParameterTimePlaying: | |||
| parameter.hints |= kParameterIsBoolean; | |||
| parameter.name = "TimePlaying"; | |||
| parameter.symbol = "time_playing"; | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 1.0f; | |||
| break; | |||
| case kParameterTimeFrame: | |||
| parameter.name = "TimeFrame"; | |||
| parameter.symbol = "time_frame"; | |||
| break; | |||
| case kParameterTimeValidBBT: | |||
| parameter.hints |= kParameterIsBoolean; | |||
| parameter.name = "TimeValidBBT"; | |||
| parameter.symbol = "time_validbbt"; | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 1.0f; | |||
| break; | |||
| case kParameterTimeBar: | |||
| parameter.name = "TimeBar"; | |||
| parameter.symbol = "time_bar"; | |||
| break; | |||
| case kParameterTimeBeat: | |||
| parameter.name = "TimeBeat"; | |||
| parameter.symbol = "time_beat"; | |||
| break; | |||
| case kParameterTimeTick: | |||
| parameter.name = "TimeTick"; | |||
| parameter.symbol = "time_tick"; | |||
| break; | |||
| case kParameterTimeBarStartTick: | |||
| parameter.name = "TimeBarStartTick"; | |||
| parameter.symbol = "time_barstarttick"; | |||
| break; | |||
| case kParameterTimeBeatsPerBar: | |||
| parameter.name = "TimeBeatsPerBar"; | |||
| parameter.symbol = "time_beatsperbar"; | |||
| break; | |||
| case kParameterTimeBeatType: | |||
| parameter.name = "TimeBeatType"; | |||
| parameter.symbol = "time_beattype"; | |||
| break; | |||
| case kParameterTimeTicksPerBeat: | |||
| parameter.name = "TimeTicksPerBeat"; | |||
| parameter.symbol = "time_ticksperbeat"; | |||
| break; | |||
| case kParameterTimeBeatsPerMinute: | |||
| parameter.name = "TimeBeatsPerMinute"; | |||
| parameter.symbol = "time_beatsperminute"; | |||
| break; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| /** | |||
| Get the current value of a parameter. | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| float getParameterValue(uint32_t index) const override | |||
| { | |||
| return fParameters[index]; | |||
| } | |||
| /** | |||
| Change a parameter value. | |||
| The host may call this function from any context, including realtime processing. | |||
| When a parameter is marked as automable, you must ensure no non-realtime operations are performed. | |||
| @note This function will only be called for parameter inputs. | |||
| */ | |||
| void setParameterValue(uint32_t, float) override | |||
| { | |||
| // this is only called for input paramters, which we have none of. | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Audio/MIDI Processing */ | |||
| /** | |||
| Run/process function for plugins without MIDI input. | |||
| @note Some parameters might be null if there are no audio inputs or outputs. | |||
| */ | |||
| void run(const float** inputs, float** outputs, uint32_t frames) override | |||
| { | |||
| /** | |||
| This plugin does nothing, it just demonstrates information 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); | |||
| // get time position | |||
| const TimePosition& timePos(getTimePosition()); | |||
| // set basic values | |||
| fParameters[kParameterTimePlaying] = timePos.playing ? 1.0f : 0.0f; | |||
| fParameters[kParameterTimeFrame] = timePos.frame; | |||
| fParameters[kParameterTimeValidBBT] = timePos.bbt.valid ? 1.0f : 0.0f; | |||
| // set bbt | |||
| if (timePos.bbt.valid) | |||
| { | |||
| fParameters[kParameterTimeBar] = timePos.bbt.bar; | |||
| fParameters[kParameterTimeBeat] = timePos.bbt.beat; | |||
| fParameters[kParameterTimeTick] = timePos.bbt.tick; | |||
| fParameters[kParameterTimeBarStartTick] = timePos.bbt.barStartTick; | |||
| fParameters[kParameterTimeBeatsPerBar] = timePos.bbt.beatsPerBar; | |||
| fParameters[kParameterTimeBeatType] = timePos.bbt.beatType; | |||
| fParameters[kParameterTimeTicksPerBeat] = timePos.bbt.ticksPerBeat; | |||
| fParameters[kParameterTimeBeatsPerMinute] = timePos.bbt.beatsPerMinute; | |||
| } | |||
| else | |||
| { | |||
| fParameters[kParameterTimeBar] = 0.0f; | |||
| fParameters[kParameterTimeBeat] = 0.0f; | |||
| fParameters[kParameterTimeTick] = 0.0f; | |||
| fParameters[kParameterTimeBarStartTick] = 0.0f; | |||
| fParameters[kParameterTimeBeatsPerBar] = 0.0f; | |||
| fParameters[kParameterTimeBeatType] = 0.0f; | |||
| fParameters[kParameterTimeTicksPerBeat] = 0.0f; | |||
| fParameters[kParameterTimeBeatsPerMinute] = 0.0f; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Callbacks (optional) */ | |||
| /** | |||
| Optional callback to inform the plugin about a buffer size change.@ | |||
| This function will only be called when the plugin is deactivated. | |||
| @note This value is only a hint! | |||
| Hosts might call run() with a higher or lower number of frames. | |||
| */ | |||
| void bufferSizeChanged(uint32_t newBufferSize) override | |||
| { | |||
| fParameters[kParameterBufferSize] = newBufferSize; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| // Parameters | |||
| float fParameters[kParameterCount]; | |||
| /** | |||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(InfoExamplePlugin) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Plugin entry point, called by DPF to create a new plugin instance. */ | |||
| Plugin* createPlugin() | |||
| { | |||
| return new InfoExamplePlugin(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,222 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 "DistrhoPluginInfo.h" | |||
| #include "DistrhoUI.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| class InfoExampleUI : public UI | |||
| { | |||
| public: | |||
| InfoExampleUI() | |||
| : UI(405, 256) | |||
| { | |||
| std::memset(fParameters, 0, sizeof(float)*kParameterCount); | |||
| std::memset(fStrBuf, 0, sizeof(char)*(0xff+1)); | |||
| fSampleRate = getSampleRate(); | |||
| fFont = createFontFromFile("sans", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"); | |||
| } | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * 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 parameterChanged(uint32_t index, float value) override | |||
| { | |||
| fParameters[index] = value; | |||
| repaint(); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * DSP/Plugin Callbacks (optional) */ | |||
| /** | |||
| Optional callback to inform the UI about a sample rate change on the plugin side. | |||
| */ | |||
| void sampleRateChanged(double newSampleRate) override | |||
| { | |||
| fSampleRate = newSampleRate; | |||
| repaint(); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Widget Callbacks */ | |||
| /** | |||
| The NanoVG drawing function. | |||
| */ | |||
| void onNanoDisplay() override | |||
| { | |||
| static const float lineHeight = 20; | |||
| fontSize(15.0f); | |||
| textLineHeight(lineHeight); | |||
| float x = 0; | |||
| float y = 15; | |||
| // buffer size | |||
| drawLeft(x, y, "Buffer Size:"); | |||
| drawRight(x, y, getTextBufInt(fParameters[kParameterBufferSize])); | |||
| y+=lineHeight; | |||
| // sample rate | |||
| drawLeft(x, y, "Sample Rate:"); | |||
| drawRight(x, y, getTextBufFloat(fSampleRate)); | |||
| y+=lineHeight; | |||
| // nothing | |||
| y+=lineHeight; | |||
| // time stuff | |||
| drawLeft(x, y, "Playing:"); | |||
| drawRight(x, y, (fParameters[kParameterTimePlaying] > 0.5f) ? "Yes" : "No"); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Frame:"); | |||
| drawRight(x, y, getTextBufInt(fParameters[kParameterTimeFrame])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Time:"); | |||
| drawRight(x, y, getTextBufTime(fParameters[kParameterTimeFrame])); | |||
| y+=lineHeight; | |||
| // BBT | |||
| x = 200; | |||
| y = 15; | |||
| const bool validBBT(fParameters[kParameterTimeValidBBT] > 0.5f); | |||
| drawLeft(x, y, "BBT Valid:"); | |||
| drawRight(x, y, validBBT ? "Yes" : "No"); | |||
| y+=lineHeight; | |||
| if (! validBBT) | |||
| return; | |||
| drawLeft(x, y, "Bar:"); | |||
| drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBar])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Beat:"); | |||
| drawRight(x, y, getTextBufInt(fParameters[kParameterTimeBeat])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Tick:"); | |||
| drawRight(x, y, getTextBufInt(fParameters[kParameterTimeTick])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Bar Start Tick:"); | |||
| drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBarStartTick])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Beats Per Bar:"); | |||
| drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerBar])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Beat Type:"); | |||
| drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatType])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "Ticks Per Beat:"); | |||
| drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeTicksPerBeat])); | |||
| y+=lineHeight; | |||
| drawLeft(x, y, "BPM:"); | |||
| drawRight(x, y, getTextBufFloat(fParameters[kParameterTimeBeatsPerMinute])); | |||
| y+=lineHeight; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| // Parameters | |||
| float fParameters[kParameterCount]; | |||
| double fSampleRate; | |||
| // font | |||
| FontId fFont; | |||
| // temp buf for text | |||
| char fStrBuf[0xff+1]; | |||
| // helpers for putting text into fStrBuf and returning it | |||
| const char* getTextBufInt(const int value) | |||
| { | |||
| std::snprintf(fStrBuf, 0xff, "%i", value); | |||
| return fStrBuf; | |||
| } | |||
| const char* getTextBufFloat(const float value) | |||
| { | |||
| std::snprintf(fStrBuf, 0xff, "%.1f", value); | |||
| return fStrBuf; | |||
| } | |||
| const char* getTextBufTime(const uint64_t frame) | |||
| { | |||
| const uint32_t time = frame / uint64_t(fSampleRate); | |||
| const uint32_t secs = time % 60; | |||
| const uint32_t mins = (time / 60) % 60; | |||
| const uint32_t hrs = (time / 3600) % 60; | |||
| std::snprintf(fStrBuf, 0xff, "%02i:%02i:%02i", hrs, mins, secs); | |||
| return fStrBuf; | |||
| } | |||
| // helpers for drawing text | |||
| void drawLeft(const float x, const float y, const char* const text) | |||
| { | |||
| beginPath(); | |||
| fillColor(200, 200, 200); | |||
| textAlign(ALIGN_RIGHT|ALIGN_TOP); | |||
| textBox(x, y, 100, text); | |||
| closePath(); | |||
| } | |||
| void drawRight(const float x, const float y, const char* const text) | |||
| { | |||
| beginPath(); | |||
| fillColor(255, 255, 255); | |||
| textAlign(ALIGN_LEFT|ALIGN_TOP); | |||
| textBox(x+105, y, 100, text); | |||
| closePath(); | |||
| } | |||
| /** | |||
| Set our UI class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(InfoExampleUI) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * UI entry point, called by DPF to create a new UI instance. */ | |||
| UI* createUI() | |||
| { | |||
| return new InfoExampleUI(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,45 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DISTRHO Plugins # | |||
| # ---------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # -------------------------------------------------------------- | |||
| # Project name, used for binaries | |||
| NAME = d_info | |||
| # -------------------------------------------------------------- | |||
| # Files to build | |||
| FILES_DSP = \ | |||
| InfoExamplePlugin.cpp | |||
| FILES_UI = \ | |||
| InfoExampleUI.cpp | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| endif | |||
| ifeq ($(HAVE_DGL),true) | |||
| TARGETS += lv2_sep | |||
| else | |||
| TARGETS += lv2_dsp | |||
| endif | |||
| TARGETS += vst | |||
| all: $(TARGETS) | |||
| # -------------------------------------------------------------- | |||
| @@ -0,0 +1,10 @@ | |||
| # Information example | |||
| This example will show how to get some basic information sent to the UI.<br/> | |||
| The Plugin has a lot of parameter outputs which the UI uses to get info from.<br/> | |||
| This includes buffer-size and time position.<br/> | |||
| Sample-rate can be requested directly from the UI.<br/> | |||
| The UI will show this information as text.<br/> | |||
| The plugin will not do any audio processing.<br/> | |||
| @@ -0,0 +1,30 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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. | |||
| */ | |||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "Latency" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Latency" | |||
| #define DISTRHO_PLUGIN_HAS_UI 0 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 1 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 1 | |||
| #define DISTRHO_PLUGIN_WANT_LATENCY 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -0,0 +1,251 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| Plugin that demonstrates the latency API in DPF. | |||
| */ | |||
| class LatencyExamplePlugin : public Plugin | |||
| { | |||
| public: | |||
| LatencyExamplePlugin() | |||
| : Plugin(1, 0, 0), // 1 parameter | |||
| fLatency(1.0f), | |||
| fLatencyInFrames(0), | |||
| fBuffer(nullptr), | |||
| fBufferPos(0) | |||
| { | |||
| // allocates buffer | |||
| sampleRateChanged(getSampleRate()); | |||
| } | |||
| ~LatencyExamplePlugin() override | |||
| { | |||
| delete[] fBuffer; | |||
| } | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Information */ | |||
| /** | |||
| Get the plugin label. | |||
| This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. | |||
| */ | |||
| const char* getLabel() const override | |||
| { | |||
| return "Latency"; | |||
| } | |||
| /** | |||
| Get an extensive comment/description about the plugin. | |||
| */ | |||
| const char* getDescription() const override | |||
| { | |||
| return "Plugin that demonstrates the latency API in DPF."; | |||
| } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| const char* getMaker() const override | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| /** | |||
| Get the plugin homepage. | |||
| */ | |||
| const char* getHomePage() const override | |||
| { | |||
| return "https://github.com/DISTRHO/plugin-examples"; | |||
| } | |||
| /** | |||
| Get the plugin license name (a single line of text). | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| const char* getLicense() const override | |||
| { | |||
| return "ISC"; | |||
| } | |||
| /** | |||
| Get the plugin version, in hexadecimal. | |||
| */ | |||
| uint32_t getVersion() const override | |||
| { | |||
| return d_version(1, 0, 0); | |||
| } | |||
| /** | |||
| Get the plugin unique Id. | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| */ | |||
| int64_t getUniqueId() const override | |||
| { | |||
| return d_cconst('d', 'L', 'a', 't'); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Init */ | |||
| /** | |||
| Initialize the parameter @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initParameter(uint32_t index, Parameter& parameter) override | |||
| { | |||
| if (index != 0) | |||
| return; | |||
| parameter.hints = kParameterIsAutomable; | |||
| parameter.name = "Latency"; | |||
| parameter.symbol = "latency"; | |||
| parameter.unit = "s"; | |||
| parameter.ranges.def = 1.0f; | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 5.0f; | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| /** | |||
| Get the current value of a parameter. | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| float getParameterValue(uint32_t index) const override | |||
| { | |||
| if (index != 0) | |||
| return 0.0f; | |||
| return fLatency; | |||
| } | |||
| /** | |||
| Change a parameter value. | |||
| The host may call this function from any context, including realtime processing. | |||
| When a parameter is marked as automable, you must ensure no non-realtime operations are performed. | |||
| @note This function will only be called for parameter inputs. | |||
| */ | |||
| void setParameterValue(uint32_t index, float value) override | |||
| { | |||
| if (index != 0) | |||
| return; | |||
| fLatency = value; | |||
| fLatencyInFrames = value*getSampleRate(); | |||
| setLatency(fLatencyInFrames); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Audio/MIDI Processing */ | |||
| /** | |||
| Run/process function for plugins without MIDI input. | |||
| @note Some parameters might be null if there are no audio inputs or outputs. | |||
| */ | |||
| void run(const float** inputs, float** outputs, uint32_t frames) override | |||
| { | |||
| const float* const in = inputs[0]; | |||
| /* */ float* const out = outputs[0]; | |||
| if (fLatencyInFrames == 0) | |||
| { | |||
| if (out != in) | |||
| std::memcpy(out, in, sizeof(float)*frames); | |||
| return; | |||
| } | |||
| // Put the new audio in the buffer. | |||
| std::memcpy(fBuffer+fBufferPos, in, sizeof(float)*frames); | |||
| fBufferPos += frames; | |||
| // buffer is not filled enough yet | |||
| if (fBufferPos < fLatencyInFrames+frames) | |||
| { | |||
| // silence output | |||
| std::memset(out, 0, sizeof(float)*frames); | |||
| } | |||
| // buffer is ready to copy | |||
| else | |||
| { | |||
| // copy latency buffer to output | |||
| const uint32_t readPos = fBufferPos-fLatencyInFrames-frames; | |||
| std::memcpy(out, fBuffer+readPos, sizeof(float)*frames); | |||
| // move latency buffer back by some frames | |||
| std::memmove(fBuffer, fBuffer+frames, sizeof(float)*fBufferPos); | |||
| fBufferPos -= frames; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Callbacks (optional) */ | |||
| /** | |||
| Optional callback to inform the plugin about a sample rate change. | |||
| This function will only be called when the plugin is deactivated. | |||
| */ | |||
| void sampleRateChanged(double newSampleRate) override | |||
| { | |||
| if (fBuffer != nullptr) | |||
| delete[] fBuffer; | |||
| const uint32_t maxFrames = newSampleRate*6; // 6 seconds | |||
| fBuffer = new float[maxFrames]; | |||
| std::memset(fBuffer, 0, sizeof(float)*maxFrames); | |||
| fLatencyInFrames = fLatency*newSampleRate; | |||
| fBufferPos = 0; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| // Parameters | |||
| float fLatency; | |||
| uint32_t fLatencyInFrames; | |||
| // Buffer for previous audio, size depends on sample rate | |||
| float* fBuffer; | |||
| uint32_t fBufferPos; | |||
| /** | |||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LatencyExamplePlugin) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Plugin entry point, called by DPF to create a new plugin instance. */ | |||
| Plugin* createPlugin() | |||
| { | |||
| return new LatencyExamplePlugin(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,36 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DISTRHO Plugins # | |||
| # ---------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # -------------------------------------------------------------- | |||
| # Project name, used for binaries | |||
| NAME = d_latency | |||
| # -------------------------------------------------------------- | |||
| # Files to build | |||
| FILES_DSP = \ | |||
| LatencyExamplePlugin.cpp | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(LINUX),true) | |||
| TARGETS += ladspa | |||
| TARGETS += dssi | |||
| endif | |||
| TARGETS += lv2_dsp | |||
| TARGETS += vst | |||
| all: $(TARGETS) | |||
| # -------------------------------------------------------------- | |||
| @@ -0,0 +1,8 @@ | |||
| # Latency example | |||
| This example will show how to use latency in DPF based plugins.<br/> | |||
| The plugin will delay its audio signal by a variable amount of time, specified by a parameter.<br/> | |||
| Good hosts will receive this hint and compensate accordingly.<br/> | |||
| The plugin has no UI because there's no need for one in this case.<br/> | |||
| @@ -0,0 +1,172 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DPF Example Plugins # | |||
| # -------------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # NAME, FILES_DSP and FILES_UI have been defined before | |||
| include ../../Makefile.mk | |||
| ifeq ($(OBJS_UI),) | |||
| HAVE_DGL = false | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Basic setup | |||
| TARGET_DIR = ../../bin | |||
| BUILD_DIR = ../../build/$(NAME) | |||
| BUILD_C_FLAGS += -I. | |||
| BUILD_CXX_FLAGS += -I. -I../../distrho -I../../dgl | |||
| ifeq ($(HAVE_DGL),true) | |||
| BASE_FLAGS += -DHAVE_DGL | |||
| endif | |||
| ifeq ($(HAVE_JACK),true) | |||
| BASE_FLAGS += -DHAVE_JACK | |||
| endif | |||
| ifeq ($(HAVE_LIBLO),true) | |||
| BASE_FLAGS += -DHAVE_LIBLO | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Set files to build | |||
| OBJS_DSP = $(FILES_DSP:%=$(BUILD_DIR)/%.o) | |||
| OBJS_UI = $(FILES_UI:%=$(BUILD_DIR)/%.o) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Set plugin binary file targets | |||
| jack = $(TARGET_DIR)/$(NAME)$(APP_EXT) | |||
| ladspa_dsp = $(TARGET_DIR)/$(NAME)-ladspa$(LIB_EXT) | |||
| dssi_dsp = $(TARGET_DIR)/$(NAME)-dssi$(LIB_EXT) | |||
| dssi_ui = $(TARGET_DIR)/$(NAME)-dssi/$(NAME)_ui$(APP_EXT) | |||
| lv2 = $(TARGET_DIR)/$(NAME).lv2/$(NAME)$(LIB_EXT) | |||
| lv2_dsp = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_dsp$(LIB_EXT) | |||
| lv2_ui = $(TARGET_DIR)/$(NAME).lv2/$(NAME)_ui$(LIB_EXT) | |||
| vst = $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT) | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Set distrho code files | |||
| DISTRHO_PLUGIN_FILES = ../../distrho/DistrhoPluginMain.cpp | |||
| ifeq ($(HAVE_DGL),true) | |||
| DISTRHO_UI_FILES = ../../distrho/DistrhoUIMain.cpp ../../build/libdgl.a | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Handle plugins without UI | |||
| ifneq ($(HAVE_DGL),true) | |||
| dssi_ui = | |||
| lv2_ui = | |||
| DISTRHO_UI_FILES = | |||
| DGL_LIBS = | |||
| OBJS_UI = | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # all needs to be first | |||
| all: | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # Common | |||
| $(BUILD_DIR)/%.c.o: %.c | |||
| -@mkdir -p $(BUILD_DIR) | |||
| @echo "Compiling $<" | |||
| @$(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||
| $(BUILD_DIR)/%.cpp.o: %.cpp | |||
| -@mkdir -p $(BUILD_DIR) | |||
| @echo "Compiling $<" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
| clean: | |||
| rm -rf $(BUILD_DIR) | |||
| rm -rf $(TARGET_DIR)/$(NAME) $(TARGET_DIR)/$(NAME)-* $(TARGET_DIR)/$(NAME).lv2 | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # JACK | |||
| jack: $(jack) | |||
| $(jack): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating JACK standalone for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs jack) -DDISTRHO_PLUGIN_TARGET_JACK -o $@ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # LADSPA | |||
| ladspa: $(ladspa_dsp) | |||
| $(ladspa_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating LADSPA plugin for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LADSPA -o $@ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # DSSI | |||
| dssi: $(dssi_dsp) $(dssi_ui) | |||
| dssi_dsp: $(dssi_dsp) | |||
| dssi_ui: $(dssi_ui) | |||
| $(dssi_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating DSSI plugin library for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@ | |||
| $(dssi_ui): $(OBJS_UI) $(DISTRHO_UI_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating DSSI UI for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(shell pkg-config --cflags --libs liblo) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # LV2 | |||
| lv2_one: $(lv2) | |||
| lv2_dsp: $(lv2_dsp) | |||
| lv2_sep: $(lv2_dsp) $(lv2_ui) | |||
| $(lv2): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating LV2 plugin for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ | |||
| $(lv2_dsp): $(OBJS_DSP) $(DISTRHO_PLUGIN_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating LV2 plugin library for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ | |||
| $(lv2_ui): $(OBJS_UI) $(DISTRHO_UI_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating LV2 plugin UI for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| # VST | |||
| vst: $(vst) | |||
| $(vst): $(OBJS_DSP) $(OBJS_UI) $(DISTRHO_PLUGIN_FILES) $(DISTRHO_UI_FILES) | |||
| -@mkdir -p $(shell dirname $@) | |||
| @echo "Creating VST plugin for $(NAME)" | |||
| @$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_VST -o $@ | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| -include $(OBJS_DSP:%.o=%.d) | |||
| ifeq ($(HAVE_DGL),true) | |||
| -include $(OBJS_UI:%.o=%.d) | |||
| endif | |||
| # --------------------------------------------------------------------------------------------------------------------- | |||
| @@ -0,0 +1,34 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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. | |||
| */ | |||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "Meters" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Meters" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_STATE 1 | |||
| #define DISTRHO_UI_USE_NANOVG 1 | |||
| #define METER_COLOR_GREEN 0 | |||
| #define METER_COLOR_BLUE 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -0,0 +1,284 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| Plugin to demonstrate parameter outputs using meters. | |||
| */ | |||
| class ExamplePluginMeters : public Plugin | |||
| { | |||
| public: | |||
| ExamplePluginMeters() | |||
| : Plugin(3, 0, 0), // 3 parameters, 0 programs, 0 states | |||
| fColor(0.0f), | |||
| fOutLeft(0.0f), | |||
| fOutRight(0.0f), | |||
| fNeedsReset(true) | |||
| { | |||
| } | |||
| 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* getLabel() const override | |||
| { | |||
| return "meters"; | |||
| } | |||
| /** | |||
| Get an extensive comment/description about the plugin. | |||
| */ | |||
| const char* getDescription() const override | |||
| { | |||
| return "Plugin to demonstrate parameter outputs using meters."; | |||
| } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| const char* getMaker() const override | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| /** | |||
| Get the plugin homepage. | |||
| */ | |||
| const char* getHomePage() const override | |||
| { | |||
| return "https://github.com/DISTRHO/plugin-examples"; | |||
| } | |||
| /** | |||
| Get the plugin license name (a single line of text). | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| const char* getLicense() const override | |||
| { | |||
| return "ISC"; | |||
| } | |||
| /** | |||
| Get the plugin version, in hexadecimal. | |||
| */ | |||
| uint32_t getVersion() const override | |||
| { | |||
| return d_version(1, 0, 0); | |||
| } | |||
| /** | |||
| Get the plugin unique Id. | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| */ | |||
| int64_t getUniqueId() const override | |||
| { | |||
| return d_cconst('d', 'M', 't', 'r'); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Init */ | |||
| /** | |||
| Initialize the parameter @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initParameter(uint32_t index, Parameter& parameter) override | |||
| { | |||
| /** | |||
| All parameters in this plugin have the same ranges. | |||
| */ | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 1.0f; | |||
| parameter.ranges.def = 0.0f; | |||
| /** | |||
| Set parameter data. | |||
| */ | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| parameter.hints = kParameterIsAutomable|kParameterIsInteger; | |||
| parameter.name = "color"; | |||
| parameter.symbol = "color"; | |||
| parameter.enumValues.count = 2; | |||
| parameter.enumValues.restrictedMode = true; | |||
| { | |||
| ParameterEnumerationValue* const values = new ParameterEnumerationValue[2]; | |||
| parameter.enumValues.values = values; | |||
| values[0].label = "Green"; | |||
| values[0].value = METER_COLOR_GREEN; | |||
| values[1].label = "Blue"; | |||
| values[1].value = METER_COLOR_BLUE; | |||
| } | |||
| break; | |||
| case 1: | |||
| parameter.hints = kParameterIsAutomable|kParameterIsOutput; | |||
| parameter.name = "out-left"; | |||
| parameter.symbol = "out_left"; | |||
| break; | |||
| case 2: | |||
| parameter.hints = kParameterIsAutomable|kParameterIsOutput; | |||
| parameter.name = "out-right"; | |||
| parameter.symbol = "out_right"; | |||
| break; | |||
| } | |||
| } | |||
| /** | |||
| Set a state key and default value. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initState(uint32_t, String&, String&) override | |||
| { | |||
| // we are using states but don't want them saved in the host | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| /** | |||
| Get the current value of a parameter. | |||
| */ | |||
| float getParameterValue(uint32_t index) const override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: return fColor; | |||
| case 1: return fOutLeft; | |||
| case 2: return fOutRight; | |||
| } | |||
| return 0.0f; | |||
| } | |||
| /** | |||
| Change a parameter value. | |||
| */ | |||
| void setParameterValue(uint32_t index, float value) override | |||
| { | |||
| // this is only called for input paramters, and we only have one of those. | |||
| if (index != 0) return; | |||
| fColor = value; | |||
| } | |||
| /** | |||
| Change an internal state. | |||
| */ | |||
| void setState(const char* key, const char*) override | |||
| { | |||
| if (std::strcmp(key, "reset") != 0) | |||
| return; | |||
| fNeedsReset = true; | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Process */ | |||
| /** | |||
| Run/process function for plugins without MIDI input. | |||
| */ | |||
| void run(const float** inputs, float** outputs, uint32_t frames) override | |||
| { | |||
| float tmp; | |||
| float tmpLeft = 0.0f; | |||
| float tmpRight = 0.0f; | |||
| for (uint32_t i=0; i<frames; ++i) | |||
| { | |||
| // left | |||
| tmp = std::abs(inputs[0][i]); | |||
| if (tmp > tmpLeft) | |||
| tmpLeft = tmp; | |||
| // right | |||
| tmp = std::abs(inputs[1][i]); | |||
| if (tmp > tmpRight) | |||
| tmpRight = tmp; | |||
| } | |||
| if (tmpLeft > 1.0f) | |||
| tmpLeft = 1.0f; | |||
| if (tmpRight > 1.0f) | |||
| tmpRight = 1.0f; | |||
| if (fNeedsReset) | |||
| { | |||
| fOutLeft = tmpLeft; | |||
| fOutRight = tmpRight; | |||
| fNeedsReset = false; | |||
| } | |||
| else | |||
| { | |||
| if (tmpLeft > fOutLeft) | |||
| fOutLeft = tmpLeft; | |||
| if (tmpRight > fOutRight) | |||
| fOutRight = tmpRight; | |||
| } | |||
| // copy inputs over outputs if needed | |||
| 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: | |||
| /** | |||
| Parameters. | |||
| */ | |||
| float fColor, fOutLeft, fOutRight; | |||
| /** | |||
| Boolean used to reset meter values. | |||
| The UI will send a "reset" message which sets this as true. | |||
| */ | |||
| volatile bool fNeedsReset; | |||
| /** | |||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginMeters) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Plugin entry point, called by DPF to create a new plugin instance. */ | |||
| Plugin* createPlugin() | |||
| { | |||
| return new ExamplePluginMeters(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,254 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| /** | |||
| We need the Color class from DGL. | |||
| */ | |||
| using DGL::Color; | |||
| /** | |||
| Smooth meters a bit. | |||
| */ | |||
| static const float kSmoothMultiplier = 3.0f; | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| class ExampleUIMeters : public UI | |||
| { | |||
| public: | |||
| ExampleUIMeters() | |||
| : UI(128, 512), | |||
| // default color is green | |||
| fColor(93, 231, 61), | |||
| // which is value 0 | |||
| fColorValue(0), | |||
| // init meter values to 0 | |||
| fOutLeft(0.0f), | |||
| fOutRight(0.0f) | |||
| { | |||
| } | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * 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 parameterChanged(uint32_t index, float value) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: // color | |||
| updateColor(std::round(value)); | |||
| break; | |||
| case 1: // out-left | |||
| value = (fOutLeft * kSmoothMultiplier + value) / (kSmoothMultiplier + 1.0f); | |||
| /**/ if (value < 0.001f) value = 0.0f; | |||
| else if (value > 0.999f) value = 1.0f; | |||
| if (fOutLeft != value) | |||
| { | |||
| fOutLeft = value; | |||
| repaint(); | |||
| } | |||
| break; | |||
| case 2: // out-right | |||
| value = (fOutRight * kSmoothMultiplier + value) / (kSmoothMultiplier + 1.0f); | |||
| /**/ if (value < 0.001f) value = 0.0f; | |||
| else if (value > 0.999f) value = 1.0f; | |||
| if (fOutRight != value) | |||
| { | |||
| fOutRight = value; | |||
| repaint(); | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| /** | |||
| A state has changed on the plugin side. | |||
| This is called by the host to inform the UI about state changes. | |||
| */ | |||
| void stateChanged(const char*, const char*) | |||
| { | |||
| // nothing here | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Widget Callbacks */ | |||
| /** | |||
| The NanoVG drawing function. | |||
| */ | |||
| void onNanoDisplay() override | |||
| { | |||
| static const Color kColorBlack(0, 0, 0); | |||
| static const Color kColorRed(255, 0, 0); | |||
| static const Color kColorYellow(255, 255, 0); | |||
| // get meter values | |||
| const float outLeft(fOutLeft); | |||
| const float outRight(fOutRight); | |||
| // tell DSP side to reset meter values | |||
| setState("reset", ""); | |||
| // useful vars | |||
| const float halfWidth = static_cast<float>(getWidth())/2; | |||
| const float redYellowHeight = static_cast<float>(getHeight())*0.2f; | |||
| const float yellowBaseHeight = static_cast<float>(getHeight())*0.4f; | |||
| const float baseBaseHeight = static_cast<float>(getHeight())*0.6f; | |||
| // create gradients | |||
| Paint fGradient1 = linearGradient(0.0f, 0.0f, 0.0f, redYellowHeight, kColorRed, kColorYellow); | |||
| Paint fGradient2 = linearGradient(0.0f, redYellowHeight, 0.0f, yellowBaseHeight, kColorYellow, fColor); | |||
| // paint left meter | |||
| beginPath(); | |||
| rect(0.0f, 0.0f, halfWidth-1.0f, redYellowHeight); | |||
| fillPaint(fGradient1); | |||
| fill(); | |||
| closePath(); | |||
| beginPath(); | |||
| rect(0.0f, redYellowHeight-0.5f, halfWidth-1.0f, yellowBaseHeight); | |||
| fillPaint(fGradient2); | |||
| fill(); | |||
| closePath(); | |||
| beginPath(); | |||
| rect(0.0f, redYellowHeight+yellowBaseHeight-1.5f, halfWidth-1.0f, baseBaseHeight); | |||
| fillColor(fColor); | |||
| fill(); | |||
| closePath(); | |||
| // paint left black matching output level | |||
| beginPath(); | |||
| rect(0.0f, 0.0f, halfWidth-1.0f, (1.0f-outLeft)*getHeight()); | |||
| fillColor(kColorBlack); | |||
| fill(); | |||
| closePath(); | |||
| // paint right meter | |||
| beginPath(); | |||
| rect(halfWidth+1.0f, 0.0f, halfWidth-2.0f, redYellowHeight); | |||
| fillPaint(fGradient1); | |||
| fill(); | |||
| closePath(); | |||
| beginPath(); | |||
| rect(halfWidth+1.0f, redYellowHeight-0.5f, halfWidth-2.0f, yellowBaseHeight); | |||
| fillPaint(fGradient2); | |||
| fill(); | |||
| closePath(); | |||
| beginPath(); | |||
| rect(halfWidth+1.0f, redYellowHeight+yellowBaseHeight-1.5f, halfWidth-2.0f, baseBaseHeight); | |||
| fillColor(fColor); | |||
| fill(); | |||
| closePath(); | |||
| // paint right black matching output level | |||
| beginPath(); | |||
| rect(halfWidth+1.0f, 0.0f, halfWidth-2.0f, (1.0f-outRight)*getHeight()); | |||
| fillColor(kColorBlack); | |||
| fill(); | |||
| closePath(); | |||
| } | |||
| /** | |||
| Mouse press event. | |||
| This UI will change color when clicked. | |||
| */ | |||
| bool onMouse(const MouseEvent& ev) override | |||
| { | |||
| // Test for left-clicked + pressed first. | |||
| if (ev.button != 1 || ! ev.press) | |||
| return false; | |||
| const int newColor(fColorValue == 0 ? 1 : 0); | |||
| updateColor(newColor); | |||
| setParameterValue(0, newColor); | |||
| return true; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| /** | |||
| Color and its matching parameter value. | |||
| */ | |||
| Color fColor; | |||
| int fColorValue; | |||
| /** | |||
| Meter values. | |||
| These are the parameter outputs from the DSP side. | |||
| */ | |||
| float fOutLeft, fOutRight; | |||
| /** | |||
| Update color if needed. | |||
| */ | |||
| void updateColor(const int color) | |||
| { | |||
| if (fColorValue == color) | |||
| return; | |||
| fColorValue = color; | |||
| switch (color) | |||
| { | |||
| case METER_COLOR_GREEN: | |||
| fColor = Color(93, 231, 61); | |||
| break; | |||
| case METER_COLOR_BLUE: | |||
| fColor = Color(82, 238, 248); | |||
| break; | |||
| } | |||
| repaint(); | |||
| } | |||
| /** | |||
| Set our UI class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExampleUIMeters) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * UI entry point, called by DPF to create a new UI instance. */ | |||
| UI* createUI() | |||
| { | |||
| return new ExampleUIMeters(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,53 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DISTRHO Plugins # | |||
| # ---------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # -------------------------------------------------------------- | |||
| # Project name, used for binaries | |||
| NAME = d_meters | |||
| # -------------------------------------------------------------- | |||
| # Files to build | |||
| FILES_DSP = \ | |||
| ExamplePluginMeters.cpp | |||
| FILES_UI = \ | |||
| ExampleUIMeters.cpp | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| endif | |||
| ifeq ($(LINUX),true) | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_LIBLO),true) | |||
| TARGETS += dssi | |||
| endif | |||
| endif | |||
| endif | |||
| ifeq ($(HAVE_DGL),true) | |||
| TARGETS += lv2_sep | |||
| else | |||
| TARGETS += lv2_dsp | |||
| endif | |||
| TARGETS += vst | |||
| all: $(TARGETS) | |||
| # -------------------------------------------------------------- | |||
| @@ -0,0 +1,8 @@ | |||
| # Meters example | |||
| This example will show how parameter outputs can be used for UI meters in DPF.<br/> | |||
| The plugin will inspect the host audio buffer but it won't change it in any way.<br/> | |||
| In this example the UI will display a simple meter based on the plugin's parameter outputs.<br/> | |||
| In order to make drawing easier the UI uses NanoVG instead of raw OpenGL.<br/> | |||
| Please see the Parameters and States examples before studying this one.<br/> | |||
| @@ -0,0 +1,31 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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. | |||
| */ | |||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "MidiThrough" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/MidiThrough" | |||
| #define DISTRHO_PLUGIN_HAS_UI 0 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 0 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 0 | |||
| #define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1 | |||
| #define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -0,0 +1,35 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DISTRHO Plugins # | |||
| # ---------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # -------------------------------------------------------------- | |||
| # Project name, used for binaries | |||
| NAME = d_midiThrough | |||
| # -------------------------------------------------------------- | |||
| # Files to build | |||
| FILES_DSP = \ | |||
| MidiThroughExamplePlugin.cpp | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(LINUX),true) | |||
| TARGETS += jack | |||
| endif | |||
| TARGETS += lv2_dsp | |||
| TARGETS += vst | |||
| all: $(TARGETS) | |||
| # -------------------------------------------------------------- | |||
| @@ -0,0 +1,137 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| /** | |||
| Plugin that demonstrates the latency API in DPF. | |||
| */ | |||
| class MidiThroughExamplePlugin : public Plugin | |||
| { | |||
| public: | |||
| MidiThroughExamplePlugin() | |||
| : Plugin(0, 0, 0) {} | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Information */ | |||
| /** | |||
| Get the plugin label. | |||
| This label is a short restricted name consisting of only _, a-z, A-Z and 0-9 characters. | |||
| */ | |||
| const char* getLabel() const override | |||
| { | |||
| return "MidiThrough"; | |||
| } | |||
| /** | |||
| Get an extensive comment/description about the plugin. | |||
| */ | |||
| const char* getDescription() const override | |||
| { | |||
| return "Plugin that demonstrates the latency API in DPF."; | |||
| } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| const char* getMaker() const override | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| /** | |||
| Get the plugin homepage. | |||
| */ | |||
| const char* getHomePage() const override | |||
| { | |||
| return "https://github.com/DISTRHO/plugin-examples"; | |||
| } | |||
| /** | |||
| Get the plugin license name (a single line of text). | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| const char* getLicense() const override | |||
| { | |||
| return "ISC"; | |||
| } | |||
| /** | |||
| Get the plugin version, in hexadecimal. | |||
| */ | |||
| uint32_t getVersion() const override | |||
| { | |||
| return d_version(1, 0, 0); | |||
| } | |||
| /** | |||
| Get the plugin unique Id. | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| */ | |||
| int64_t getUniqueId() const override | |||
| { | |||
| return d_cconst('d', 'M', 'T', 'r'); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Init and Internal data, unused in this plugin */ | |||
| void initParameter(uint32_t, Parameter&) override {} | |||
| float getParameterValue(uint32_t) const override { return 0.0f;} | |||
| void setParameterValue(uint32_t, float) override {} | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Audio/MIDI Processing */ | |||
| /** | |||
| Run/process function for plugins with MIDI input. | |||
| In this case we just pass-through all MIDI events. | |||
| */ | |||
| void run(const float**, float**, uint32_t, | |||
| const MidiEvent* midiEvents, uint32_t midiEventCount) override | |||
| { | |||
| for (uint32_t i=0; i<midiEventCount; ++i) | |||
| writeMidiEvent(midiEvents[i]); | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| // nothing here :) | |||
| /** | |||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiThroughExamplePlugin) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Plugin entry point, called by DPF to create a new plugin instance. */ | |||
| Plugin* createPlugin() | |||
| { | |||
| return new MidiThroughExamplePlugin(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,6 @@ | |||
| # MidiThrough example | |||
| This example will show how to use MIDI output in DPF based plugins.<br/> | |||
| It simply calls writeMidiEvent() in its process function for every event it receives. | |||
| @@ -0,0 +1,30 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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. | |||
| */ | |||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "Parameters" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Parameters" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -0,0 +1,292 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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, 2, 0) // 9 parameters, 2 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* getLabel() const override | |||
| { | |||
| return "parameters"; | |||
| } | |||
| /** | |||
| Get an extensive comment/description about the plugin. | |||
| */ | |||
| const char* getDescription() const override | |||
| { | |||
| return "Simple plugin to demonstrate parameter usage (including UI).\n\ | |||
| The plugin will be treated as an effect, but it will not change the host audio."; | |||
| } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| const char* getMaker() const override | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| /** | |||
| Get the plugin homepage. | |||
| */ | |||
| const char* getHomePage() const override | |||
| { | |||
| return "https://github.com/DISTRHO/plugin-examples"; | |||
| } | |||
| /** | |||
| Get the plugin license name (a single line of text). | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| const char* getLicense() const override | |||
| { | |||
| return "ISC"; | |||
| } | |||
| /** | |||
| Get the plugin version, in hexadecimal. | |||
| */ | |||
| uint32_t getVersion() const override | |||
| { | |||
| return d_version(1, 0, 0); | |||
| } | |||
| /** | |||
| Get the plugin unique Id. | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| */ | |||
| int64_t 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 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 as 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 valid symbols except for "-". | |||
| */ | |||
| parameter.symbol = parameter.name; | |||
| parameter.symbol.replace('-', '_'); | |||
| } | |||
| /** | |||
| Set the name of the program @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initProgramName(uint32_t index, String& programName) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| programName = "Default"; | |||
| break; | |||
| case 1: | |||
| programName = "Custom"; | |||
| break; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| /** | |||
| Get the current value of a parameter. | |||
| */ | |||
| float getParameterValue(uint32_t index) const override | |||
| { | |||
| return fParamGrid[index]; | |||
| } | |||
| /** | |||
| Change a parameter value. | |||
| */ | |||
| void setParameterValue(uint32_t index, float value) override | |||
| { | |||
| fParamGrid[index] = value; | |||
| } | |||
| /** | |||
| Load a program. | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| void loadProgram(uint32_t index) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = 0.0f; | |||
| fParamGrid[1] = 0.0f; | |||
| fParamGrid[2] = 0.0f; | |||
| fParamGrid[3] = 0.0f; | |||
| fParamGrid[4] = 0.0f; | |||
| fParamGrid[5] = 0.0f; | |||
| fParamGrid[6] = 0.0f; | |||
| fParamGrid[7] = 0.0f; | |||
| fParamGrid[8] = 0.0f; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = 1.0f; | |||
| fParamGrid[1] = 1.0f; | |||
| fParamGrid[2] = 0.0f; | |||
| fParamGrid[3] = 0.0f; | |||
| fParamGrid[4] = 1.0f; | |||
| fParamGrid[5] = 1.0f; | |||
| fParamGrid[6] = 1.0f; | |||
| fParamGrid[7] = 0.0f; | |||
| fParamGrid[8] = 1.0f; | |||
| break; | |||
| } | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Process */ | |||
| /** | |||
| Run/process function for plugins without MIDI input. | |||
| */ | |||
| void 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 | |||
| @@ -0,0 +1,244 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| /** | |||
| We need the rectangle class from DGL. | |||
| */ | |||
| using DGL::Rectangle; | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| class ExampleUIParameters : public UI | |||
| { | |||
| public: | |||
| /** | |||
| For simplicity this UI will be of constant size. | |||
| */ | |||
| static const int kUIWidth = 512; | |||
| static const int kUIHeight = 512; | |||
| /* constructor */ | |||
| ExampleUIParameters() | |||
| : UI(kUIWidth, kUIHeight) | |||
| { | |||
| /** | |||
| 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: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * 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 parameterChanged(uint32_t index, float value) override | |||
| { | |||
| // update our grid state to match the plugin side | |||
| fParamGrid[index] = (value > 0.5f); | |||
| // trigger repaint | |||
| repaint(); | |||
| } | |||
| /** | |||
| A program has been loaded on the plugin side. | |||
| This is called by the host to inform the UI about program changes. | |||
| */ | |||
| void programLoaded(uint32_t index) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = false; | |||
| fParamGrid[1] = false; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = false; | |||
| fParamGrid[5] = false; | |||
| fParamGrid[6] = false; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = false; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = true; | |||
| fParamGrid[1] = true; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = true; | |||
| fParamGrid[5] = true; | |||
| fParamGrid[6] = true; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = true; | |||
| break; | |||
| } | |||
| 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<int> 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<int> 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) | |||
| 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]; | |||
| 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]; | |||
| 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 | |||
| @@ -0,0 +1,54 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DISTRHO Plugins # | |||
| # ---------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # -------------------------------------------------------------- | |||
| # Project name, used for binaries | |||
| NAME = d_parameters | |||
| # -------------------------------------------------------------- | |||
| # Files to build | |||
| FILES_DSP = \ | |||
| ExamplePluginParameters.cpp | |||
| FILES_UI = \ | |||
| ExampleUIParameters.cpp | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| endif | |||
| ifeq ($(LINUX),true) | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_LIBLO),true) | |||
| TARGETS += ladspa | |||
| TARGETS += dssi | |||
| endif | |||
| endif | |||
| endif | |||
| ifeq ($(HAVE_DGL),true) | |||
| TARGETS += lv2_sep | |||
| else | |||
| TARGETS += lv2_dsp | |||
| endif | |||
| TARGETS += vst | |||
| all: $(TARGETS) | |||
| # -------------------------------------------------------------- | |||
| @@ -0,0 +1,9 @@ | |||
| # Parameters example | |||
| This example will show how parameters work in DPF.<br/> | |||
| The plugin will not do any audio processing.<br/> | |||
| In this example the UI will display a 3x3 grid of colors which can be changed or automated by the host.<br/> | |||
| There are 2 colors: blue and orange. Blue means off, orange means on.<br/> | |||
| When a grid block is clicked its color will change and the host will receive a parameter change.<br/> | |||
| When the host changes a plugin parameter the UI will update accordingly.<br/> | |||
| @@ -0,0 +1,31 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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. | |||
| */ | |||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "States" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/States" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_IS_RT_SAFE 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
| #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
| #define DISTRHO_PLUGIN_WANT_STATE 1 | |||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | |||
| @@ -0,0 +1,316 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 state usage (including UI). | |||
| The plugin will be treated as an effect, but it will not change the host audio. | |||
| */ | |||
| class ExamplePluginStates : public Plugin | |||
| { | |||
| public: | |||
| ExamplePluginStates() | |||
| : Plugin(0, 2, 9) // 0 parameters, 2 programs, 9 states | |||
| { | |||
| /** | |||
| 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: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * 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* getLabel() const override | |||
| { | |||
| return "states"; | |||
| } | |||
| /** | |||
| Get an extensive comment/description about the plugin. | |||
| */ | |||
| const char* getDescription() const override | |||
| { | |||
| return "Simple plugin to demonstrate state usage (including UI).\n\ | |||
| The plugin will be treated as an effect, but it will not change the host audio."; | |||
| } | |||
| /** | |||
| Get the plugin author/maker. | |||
| */ | |||
| const char* getMaker() const override | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| /** | |||
| Get the plugin homepage. | |||
| */ | |||
| const char* getHomePage() const override | |||
| { | |||
| return "https://github.com/DISTRHO/plugin-examples"; | |||
| } | |||
| /** | |||
| Get the plugin license name (a single line of text). | |||
| For commercial plugins this should return some short copyright information. | |||
| */ | |||
| const char* getLicense() const override | |||
| { | |||
| return "ISC"; | |||
| } | |||
| /** | |||
| Get the plugin version, in hexadecimal. | |||
| */ | |||
| uint32_t getVersion() const override | |||
| { | |||
| return d_version(1, 0, 0); | |||
| } | |||
| /** | |||
| Get the plugin unique Id. | |||
| This value is used by LADSPA, DSSI and VST plugin formats. | |||
| */ | |||
| int64_t getUniqueId() const override | |||
| { | |||
| return d_cconst('d', 'S', 't', 's'); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Init */ | |||
| /** | |||
| This plugin has no parameters.. | |||
| */ | |||
| void initParameter(uint32_t, Parameter&) override {} | |||
| /** | |||
| Set the name of the program @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initProgramName(uint32_t index, String& programName) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| programName = "Default"; | |||
| break; | |||
| case 1: | |||
| programName = "Custom"; | |||
| break; | |||
| } | |||
| } | |||
| /** | |||
| Set the state key and default value of @a index. | |||
| This function will be called once, shortly after the plugin is created. | |||
| */ | |||
| void initState(uint32_t index, String& stateKey, String& defaultStateValue) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| stateKey = "top-left"; | |||
| break; | |||
| case 1: | |||
| stateKey = "top-center"; | |||
| break; | |||
| case 2: | |||
| stateKey = "top-right"; | |||
| break; | |||
| case 3: | |||
| stateKey = "middle-left"; | |||
| break; | |||
| case 4: | |||
| stateKey = "middle-center"; | |||
| break; | |||
| case 5: | |||
| stateKey = "middle-right"; | |||
| break; | |||
| case 6: | |||
| stateKey = "bottom-left"; | |||
| break; | |||
| case 7: | |||
| stateKey = "bottom-center"; | |||
| break; | |||
| case 8: | |||
| stateKey = "bottom-right"; | |||
| break; | |||
| } | |||
| defaultStateValue = "false"; | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Internal data */ | |||
| /** | |||
| This plugin has no parameters.. | |||
| */ | |||
| void setParameterValue(uint32_t, float) override {} | |||
| float getParameterValue(uint32_t) const override { return 0.0f; } | |||
| /** | |||
| Load a program. | |||
| The host may call this function from any context, including realtime processing. | |||
| */ | |||
| void loadProgram(uint32_t index) override | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = false; | |||
| fParamGrid[1] = false; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = false; | |||
| fParamGrid[5] = false; | |||
| fParamGrid[6] = false; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = false; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = true; | |||
| fParamGrid[1] = true; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = true; | |||
| fParamGrid[5] = true; | |||
| fParamGrid[6] = true; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = true; | |||
| break; | |||
| } | |||
| } | |||
| /** | |||
| Get the value of an internal state. | |||
| The host may call this function from any non-realtime context. | |||
| */ | |||
| String getState(const char* key) const override | |||
| { | |||
| static const String sTrue ("true"); | |||
| static const String sFalse("false"); | |||
| // check which block changed | |||
| /**/ if (std::strcmp(key, "top-left") == 0) | |||
| return fParamGrid[0] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "top-center") == 0) | |||
| return fParamGrid[1] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "top-right") == 0) | |||
| return fParamGrid[2] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "middle-left") == 0) | |||
| return fParamGrid[3] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "middle-center") == 0) | |||
| return fParamGrid[4] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "middle-right") == 0) | |||
| return fParamGrid[5] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "bottom-left") == 0) | |||
| return fParamGrid[6] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "bottom-center") == 0) | |||
| return fParamGrid[7] ? sTrue : sFalse; | |||
| else if (std::strcmp(key, "bottom-right") == 0) | |||
| return fParamGrid[8] ? sTrue : sFalse; | |||
| return sFalse; | |||
| } | |||
| /** | |||
| Change an internal state. | |||
| */ | |||
| void setState(const char* key, const char* value) override | |||
| { | |||
| const bool valueOnOff = (std::strcmp(value, "true") == 0); | |||
| // check which block changed | |||
| /**/ if (std::strcmp(key, "top-left") == 0) | |||
| fParamGrid[0] = valueOnOff; | |||
| else if (std::strcmp(key, "top-center") == 0) | |||
| fParamGrid[1] = valueOnOff; | |||
| else if (std::strcmp(key, "top-right") == 0) | |||
| fParamGrid[2] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-left") == 0) | |||
| fParamGrid[3] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-center") == 0) | |||
| fParamGrid[4] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-right") == 0) | |||
| fParamGrid[5] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-left") == 0) | |||
| fParamGrid[6] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-center") == 0) | |||
| fParamGrid[7] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-right") == 0) | |||
| fParamGrid[8] = valueOnOff; | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Process */ | |||
| /** | |||
| Run/process function for plugins without MIDI input. | |||
| */ | |||
| void 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 used to display the grid on/off states. | |||
| */ | |||
| bool fParamGrid[9]; | |||
| /** | |||
| Set our plugin class as non-copyable and add a leak detector just in case. | |||
| */ | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginStates) | |||
| }; | |||
| /* ------------------------------------------------------------------------------------------------------------ | |||
| * Plugin entry point, called by DPF to create a new plugin instance. */ | |||
| Plugin* createPlugin() | |||
| { | |||
| return new ExamplePluginStates(); | |||
| } | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,287 @@ | |||
| /* | |||
| * DISTRHO Plugin Framework (DPF) | |||
| * Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| class ExampleUIParameters : public UI | |||
| { | |||
| public: | |||
| /** | |||
| For simplicity this UI will be of constant size. | |||
| */ | |||
| static const int kUIWidth = 512; | |||
| static const int kUIHeight = 512; | |||
| /** | |||
| Get key name from an index. | |||
| */ | |||
| static const char* getStateKeyFromIndex(const uint32_t index) noexcept | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: return "top-left"; | |||
| case 1: return "top-center"; | |||
| case 2: return "top-right"; | |||
| case 3: return "middle-left"; | |||
| case 4: return "middle-center"; | |||
| case 5: return "middle-right"; | |||
| case 6: return "bottom-left"; | |||
| case 7: return "bottom-center"; | |||
| case 8: return "bottom-right"; | |||
| } | |||
| return "unknown"; | |||
| } | |||
| /* constructor */ | |||
| ExampleUIParameters() | |||
| : UI() | |||
| { | |||
| /** | |||
| Initialize the grid to all off per default. | |||
| */ | |||
| std::memset(fParamGrid, 0, sizeof(bool)*9); | |||
| setSize(kUIWidth, kUIHeight); | |||
| } | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * DSP/Plugin Callbacks */ | |||
| /** | |||
| This plugin has no parameters, so we can safely ignore this. | |||
| */ | |||
| void parameterChanged(uint32_t, float) override {} | |||
| /** | |||
| A program has been loaded on the plugin side. | |||
| This is called by the host to inform the UI about program changes. | |||
| */ | |||
| void programLoaded(uint32_t index) override | |||
| { | |||
| d_stdout("UI programLoaded %i", index); | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| fParamGrid[0] = false; | |||
| fParamGrid[1] = false; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = false; | |||
| fParamGrid[5] = false; | |||
| fParamGrid[6] = false; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = false; | |||
| break; | |||
| case 1: | |||
| fParamGrid[0] = true; | |||
| fParamGrid[1] = true; | |||
| fParamGrid[2] = false; | |||
| fParamGrid[3] = false; | |||
| fParamGrid[4] = true; | |||
| fParamGrid[5] = true; | |||
| fParamGrid[6] = true; | |||
| fParamGrid[7] = false; | |||
| fParamGrid[8] = true; | |||
| break; | |||
| } | |||
| repaint(); | |||
| } | |||
| /** | |||
| A state has changed on the plugin side. | |||
| This is called by the host to inform the UI about state changes. | |||
| */ | |||
| void stateChanged(const char* key, const char* value) override | |||
| { | |||
| const bool valueOnOff = (std::strcmp(value, "true") == 0); | |||
| // check which block changed | |||
| /**/ if (std::strcmp(key, "top-left") == 0) | |||
| fParamGrid[0] = valueOnOff; | |||
| else if (std::strcmp(key, "top-center") == 0) | |||
| fParamGrid[1] = valueOnOff; | |||
| else if (std::strcmp(key, "top-right") == 0) | |||
| fParamGrid[2] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-left") == 0) | |||
| fParamGrid[3] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-center") == 0) | |||
| fParamGrid[4] = valueOnOff; | |||
| else if (std::strcmp(key, "middle-right") == 0) | |||
| fParamGrid[5] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-left") == 0) | |||
| fParamGrid[6] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-center") == 0) | |||
| fParamGrid[7] = valueOnOff; | |||
| else if (std::strcmp(key, "bottom-right") == 0) | |||
| fParamGrid[8] = valueOnOff; | |||
| // trigger repaint | |||
| repaint(); | |||
| } | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * Widget Callbacks */ | |||
| /** | |||
| The OpenGL drawing function. | |||
| This UI will draw a 3x3 grid, with on/off states according to plugin state. | |||
| */ | |||
| void onDisplay() override | |||
| { | |||
| Rectangle<int> 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 state 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<int> 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)) | |||
| { | |||
| // 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) | |||
| setState(getStateKeyFromIndex(index), fParamGrid[index] ? "true" : "false"); | |||
| // 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]; | |||
| setState(getStateKeyFromIndex(index), fParamGrid[index] ? "true" : "false"); | |||
| 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]; | |||
| setState(getStateKeyFromIndex(index), fParamGrid[index] ? "true" : "false"); | |||
| repaint(); | |||
| break; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| private: | |||
| /** | |||
| Our states used to display the grid. | |||
| The host does not know about these. | |||
| */ | |||
| 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 | |||
| @@ -0,0 +1,53 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for DISTRHO Plugins # | |||
| # ---------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| # -------------------------------------------------------------- | |||
| # Project name, used for binaries | |||
| NAME = d_states | |||
| # -------------------------------------------------------------- | |||
| # Files to build | |||
| FILES_DSP = \ | |||
| ExamplePluginStates.cpp | |||
| FILES_UI = \ | |||
| ExampleUIStates.cpp | |||
| # -------------------------------------------------------------- | |||
| # Do some magic | |||
| include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| # Enable all possible plugin types | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_JACK),true) | |||
| TARGETS += jack | |||
| endif | |||
| endif | |||
| ifeq ($(LINUX),true) | |||
| ifeq ($(HAVE_DGL),true) | |||
| ifeq ($(HAVE_LIBLO),true) | |||
| TARGETS += dssi | |||
| endif | |||
| endif | |||
| endif | |||
| ifeq ($(HAVE_DGL),true) | |||
| TARGETS += lv2_sep | |||
| else | |||
| TARGETS += lv2_dsp | |||
| endif | |||
| TARGETS += vst | |||
| all: $(TARGETS) | |||
| # -------------------------------------------------------------- | |||
| @@ -0,0 +1,9 @@ | |||
| # States example | |||
| This example will show how states work in DPF.<br/> | |||
| The plugin will not do any audio processing.<br/> | |||
| In this example the UI will display a 3x3 grid of colors which can *not* be changed by the host.<br/> | |||
| There are 2 colors: blue and orange. Blue means off, orange means on.<br/> | |||
| When a grid block is clicked its color will change and the host will receive a message which is auto-saved.<br/> | |||
| When the UI is opened it will receive messages indicating the last used block states.<br/> | |||