@@ -0,0 +1,19 @@ | |||||
*.a | |||||
*.d | |||||
*.o | |||||
*.exe | |||||
*.dll | |||||
*.dylib | |||||
*.so | |||||
*.zip | |||||
.kdev_include_paths | |||||
.kdev4/ | |||||
.DS_Store | |||||
bin/*-dssi/ | |||||
bin/*.lv2/ | |||||
bin/d_* | |||||
bin/ducka | |||||
bin/roomy |
@@ -0,0 +1,3 @@ | |||||
[submodule "dpf"] | |||||
path = dpf | |||||
url = git://github.com/DISTRHO/DPF.git |
@@ -0,0 +1,9 @@ | |||||
[Project] | |||||
Manager=KDevCustomMakeManager | |||||
Name=DPF Plugins | |||||
[Filters] | |||||
Excludes=*/.*,*/*~,*/*.a,*/*.d,*/*.o,*/*.so | |||||
[Project] | |||||
VersionControlSupport=kdevgit |
@@ -0,0 +1,13 @@ | |||||
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. |
@@ -0,0 +1,51 @@ | |||||
#!/usr/bin/make -f | |||||
# Makefile for DISTRHO Plugins # | |||||
# ---------------------------- # | |||||
# Created by falkTX | |||||
# | |||||
include Makefile.mk | |||||
all: libs plugins gen | |||||
# -------------------------------------------------------------- | |||||
libs: | |||||
ifeq ($(HAVE_DGL),true) | |||||
$(MAKE) -C dpf/dgl | |||||
endif | |||||
plugins: libs | |||||
$(MAKE) all -C plugins/Info | |||||
$(MAKE) all -C plugins/Latency | |||||
$(MAKE) all -C plugins/Meters | |||||
$(MAKE) all -C plugins/MidiThrough | |||||
$(MAKE) all -C plugins/Parameters | |||||
$(MAKE) all -C plugins/States | |||||
gen: plugins dpf/utils/lv2_ttl_generator | |||||
@$(CURDIR)/dpf/utils/generate-ttl.sh | |||||
ifeq ($(MACOS),true) | |||||
@$(CURDIR)/dpf/utils/generate-vst-bundles.sh | |||||
endif | |||||
dpf/utils/lv2_ttl_generator: | |||||
$(MAKE) -C dpf/utils/lv2-ttl-generator | |||||
# -------------------------------------------------------------- | |||||
clean: | |||||
ifeq ($(HAVE_DGL),true) | |||||
$(MAKE) clean -C dpf/dgl | |||||
endif | |||||
$(MAKE) clean -C dpf/utils/lv2-ttl-generator | |||||
$(MAKE) clean -C plugins/Info | |||||
$(MAKE) clean -C plugins/Latency | |||||
$(MAKE) clean -C plugins/Meters | |||||
$(MAKE) clean -C plugins/MidiThrough | |||||
$(MAKE) clean -C plugins/Parameters | |||||
$(MAKE) clean -C plugins/States | |||||
# -------------------------------------------------------------- | |||||
.PHONY: plugins |
@@ -0,0 +1,147 @@ | |||||
#!/usr/bin/make -f | |||||
# Makefile for DISTRHO Plugins # | |||||
# ---------------------------- # | |||||
# Created by falkTX | |||||
# | |||||
AR ?= ar | |||||
CC ?= gcc | |||||
CXX ?= g++ | |||||
# -------------------------------------------------------------- | |||||
# Fallback to Linux if no other OS defined | |||||
ifneq ($(HAIKU),true) | |||||
ifneq ($(MACOS),true) | |||||
ifneq ($(WIN32),true) | |||||
LINUX=true | |||||
endif | |||||
endif | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# Set build and link flags | |||||
BASE_FLAGS = -Wall -Wextra -pipe | |||||
BASE_OPTS = -O2 -ffast-math -mtune=generic -msse -msse2 -fdata-sections -ffunction-sections | |||||
ifneq ($(MACOS),true) | |||||
# MacOS doesn't support this | |||||
BASE_OPTS += -mfpmath=sse | |||||
endif | |||||
ifeq ($(MACOS),true) | |||||
# MacOS linker flags | |||||
LINK_OPTS = -fdata-sections -ffunction-sections -Wl,-dead_strip -Wl,-dead_strip_dylibs | |||||
else | |||||
# Common linker flags | |||||
LINK_OPTS = -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,-O1 -Wl,--as-needed -Wl,--strip-all | |||||
endif | |||||
ifeq ($(RASPPI),true) | |||||
# Raspberry-Pi optimization flags | |||||
BASE_OPTS = -O2 -ffast-math -march=armv6 -mfpu=vfp -mfloat-abi=hard | |||||
LINK_OPTS = -Wl,-O1 -Wl,--as-needed -Wl,--strip-all | |||||
endif | |||||
ifeq ($(PANDORA),true) | |||||
# OpenPandora optimization flags | |||||
BASE_OPTS = -O2 -ffast-math -march=armv7-a -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp | |||||
LINK_OPTS = -Wl,-O1 -Wl,--as-needed -Wl,--strip-all | |||||
endif | |||||
ifeq ($(NOOPT),true) | |||||
# No optimization flags | |||||
BASE_OPTS = -O2 -ffast-math -fdata-sections -ffunction-sections | |||||
endif | |||||
ifneq ($(WIN32),true) | |||||
# not needed for Windows | |||||
BASE_FLAGS += -fPIC -DPIC | |||||
endif | |||||
ifeq ($(DEBUG),true) | |||||
BASE_FLAGS += -DDEBUG -O0 -g | |||||
LINK_OPTS = | |||||
else | |||||
BASE_FLAGS += -DNDEBUG $(BASE_OPTS) -fvisibility=hidden | |||||
CXXFLAGS += -fvisibility-inlines-hidden | |||||
endif | |||||
BUILD_C_FLAGS = $(BASE_FLAGS) -std=c99 -std=gnu99 $(CFLAGS) | |||||
BUILD_CXX_FLAGS = $(BASE_FLAGS) -std=c++0x -std=gnu++0x $(CXXFLAGS) $(CPPFLAGS) | |||||
LINK_FLAGS = $(LINK_OPTS) -Wl,--no-undefined $(LDFLAGS) | |||||
ifeq ($(MACOS),true) | |||||
# No C++11 support | |||||
BUILD_CXX_FLAGS = $(BASE_FLAGS) $(CXXFLAGS) $(CPPFLAGS) | |||||
LINK_FLAGS = $(LINK_OPTS) $(LDFLAGS) | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# Check for optional libs | |||||
ifeq ($(LINUX),true) | |||||
HAVE_DGL = $(shell pkg-config --exists gl x11 && echo true) | |||||
HAVE_JACK = $(shell pkg-config --exists jack && echo true) | |||||
HAVE_LIBLO = $(shell pkg-config --exists liblo && echo true) | |||||
endif | |||||
ifeq ($(MACOS),true) | |||||
HAVE_DGL = true | |||||
endif | |||||
ifeq ($(WIN32),true) | |||||
HAVE_DGL = true | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# Set libs stuff | |||||
ifeq ($(HAVE_DGL),true) | |||||
ifeq ($(LINUX),true) | |||||
DGL_FLAGS = $(shell pkg-config --cflags gl x11) | |||||
DGL_LIBS = $(shell pkg-config --libs gl x11) | |||||
endif | |||||
ifeq ($(MACOS),true) | |||||
DGL_LIBS = -framework OpenGL -framework Cocoa | |||||
endif | |||||
ifeq ($(WIN32),true) | |||||
DGL_LIBS = -lopengl32 -lgdi32 | |||||
endif | |||||
endif # HAVE_DGL | |||||
# -------------------------------------------------------------- | |||||
# Set app extension | |||||
ifeq ($(WIN32),true) | |||||
APP_EXT = .exe | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# Set shared lib extension | |||||
LIB_EXT = .so | |||||
ifeq ($(MACOS),true) | |||||
LIB_EXT = .dylib | |||||
endif | |||||
ifeq ($(WIN32),true) | |||||
LIB_EXT = .dll | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# Set shared library CLI arg | |||||
SHARED = -shared | |||||
ifeq ($(MACOS),true) | |||||
SHARED = -dynamiclib | |||||
endif | |||||
# -------------------------------------------------------------- |
@@ -1,3 +1,3 @@ | |||||
# DPF Plugin Examples | # DPF Plugin Examples | ||||
NOTE: Plugin examples have been moved inside DPF, please visit https://github.com/DISTRHO/DPF. | |||||
This repository contains plugin examples and test code for DPF. |
@@ -0,0 +1,3 @@ | |||||
All final plugin builds will be placed in this folder. | |||||
There is no "make install" process, simply copy those files to their appropriate place. |
@@ -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 | |||||
OBJS_DSP = \ | |||||
InfoExamplePlugin.cpp.o | |||||
OBJS_UI = \ | |||||
InfoExampleUI.cpp.o | |||||
# -------------------------------------------------------------- | |||||
# 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 | |||||
OBJS_DSP = \ | |||||
LatencyExamplePlugin.cpp.o | |||||
# -------------------------------------------------------------- | |||||
# 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,153 @@ | |||||
#!/usr/bin/make -f | |||||
# Makefile for DISTRHO Plugins # | |||||
# ---------------------------- # | |||||
# Created by falkTX | |||||
# | |||||
# NAME, OBJS_DSP and OBJS_UI have been defined before | |||||
include ../../Makefile.mk | |||||
ifeq ($(OBJS_UI),) | |||||
HAVE_DGL = false | |||||
endif | |||||
# -------------------------------------------------------------- | |||||
# Basic setup | |||||
TARGET_DIR = ../../bin | |||||
BUILD_C_FLAGS += -I. | |||||
BUILD_CXX_FLAGS += -I. -I../../dpf/distrho -I../../dpf/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 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 = ../../dpf/distrho/DistrhoPluginMain.cpp | |||||
ifeq ($(HAVE_DGL),true) | |||||
DISTRHO_UI_FILES = ../../dpf/distrho/DistrhoUIMain.cpp ../../dpf/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 | |||||
%.c.o: %.c | |||||
$(CC) $< $(BUILD_C_FLAGS) -MD -MP -c -o $@ | |||||
%.cpp.o: %.cpp | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) -MD -MP -c -o $@ | |||||
clean: | |||||
rm -f *.d *.o | |||||
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 $@) | |||||
$(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 $@) | |||||
$(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 $@) | |||||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_DSSI -o $@ | |||||
$(dssi_ui): $(OBJS_UI) $(DISTRHO_UI_FILES) | |||||
mkdir -p $(shell dirname $@) | |||||
$(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 $@) | |||||
$(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 $@) | |||||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(SHARED) -DDISTRHO_PLUGIN_TARGET_LV2 -o $@ | |||||
$(lv2_ui): $(OBJS_UI) $(DISTRHO_UI_FILES) | |||||
mkdir -p $(shell dirname $@) | |||||
$(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 $@) | |||||
$(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 | |||||
OBJS_DSP = \ | |||||
ExamplePluginMeters.cpp.o | |||||
OBJS_UI = \ | |||||
ExampleUIMeters.cpp.o | |||||
# -------------------------------------------------------------- | |||||
# 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 | |||||
OBJS_DSP = \ | |||||
MidiThroughExamplePlugin.cpp.o | |||||
# -------------------------------------------------------------- | |||||
# 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 | |||||
OBJS_DSP = \ | |||||
ExamplePluginParameters.cpp.o | |||||
OBJS_UI = \ | |||||
ExampleUIParameters.cpp.o | |||||
# -------------------------------------------------------------- | |||||
# 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 | |||||
OBJS_DSP = \ | |||||
ExamplePluginStates.cpp.o | |||||
OBJS_UI = \ | |||||
ExampleUIStates.cpp.o | |||||
# -------------------------------------------------------------- | |||||
# 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/> |