| @@ -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 | plugins: libs | ||||
| $(MAKE) all -C plugins/Parameters | $(MAKE) all -C plugins/Parameters | ||||
| $(MAKE) all -C plugins/States | |||||
| gen: plugins dpf/utils/lv2_ttl_generator | gen: plugins dpf/utils/lv2_ttl_generator | ||||
| @$(CURDIR)/dpf/utils/generate-ttl.sh | @$(CURDIR)/dpf/utils/generate-ttl.sh | ||||
| @@ -26,6 +27,7 @@ clean: | |||||
| $(MAKE) clean -C dpf/dgl | $(MAKE) clean -C dpf/dgl | ||||
| $(MAKE) clean -C dpf/utils/lv2-ttl-generator | $(MAKE) clean -C dpf/utils/lv2-ttl-generator | ||||
| $(MAKE) clean -C plugins/Parameters | $(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 | %.c.o: %.c | ||||
| $(CC) $< $(BUILD_C_FLAGS) -c -o $@ | $(CC) $< $(BUILD_C_FLAGS) -c -o $@ | ||||
| %.cpp.o: %.cpp | |||||
| %.cpp.o: %.cpp ../../dpf/distrho/* | |||||
| $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | ||||
| clean: | 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 = 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/> | |||||