@@ -0,0 +1,14 @@ | |||
*.a | |||
*.o | |||
*.exe | |||
*.dll | |||
*.dylib | |||
*.so | |||
.kdev_include_paths | |||
.kdev4/ | |||
bin/*-dssi/ | |||
bin/*.lv2/ | |||
bin/d_* |
@@ -13,6 +13,7 @@ libs: | |||
plugins: libs | |||
$(MAKE) all -C plugins/Parameters | |||
$(MAKE) all -C plugins/States | |||
gen: plugins dpf/utils/lv2_ttl_generator | |||
@$(CURDIR)/dpf/utils/generate-ttl.sh | |||
@@ -26,6 +27,7 @@ clean: | |||
$(MAKE) clean -C dpf/dgl | |||
$(MAKE) clean -C dpf/utils/lv2-ttl-generator | |||
$(MAKE) clean -C plugins/Parameters | |||
$(MAKE) clean -C plugins/States | |||
# -------------------------------------------------------------- | |||
@@ -1 +1 @@ | |||
Subproject commit 0f0bacab5d200b3177eec4a176f1bea74c04f424 | |||
Subproject commit 05fea48bd0e9bf04a6f57b693213527ba694cfa8 |
@@ -62,7 +62,7 @@ all: | |||
%.c.o: %.c | |||
$(CC) $< $(BUILD_C_FLAGS) -c -o $@ | |||
%.cpp.o: %.cpp | |||
%.cpp.o: %.cpp ../../dpf/distrho/* | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
clean: | |||
@@ -148,9 +148,10 @@ protected: | |||
} | |||
/** | |||
Our parameter names are unique valid symbols, so we can just re-use them. | |||
Our parameter names are valid symbols except for "-". | |||
*/ | |||
parameter.symbol = parameter.name; | |||
parameter.symbol.replace('-', '_'); | |||
} | |||
/* -------------------------------------------------------------------------------------------------------- | |||
@@ -0,0 +1,35 @@ | |||
/* | |||
* 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_NAME "States" | |||
#define DISTRHO_PLUGIN_HAS_UI 1 | |||
#define DISTRHO_PLUGIN_IS_SYNTH 0 | |||
#define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 | |||
#define DISTRHO_PLUGIN_WANT_STATE 1 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/States" | |||
#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED |
@@ -0,0 +1,184 @@ | |||
/* | |||
* 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 "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, 0, 9) // 0 parameters, 0 programs, 9 states | |||
{ | |||
// nothing here | |||
} | |||
protected: | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* Information */ | |||
/** | |||
Get the plugin label. | |||
A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers. | |||
*/ | |||
const char* d_getLabel() const override | |||
{ | |||
return "states"; | |||
} | |||
/** | |||
Get the plugin author/maker. | |||
*/ | |||
const char* d_getMaker() const override | |||
{ | |||
return "DISTRHO"; | |||
} | |||
/** | |||
Get the plugin license name (a single line of text). | |||
*/ | |||
const char* d_getLicense() const override | |||
{ | |||
return "ISC"; | |||
} | |||
/** | |||
Get the plugin version, in hexadecimal. | |||
TODO format to be defined | |||
*/ | |||
uint32_t d_getVersion() const override | |||
{ | |||
return 0x1000; | |||
} | |||
/** | |||
Get the plugin unique Id. | |||
This value is used by LADSPA, DSSI and VST plugin formats. | |||
*/ | |||
int64_t d_getUniqueId() const override | |||
{ | |||
return d_cconst('d', 'S', 't', 's'); | |||
} | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* Parameters */ | |||
/** | |||
This plugin has no parameters, so we can safely ignore some functions. | |||
*/ | |||
void d_initParameter(uint32_t, Parameter&) override {} | |||
void d_setParameterValue(uint32_t, float) override {} | |||
float d_getParameterValue(uint32_t) const override { return 0.0f; } | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* State */ | |||
/** | |||
Set the key name of the state @a index. | |||
This function will be called once, shortly after the plugin is created. | |||
*/ | |||
void d_initStateKey(uint32_t index, d_string& stateKey) 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; | |||
} | |||
} | |||
/** | |||
Change an internal state. | |||
*/ | |||
void d_setState(const char*, const char*) override | |||
{ | |||
// there is no plugin side state here. | |||
// states on this plugin will only change the UI grid, so we do nothing here | |||
} | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* Process */ | |||
/** | |||
Run/process function for plugins without MIDI input. | |||
*/ | |||
void d_run(const float** inputs, float** outputs, uint32_t frames) override | |||
{ | |||
/** | |||
This plugin does nothing, it just demonstrates parameter usage. | |||
So here we directly copy inputs over outputs, leaving the audio untouched. | |||
We need to be careful in case the host re-uses the same buffer for both ins and outs. | |||
*/ | |||
if (outputs[0] != inputs[0]) | |||
std::memcpy(outputs[0], inputs[0], sizeof(float)*frames); | |||
if (outputs[1] != inputs[1]) | |||
std::memcpy(outputs[1], inputs[1], sizeof(float)*frames); | |||
} | |||
// ------------------------------------------------------------------------------------------------------- | |||
private: | |||
// nothing here | |||
/** | |||
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,254 @@ | |||
/* | |||
* 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 | |||
/** | |||
For simplicity this UI will be of constant size. | |||
*/ | |||
static const int kUIWidth = 512; | |||
static const int kUIHeight = 512; | |||
/** | |||
We need the rectangle class from DGL. | |||
*/ | |||
using DGL::Rectangle; | |||
/** | |||
Get key name from an index. | |||
*/ | |||
static const char* getStateKeyFromIndex(const uint32_t index) | |||
{ | |||
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"; | |||
} | |||
// ----------------------------------------------------------------------------------------------------------- | |||
class ExampleUIParameters : public UI | |||
{ | |||
public: | |||
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 d_parameterChanged(uint32_t, float) override {} | |||
/** | |||
A state has changed on the plugin side. | |||
This is called by the host to inform the UI about state changes. | |||
*/ | |||
void d_stateChanged(const char* key, const char* value) | |||
{ | |||
// check which block changed, enable it if its value is "true" | |||
/**/ if (std::strcmp(key, "top-left") == 0) | |||
fParamGrid[0] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "top-center") == 0) | |||
fParamGrid[1] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "top-right") == 0) | |||
fParamGrid[2] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "middle-left") == 0) | |||
fParamGrid[3] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "middle-center") == 0) | |||
fParamGrid[4] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "middle-right") == 0) | |||
fParamGrid[5] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "bottom-left") == 0) | |||
fParamGrid[6] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "bottom-center") == 0) | |||
fParamGrid[7] = (std::strcmp(value, "true") == 0); | |||
else if (std::strcmp(key, "bottom-right") == 0) | |||
fParamGrid[8] = (std::strcmp(value, "true") == 0); | |||
// 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) | |||
d_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]; | |||
d_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]; | |||
d_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,35 @@ | |||
#!/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 ($(LINUX),true) | |||
all: jack dssi lv2_sep vst | |||
else | |||
all: dssi lv2_sep vst | |||
endif | |||
# -------------------------------------------------------------- |
@@ -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/> |