| @@ -202,6 +202,7 @@ void carla_register_native_plugin_midiThrough(); | |||
| void carla_register_native_plugin_3BandEQ(); | |||
| void carla_register_native_plugin_3BandSplitter(); | |||
| void carla_register_native_plugin_PingPongPan(); | |||
| void carla_register_native_plugin_Notes(); | |||
| #ifdef WANT_AUDIOFILE | |||
| void carla_register_native_plugin_audiofile(); | |||
| @@ -39,10 +39,10 @@ public: | |||
| DistrhoPlugin3BandEQ(); | |||
| ~DistrhoPlugin3BandEQ(); | |||
| // --------------------------------------------- | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| const char* d_label() const | |||
| { | |||
| return "3BandEQ"; | |||
| @@ -68,27 +68,28 @@ protected: | |||
| return d_cconst('D', '3', 'E', 'Q'); | |||
| } | |||
| // --------------------------------------------- | |||
| // Init | |||
| void d_initParameter(uint32_t index, Parameter& parameter); | |||
| void d_initProgramName(uint32_t index, d_string& programName); | |||
| // --------------------------------------------- | |||
| // Internal data | |||
| float d_parameterValue(uint32_t index); | |||
| void d_setParameterValue(uint32_t index, float value); | |||
| void d_setProgram(uint32_t index); | |||
| // --------------------------------------------- | |||
| // Process | |||
| void d_activate(); | |||
| void d_deactivate(); | |||
| void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | |||
| // --------------------------------------------- | |||
| #ifdef QTCREATOR_TEST | |||
| void d_initStateKey(uint32_t, d_string&) {} | |||
| void d_setState(const char*, const char*) {} | |||
| #endif | |||
| private: | |||
| float fLow, fMid, fHigh, fMaster, fLowMidFreq, fMidHighFreq; | |||
| @@ -39,10 +39,10 @@ public: | |||
| DistrhoPlugin3BandSplitter(); | |||
| ~DistrhoPlugin3BandSplitter(); | |||
| // --------------------------------------------- | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| const char* d_label() const | |||
| { | |||
| return "3BandSplitter"; | |||
| @@ -68,16 +68,22 @@ protected: | |||
| return d_cconst('D', '3', 'E', 'S'); | |||
| } | |||
| // --------------------------------------------- | |||
| // Init | |||
| void d_initParameter(uint32_t index, Parameter& parameter); | |||
| void d_initProgramName(uint32_t index, d_string& programName); | |||
| // --------------------------------------------- | |||
| // Internal data | |||
| float d_parameterValue(uint32_t index); | |||
| void d_setParameterValue(uint32_t index, float value); | |||
| void d_setProgram(uint32_t index); | |||
| // --------------------------------------------- | |||
| // Process | |||
| void d_activate(); | |||
| void d_deactivate(); | |||
| void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | |||
| @@ -9,8 +9,8 @@ include ../Makefile.mk | |||
| # -------------------------------------------------------------- | |||
| BUILD_CXX_FLAGS += -I../../libs/distrho | |||
| BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtGui gl) | |||
| LINK_FLAGS += $(shell pkg-config --libs QtGui gl) | |||
| BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui gl) | |||
| LINK_FLAGS += $(shell pkg-config --libs QtCore QtGui gl) | |||
| ifeq ($(HAVE_AF_DEPS),true) | |||
| AF_CXX_FLAGS = $(BUILD_CXX_FLAGS) | |||
| @@ -20,8 +20,8 @@ endif | |||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||
| ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) | |||
| ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml) -pthread | |||
| LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml) -lpthread | |||
| ZYN_CXX_FLAGS += $(shell pkg-config --cflags fftw3 mxml) | |||
| LINK_FLAGS += $(shell pkg-config --libs fftw3 mxml) | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| @@ -36,7 +36,8 @@ OBJS = \ | |||
| OBJS += \ | |||
| distrho-3bandeq.cpp.o \ | |||
| distrho-3bandsplitter.cpp.o \ | |||
| distrho-pingpongpan.cpp.o | |||
| distrho-pingpongpan.cpp.o \ | |||
| distrho-notes.cpp.o | |||
| ifeq ($(HAVE_AF_DEPS),true) | |||
| OBJS += \ | |||
| @@ -88,8 +89,16 @@ distrho-3bandsplitter.cpp.o: distrho-3bandsplitter.cpp | |||
| distrho-pingpongpan.cpp.o: distrho-pingpongpan.cpp | |||
| $(CXX) $< $(BUILD_CXX_FLAGS) -Ipingpongpan -DDISTRHO_NAMESPACE=DISTRHO_PingPongPan -c -o $@ | |||
| distrho-notes.cpp.o: distrho-notes.cpp | |||
| $(CXX) $< $(BUILD_CXX_FLAGS) -Inotes -DDISTRHO_NAMESPACE=DISTRHO_Notes -c -o $@ | |||
| zynaddsubfx.cpp.o: zynaddsubfx.cpp | |||
| $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ | |||
| zynaddsubfx-src.cpp.o: zynaddsubfx-src.cpp | |||
| $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ | |||
| # -------------------------------------------------------------- | |||
| moc_%.cpp: %.hpp | |||
| $(MOC) $< -o $@ | |||
| @@ -0,0 +1,57 @@ | |||
| /* | |||
| * Carla Native Plugins | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #include "CarlaNative.hpp" | |||
| // Plugin Code | |||
| #include "notes/DistrhoPluginNotes.cpp" | |||
| #include "notes/DistrhoUINotes.cpp" | |||
| // Carla DISTRHO Plugin | |||
| #include "distrho/DistrhoPluginCarla.cpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| static const PluginDescriptor notesDesc = { | |||
| /* category */ ::PLUGIN_CATEGORY_UTILITY, | |||
| /* hints */ static_cast<PluginHints>(::PLUGIN_IS_RTSAFE | ::PLUGIN_HAS_GUI | ::PLUGIN_USES_SINGLE_THREAD), | |||
| /* audioIns */ DISTRHO_PLUGIN_NUM_INPUTS, | |||
| /* audioOuts */ DISTRHO_PLUGIN_NUM_OUTPUTS, | |||
| /* midiIns */ 0, | |||
| /* midiOuts */ 0, | |||
| /* paramIns */ 1, | |||
| /* paramOuts */ 0, | |||
| /* name */ DISTRHO_PLUGIN_NAME, | |||
| /* label */ "Notes", | |||
| /* maker */ "falkTX", | |||
| /* copyright */ "GPL v2+", | |||
| PluginDescriptorFILL(PluginCarla) | |||
| }; | |||
| END_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------- | |||
| void carla_register_native_plugin_Notes() | |||
| { | |||
| USE_NAMESPACE_DISTRHO | |||
| carla_register_native_plugin(¬esDesc); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -20,7 +20,7 @@ | |||
| #include "DistrhoPluginMain.cpp" | |||
| // TODO | |||
| #undef DISTRHO_PLUGIN_HAS_UI | |||
| //#undef DISTRHO_PLUGIN_HAS_UI | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| #include <QtGui/QMainWindow> | |||
| @@ -43,11 +43,11 @@ public: | |||
| kHost(host), | |||
| kPlugin(plugin), | |||
| fWidget(this), | |||
| fUi(this, (intptr_t)fWidget.winId(), setParameterCallback, setStateCallback, uiEditParameterCallback, uiSendNoteCallback, uiResizeCallback) | |||
| fUi(this, (intptr_t)fWidget.winId(), editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback) | |||
| { | |||
| setCentralWidget(&fWidget); | |||
| setFixedSize(fUi.getWidth(), fUi.getHeight()); | |||
| setWindowTitle(fUi.getName()); | |||
| setFixedSize(fUi.width(), fUi.height()); | |||
| setWindowTitle(fUi.name()); | |||
| } | |||
| ~UICarla() | |||
| @@ -73,17 +73,35 @@ public: | |||
| void carla_setMidiProgram(const uint32_t realProgram) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| fUi.programChanged(realProgram); | |||
| #else | |||
| return; | |||
| // unused | |||
| (void)realProgram; | |||
| #endif | |||
| } | |||
| void carla_setCustomData(const char* const key, const char* const value) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| fUi.stateChanged(key, value); | |||
| #else | |||
| return; | |||
| // unused | |||
| (void)key; | |||
| (void)value; | |||
| #endif | |||
| } | |||
| // --------------------------------------------- | |||
| protected: | |||
| void editParameter(uint32_t, bool) | |||
| { | |||
| // TODO | |||
| } | |||
| void setParameterValue(uint32_t rindex, float value) | |||
| { | |||
| kHost->ui_parameter_changed(kHost->handle, rindex, value); | |||
| @@ -94,17 +112,12 @@ protected: | |||
| kHost->ui_custom_data_changed(kHost->handle, key, value); | |||
| } | |||
| void uiEditParameter(uint32_t, bool) | |||
| void sendNote(bool, uint8_t, uint8_t, uint8_t) | |||
| { | |||
| // TODO | |||
| } | |||
| void uiSendNote(bool, uint8_t, uint8_t, uint8_t) | |||
| { | |||
| // TODO | |||
| } | |||
| void uiResize(int width, int height) | |||
| void uiResize(unsigned int width, unsigned int height) | |||
| { | |||
| setFixedSize(width, height); | |||
| } | |||
| @@ -137,6 +150,11 @@ private: | |||
| #define handlePtr ((UICarla*)ptr) | |||
| static void editParameterCallback(void* ptr, uint32_t index, bool started) | |||
| { | |||
| handlePtr->editParameter(index, started); | |||
| } | |||
| static void setParameterCallback(void* ptr, uint32_t rindex, float value) | |||
| { | |||
| handlePtr->setParameterValue(rindex, value); | |||
| @@ -147,17 +165,12 @@ private: | |||
| handlePtr->setState(key, value); | |||
| } | |||
| static void uiEditParameterCallback(void* ptr, uint32_t index, bool started) | |||
| static void sendNoteCallback(void* ptr, bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) | |||
| { | |||
| handlePtr->uiEditParameter(index, started); | |||
| handlePtr->sendNote(onOff, channel, note, velocity); | |||
| } | |||
| static void uiSendNoteCallback(void* ptr, bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) | |||
| { | |||
| handlePtr->uiSendNote(onOff, channel, note, velocity); | |||
| } | |||
| static void uiResizeCallback(void* ptr, int width, int height) | |||
| static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height) | |||
| { | |||
| handlePtr->uiResize(width, height); | |||
| } | |||
| @@ -178,14 +191,14 @@ public: | |||
| : PluginDescriptorClass(host) | |||
| { | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| fUi = nullptr; | |||
| fUiPtr = nullptr; | |||
| #endif | |||
| } | |||
| ~PluginCarla() | |||
| { | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| fUi = nullptr; | |||
| fUiPtr = nullptr; | |||
| #endif | |||
| } | |||
| @@ -358,51 +371,51 @@ protected: | |||
| if (show) | |||
| createUiIfNeeded(); | |||
| if (uiPtr != nullptr) | |||
| uiPtr->carla_show(show); | |||
| if (fUiPtr != nullptr) | |||
| fUiPtr->carla_show(show); | |||
| } | |||
| void uiIdle() | |||
| { | |||
| CARLA_ASSERT(uiPtr != nullptr); | |||
| CARLA_ASSERT(fUiPtr != nullptr); | |||
| if (uiPtr != nullptr) | |||
| uiPtr->carla_idle(); | |||
| if (fUiPtr != nullptr) | |||
| fUiPtr->carla_idle(); | |||
| } | |||
| void uiSetParameterValue(const uint32_t index, const float value) | |||
| { | |||
| CARLA_ASSERT(uiPtr != nullptr); | |||
| CARLA_ASSERT(fUiPtr != nullptr); | |||
| CARLA_ASSERT(index < getParameterCount()); | |||
| if (uiPtr != nullptr) | |||
| uiPtr->carla_setParameterValue(index, value); | |||
| if (fUiPtr != nullptr) | |||
| fUiPtr->carla_setParameterValue(index, value); | |||
| } | |||
| # if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| void uiSetMidiProgram(const uint32_t bank, const uint32_t program) | |||
| { | |||
| CARLA_ASSERT(uiPtr); | |||
| CARLA_ASSERT(fUiPtr != nullptr); | |||
| uint32_t realProgram = bank * 128 + program; | |||
| if (realProgram >= plugin.programCount()) | |||
| if (realProgram >= fPlugin.programCount()) | |||
| return; | |||
| if (uiPtr != nullptr) | |||
| uiPtr->carla_setMidiProgram(realProgram); | |||
| if (fUiPtr != nullptr) | |||
| fUiPtr->carla_setMidiProgram(realProgram); | |||
| } | |||
| # endif | |||
| # if DISTRHO_PLUGIN_WANT_STATE | |||
| void uiSetCustomData(const char* const key, const char* const value) | |||
| { | |||
| CARLA_ASSERT(uiPtr != nullptr); | |||
| CARLA_ASSERT(fUiPtr != nullptr); | |||
| CARLA_ASSERT(key != nullptr); | |||
| CARLA_ASSERT(value != nullptr); | |||
| if (uiPtr != nullptr) | |||
| uiPtr->carla_setCustomData(key, value); | |||
| if (fUiPtr != nullptr) | |||
| fUiPtr->carla_setCustomData(key, value); | |||
| } | |||
| # endif | |||
| #endif | |||
| @@ -418,14 +431,14 @@ private: | |||
| #if DISTRHO_PLUGIN_HAS_UI | |||
| // UI | |||
| ScopedPointer<UICarla> fUi; | |||
| ScopedPointer<UICarla> fUiPtr; | |||
| void createUiIfNeeded() | |||
| { | |||
| if (fUi == nullptr) | |||
| if (fUiPtr == nullptr) | |||
| { | |||
| d_lastUiSampleRate = getSampleRate(); | |||
| fUi = new UICarla(getHostHandle(), &fPlugin); | |||
| fUiPtr = new UICarla(getHostHandle(), &fPlugin); | |||
| } | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,37 @@ | |||
| /* | |||
| * DISTRHO Notes Plugin | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_PLUGIN_INFO_H__ | |||
| #define __DISTRHO_PLUGIN_INFO_H__ | |||
| #define DISTRHO_PLUGIN_NAME "Notes" | |||
| #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_URI "http://distrho.sf.net/plugins/Notes" | |||
| #define DISTRHO_UI_QT4 | |||
| #endif // __DISTRHO_PLUGIN_INFO_H__ | |||
| @@ -0,0 +1,121 @@ | |||
| /* | |||
| * DISTRHO Notes Plugin | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #include "DistrhoPluginNotes.hpp" | |||
| #include <cmath> | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| DistrhoPluginNotes::DistrhoPluginNotes() | |||
| : Plugin(1, 0, 103) // 1 parameter, 0 programs, 103 states | |||
| { | |||
| fCurPage = 0; | |||
| } | |||
| DistrhoPluginNotes::~DistrhoPluginNotes() | |||
| { | |||
| } | |||
| // ------------------------------------------------- | |||
| // Init | |||
| void DistrhoPluginNotes::d_initParameter(uint32_t index, Parameter& parameter) | |||
| { | |||
| if (index != 0) | |||
| return; | |||
| parameter.hints = PARAMETER_IS_AUTOMABLE | PARAMETER_IS_INTEGER; | |||
| parameter.name = "Page"; | |||
| parameter.symbol = "page"; | |||
| parameter.ranges.def = 1; | |||
| parameter.ranges.min = 1; | |||
| parameter.ranges.max = 100; | |||
| parameter.ranges.step = 1; | |||
| parameter.ranges.stepSmall = 1; | |||
| parameter.ranges.stepLarge = 10; | |||
| } | |||
| void DistrhoPluginNotes::d_initStateKey(uint32_t index, d_string& stateKey) | |||
| { | |||
| switch (index) | |||
| { | |||
| case 0: | |||
| stateKey = "readOnly"; | |||
| break; | |||
| case 1 ... 100: | |||
| stateKey = "pageText #" + d_string(index); | |||
| break; | |||
| case 101: | |||
| stateKey = "guiWidth"; | |||
| break; | |||
| case 102: | |||
| stateKey = "guiHeight"; | |||
| break; | |||
| } | |||
| } | |||
| // ------------------------------------------------- | |||
| // Internal data | |||
| float DistrhoPluginNotes::d_parameterValue(uint32_t index) | |||
| { | |||
| if (index != 0) | |||
| return 0.0f; | |||
| return fCurPage; | |||
| } | |||
| void DistrhoPluginNotes::d_setParameterValue(uint32_t index, float value) | |||
| { | |||
| if (index != 0) | |||
| return; | |||
| fCurPage = int(value); | |||
| } | |||
| void DistrhoPluginNotes::d_setState(const char*, const char*) | |||
| { | |||
| // do nothing, used only for UI state | |||
| } | |||
| // ------------------------------------------------- | |||
| // Process | |||
| void DistrhoPluginNotes::d_run(float** inputs, float** outputs, uint32_t frames, uint32_t, const MidiEvent*) | |||
| { | |||
| float* in1 = inputs[0]; | |||
| float* in2 = inputs[1]; | |||
| float* out1 = outputs[0]; | |||
| float* out2 = outputs[1]; | |||
| std::memcpy(out1, in1, sizeof(float)*frames); | |||
| std::memcpy(out2, in2, sizeof(float)*frames); | |||
| } | |||
| // ------------------------------------------------- | |||
| Plugin* createPlugin() | |||
| { | |||
| return new DistrhoPluginNotes(); | |||
| } | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,86 @@ | |||
| /* | |||
| * DISTRHO Notes Plugin | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_PLUGIN_NOTES_HPP__ | |||
| #define __DISTRHO_PLUGIN_NOTES_HPP__ | |||
| #include "DistrhoPlugin.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| class DistrhoPluginNotes : public Plugin | |||
| { | |||
| public: | |||
| DistrhoPluginNotes(); | |||
| ~DistrhoPluginNotes(); | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| const char* d_label() const | |||
| { | |||
| return "Notes"; | |||
| } | |||
| const char* d_maker() const | |||
| { | |||
| return "DISTRHO"; | |||
| } | |||
| const char* d_license() const | |||
| { | |||
| return "GPL v2+"; | |||
| } | |||
| uint32_t d_version() const | |||
| { | |||
| return 0x1000; | |||
| } | |||
| long d_uniqueId() const | |||
| { | |||
| return d_cconst('D', 'N', 'o', 't'); | |||
| } | |||
| // --------------------------------------------- | |||
| // Init | |||
| void d_initParameter(uint32_t index, Parameter& parameter); | |||
| void d_initStateKey(uint32_t index, d_string& stateKeyName); | |||
| // --------------------------------------------- | |||
| // Internal data | |||
| float d_parameterValue(uint32_t index); | |||
| void d_setParameterValue(uint32_t index, float value); | |||
| void d_setState(const char* key, const char* value); | |||
| // --------------------------------------------- | |||
| // Process | |||
| void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | |||
| // --------------------------------------------- | |||
| private: | |||
| int fCurPage; | |||
| }; | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_PLUGIN_NOTES_HPP__ | |||
| @@ -0,0 +1,222 @@ | |||
| /* | |||
| * DISTRHO Notes Plugin | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #include "DistrhoUINotes.hpp" | |||
| #include <QtGui/QResizeEvent> | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| DistrhoUINotes::DistrhoUINotes() | |||
| : Qt4UI(), | |||
| fCurPage(1), | |||
| fSaveSizeNowChecker(-1), | |||
| fSaveTextNowChecker(-1), | |||
| fTextEdit(this), | |||
| fButton(this), | |||
| fProgressBar(this), | |||
| fSpacer(this), | |||
| fGridLayout(this) | |||
| { | |||
| fButton.setCheckable(true); | |||
| fButton.setChecked(true); | |||
| fButton.setText("Edit"); | |||
| fButton.setFixedSize(fButton.minimumSizeHint()); | |||
| fProgressBar.set_minimum(1); | |||
| fProgressBar.set_maximum(100); | |||
| fProgressBar.set_value(1); | |||
| fSpacer.setText(""); | |||
| fSpacer.setFixedSize(5, 5); | |||
| fTextEdit.setReadOnly(false); | |||
| setLayout(&fGridLayout); | |||
| fGridLayout.addWidget(&fTextEdit, 0, 0, 1, 3); | |||
| fGridLayout.addWidget(&fButton, 1, 0, 1, 1); | |||
| fGridLayout.addWidget(&fProgressBar, 1, 1, 1, 1); | |||
| fGridLayout.addWidget(&fSpacer, 1, 2, 1, 1); | |||
| fGridLayout.setContentsMargins(0, 0, 0, 0); | |||
| connect(&fButton, SIGNAL(clicked(bool)), SLOT(buttonClicked(bool))); | |||
| connect(&fProgressBar, SIGNAL(valueChangedFromBar(float)), SLOT(progressBarValueChanged(float))); | |||
| connect(&fTextEdit, SIGNAL(textChanged()), SLOT(textChanged())); | |||
| setFixedSize(300, 200); | |||
| } | |||
| DistrhoUINotes::~DistrhoUINotes() | |||
| { | |||
| } | |||
| void DistrhoUINotes::saveCurrentTextState() | |||
| { | |||
| QString pageKey = QString("pageText #%1").arg(fCurPage); | |||
| QString pageValue = fTextEdit.toPlainText(); | |||
| if (pageValue != fNotes[fCurPage-1]) | |||
| { | |||
| fNotes[fCurPage-1] = pageValue; | |||
| d_setState(pageKey.toUtf8().constData(), pageValue.toUtf8().constData()); | |||
| } | |||
| } | |||
| // ------------------------------------------------- | |||
| // DSP Callbacks | |||
| void DistrhoUINotes::d_parameterChanged(uint32_t index, float value) | |||
| { | |||
| if (index != 0) | |||
| return; | |||
| int nextCurPage = value; | |||
| if (nextCurPage != fCurPage && nextCurPage >= 1 && nextCurPage <= 100) | |||
| { | |||
| saveCurrentTextState(); | |||
| fCurPage = nextCurPage; | |||
| fTextEdit.setPlainText(fNotes[fCurPage-1]); | |||
| fProgressBar.set_value(fCurPage); | |||
| fProgressBar.update(); | |||
| } | |||
| } | |||
| void DistrhoUINotes::d_stateChanged(const char* key, const char* value) | |||
| { | |||
| if (std::strcmp(key, "guiWidth") == 0) | |||
| { | |||
| bool ok; | |||
| int width = QString(value).toInt(&ok); | |||
| if (ok && width > 0) | |||
| setFixedWidth(width); | |||
| } | |||
| else if (std::strcmp(key, "guiHeight") == 0) | |||
| { | |||
| bool ok; | |||
| int height = QString(value).toInt(&ok); | |||
| if (ok && height > 0) | |||
| setFixedHeight(height); | |||
| } | |||
| else if (std::strncmp(key, "pageText #", 10) == 0) | |||
| { | |||
| bool ok; | |||
| int pageIndex = QString(key+10).toInt(&ok); | |||
| if (ok && pageIndex >= 1 && pageIndex <= 100) | |||
| { | |||
| fNotes[pageIndex-1] = QString(value); | |||
| if (pageIndex == fCurPage) | |||
| fTextEdit.setPlainText(fNotes[pageIndex-1]); | |||
| } | |||
| } | |||
| else if (strcmp(key, "readOnly") == 0) | |||
| { | |||
| bool readOnly = !strcmp(value, "yes"); | |||
| fButton.setChecked(!readOnly); | |||
| fTextEdit.setReadOnly(readOnly); | |||
| } | |||
| } | |||
| // ------------------------------------------------- | |||
| // UI Callbacks | |||
| void DistrhoUINotes::d_uiIdle() | |||
| { | |||
| if (fSaveSizeNowChecker == 11) | |||
| { | |||
| d_setState("guiWidth", QString::number(width()).toUtf8().constData()); | |||
| d_setState("guiHeight", QString::number(height()).toUtf8().constData()); | |||
| fSaveSizeNowChecker = -1; | |||
| } | |||
| if (fSaveTextNowChecker == 11) | |||
| { | |||
| saveCurrentTextState(); | |||
| fSaveTextNowChecker = -1; | |||
| } | |||
| if (fSaveSizeNowChecker >= 0) | |||
| fSaveSizeNowChecker++; | |||
| if (fSaveTextNowChecker >= 0) | |||
| fSaveTextNowChecker++; | |||
| Qt4UI::d_uiIdle(); | |||
| } | |||
| void DistrhoUINotes::resizeEvent(QResizeEvent* event) | |||
| { | |||
| fSaveSizeNowChecker = 0; | |||
| QWidget::resizeEvent(event); | |||
| } | |||
| // ------------------------------------------------- | |||
| void DistrhoUINotes::buttonClicked(bool click) | |||
| { | |||
| bool readOnly = !click; | |||
| fTextEdit.setReadOnly(readOnly); | |||
| d_setState("readOnly", readOnly ? "yes" : "no"); | |||
| } | |||
| void DistrhoUINotes::progressBarValueChanged(float value) | |||
| { | |||
| value = rint(value); | |||
| if (fCurPage == (int)value) | |||
| return; | |||
| // maybe save current text before changing page | |||
| if (fSaveTextNowChecker >= 0 && value >= 1.0f && value <= 100.0f) | |||
| { | |||
| saveCurrentTextState(); | |||
| fSaveTextNowChecker = -1; | |||
| } | |||
| // change current page | |||
| d_parameterChanged(0, value); | |||
| // tell host about this change | |||
| d_setParameterValue(0, value); | |||
| } | |||
| void DistrhoUINotes::textChanged() | |||
| { | |||
| fSaveTextNowChecker = 0; | |||
| } | |||
| // ------------------------------------------------- | |||
| UI* createUI() | |||
| { | |||
| return new DistrhoUINotes; | |||
| } | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,103 @@ | |||
| /* | |||
| * DISTRHO Notes Plugin | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the GPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_UI_NOTES_HPP__ | |||
| #define __DISTRHO_UI_NOTES_HPP__ | |||
| #include "DistrhoUIQt4.hpp" | |||
| #include "ParamProgressBar.hpp" | |||
| #include <QtGui/QGridLayout> | |||
| #include <QtGui/QLabel> | |||
| #include <QtGui/QPushButton> | |||
| #include <QtGui/QTextEdit> | |||
| class QResizeEvent; | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| class DistrhoUINotes : public Qt4UI | |||
| { | |||
| Q_OBJECT | |||
| public: | |||
| DistrhoUINotes(); | |||
| ~DistrhoUINotes(); | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| bool d_resizable() | |||
| { | |||
| return true; | |||
| } | |||
| uint d_minimumWidth() | |||
| { | |||
| return 180; | |||
| } | |||
| uint d_minimumHeight() | |||
| { | |||
| return 150; | |||
| } | |||
| // --------------------------------------------- | |||
| // DSP Callbacks | |||
| void d_parameterChanged(uint32_t index, float value); | |||
| void d_stateChanged(const char* key, const char* value); | |||
| // --------------------------------------------- | |||
| // UI Callbacks | |||
| void d_uiIdle(); | |||
| // --------------------------------------------- | |||
| // listen for resize events | |||
| void resizeEvent(QResizeEvent*); | |||
| private slots: | |||
| void buttonClicked(bool click); | |||
| void progressBarValueChanged(float value); | |||
| void textChanged(); | |||
| private: | |||
| int fCurPage; | |||
| int fSaveSizeNowChecker; | |||
| int fSaveTextNowChecker; | |||
| QString fNotes[100]; | |||
| QTextEdit fTextEdit; | |||
| QPushButton fButton; | |||
| ParamProgressBar fProgressBar; | |||
| QLabel fSpacer; | |||
| QGridLayout fGridLayout; | |||
| void saveCurrentTextState(); | |||
| }; | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_UI_NOTES_HPP__ | |||
| @@ -0,0 +1,118 @@ | |||
| /* | |||
| * Parameter Progress-Bar, a custom Qt4 widget | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #include "ParamProgressBar.h" | |||
| #include <QtGui/QMouseEvent> | |||
| ParamProgressBar::ParamProgressBar(QWidget* parent) | |||
| : QProgressBar(parent) | |||
| { | |||
| m_leftClickDown = false; | |||
| m_minimum = 0.0f; | |||
| m_maximum = 1.0f; | |||
| m_rvalue = 0.0f; | |||
| m_textCall = nullptr; | |||
| setMinimum(0); | |||
| setMaximum(1000); | |||
| setValue(0); | |||
| setFormat("(none)"); | |||
| } | |||
| void ParamProgressBar::set_minimum(float value) | |||
| { | |||
| m_minimum = value; | |||
| } | |||
| void ParamProgressBar::set_maximum(float value) | |||
| { | |||
| m_maximum = value; | |||
| } | |||
| void ParamProgressBar::set_value(float value) | |||
| { | |||
| m_rvalue = value; | |||
| float vper = (value - m_minimum) / (m_maximum - m_minimum); | |||
| setValue(vper * 1000); | |||
| } | |||
| void ParamProgressBar::set_label(QString label) | |||
| { | |||
| m_label = label; | |||
| if (m_label == "(coef)") | |||
| { | |||
| m_label = ""; | |||
| m_preLabel = "*"; | |||
| } | |||
| } | |||
| void ParamProgressBar::set_text_call(TextCallback* textCall) | |||
| { | |||
| m_textCall = textCall; | |||
| } | |||
| void ParamProgressBar::handleMouseEventPos(const QPoint& pos) | |||
| { | |||
| float xper = float(pos.x()) / width(); | |||
| float value = xper * (m_maximum - m_minimum) + m_minimum; | |||
| if (value < m_minimum) | |||
| value = m_minimum; | |||
| else if (value > m_maximum) | |||
| value = m_maximum; | |||
| emit valueChangedFromBar(value); | |||
| } | |||
| void ParamProgressBar::mousePressEvent(QMouseEvent* event) | |||
| { | |||
| if (event->button() == Qt::LeftButton) | |||
| { | |||
| handleMouseEventPos(event->pos()); | |||
| m_leftClickDown = true; | |||
| } | |||
| else | |||
| m_leftClickDown = false; | |||
| QProgressBar::mousePressEvent(event); | |||
| } | |||
| void ParamProgressBar::mouseMoveEvent(QMouseEvent* event) | |||
| { | |||
| if (m_leftClickDown) | |||
| handleMouseEventPos(event->pos()); | |||
| QProgressBar::mouseMoveEvent(event); | |||
| } | |||
| void ParamProgressBar::mouseReleaseEvent(QMouseEvent* event) | |||
| { | |||
| m_leftClickDown = false; | |||
| QProgressBar::mouseReleaseEvent(event); | |||
| } | |||
| void ParamProgressBar::paintEvent(QPaintEvent* event) | |||
| { | |||
| if (m_textCall) | |||
| setFormat(QString("%1 %2 %3").arg(m_preLabel).arg(m_textCall->textCallBack()).arg(m_label)); | |||
| else | |||
| setFormat(QString("%1 %2 %3").arg(m_preLabel).arg(m_rvalue).arg(m_label)); | |||
| QProgressBar::paintEvent(event); | |||
| } | |||
| @@ -0,0 +1,64 @@ | |||
| /* | |||
| * Parameter Progress-Bar, a custom Qt4 widget | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| * the Free Software Foundation; either version 2 of the License, or | |||
| * any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #ifndef PARAMPROGRESSBAR_H | |||
| #define PARAMPROGRESSBAR_H | |||
| #include <QtGui/QProgressBar> | |||
| class TextCallback | |||
| { | |||
| public: | |||
| virtual ~TextCallback(); | |||
| virtual const char* textCallBack() = 0; | |||
| }; | |||
| class ParamProgressBar : public QProgressBar | |||
| { | |||
| Q_OBJECT | |||
| public: | |||
| ParamProgressBar(QWidget* parent); | |||
| void set_minimum(float value); | |||
| void set_maximum(float value); | |||
| void set_value(float value); | |||
| void set_label(QString label); | |||
| void set_text_call(TextCallback* textCall); | |||
| signals: | |||
| void valueChangedFromBar(float value); | |||
| protected: | |||
| void handleMouseEventPos(const QPoint& pos); | |||
| void mousePressEvent(QMouseEvent* event); | |||
| void mouseMoveEvent(QMouseEvent* event); | |||
| void mouseReleaseEvent(QMouseEvent* event); | |||
| void paintEvent(QPaintEvent* event); | |||
| private: | |||
| bool m_leftClickDown; | |||
| float m_minimum; | |||
| float m_maximum; | |||
| float m_rvalue; | |||
| QString m_label; | |||
| QString m_preLabel; | |||
| TextCallback* m_textCall; | |||
| }; | |||
| #endif // #define PARAMPROGRESSBAR_H | |||
| @@ -35,10 +35,10 @@ public: | |||
| DistrhoPluginPingPongPan(); | |||
| ~DistrhoPluginPingPongPan(); | |||
| // --------------------------------------------- | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| const char* d_label() const | |||
| { | |||
| return "PingPongPan"; | |||
| @@ -64,16 +64,22 @@ protected: | |||
| return d_cconst('D', 'P', 'P', 'P'); | |||
| } | |||
| // --------------------------------------------- | |||
| // Init | |||
| void d_initParameter(uint32_t index, Parameter& parameter); | |||
| void d_initProgramName(uint32_t index, d_string& programName); | |||
| // --------------------------------------------- | |||
| // Internal data | |||
| float d_parameterValue(uint32_t index); | |||
| void d_setParameterValue(uint32_t index, float value); | |||
| void d_setProgram(uint32_t index); | |||
| // --------------------------------------------- | |||
| // Process | |||
| void d_activate(); | |||
| void d_deactivate(); | |||
| void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | |||
| @@ -1775,6 +1775,7 @@ private: | |||
| carla_register_native_plugin_3BandEQ(); | |||
| carla_register_native_plugin_3BandSplitter(); | |||
| carla_register_native_plugin_PingPongPan(); | |||
| carla_register_native_plugin_Notes(); | |||
| # ifdef WANT_AUDIOFILE | |||
| carla_register_native_plugin_audiofile(); | |||
| @@ -0,0 +1,219 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_PLUGIN_HPP__ | |||
| #define __DISTRHO_PLUGIN_HPP__ | |||
| #include "DistrhoUtils.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| // Parameter Hints | |||
| const uint32_t PARAMETER_IS_AUTOMABLE = 1 << 0; | |||
| const uint32_t PARAMETER_IS_BOOLEAN = 1 << 1; | |||
| const uint32_t PARAMETER_IS_INTEGER = 1 << 2; | |||
| const uint32_t PARAMETER_IS_LOGARITHMIC = 1 << 3; | |||
| const uint32_t PARAMETER_IS_OUTPUT = 1 << 4; | |||
| // ------------------------------------------------- | |||
| // Parameter Ranges | |||
| struct ParameterRanges { | |||
| float def; | |||
| float min; | |||
| float max; | |||
| float step; | |||
| float stepSmall; | |||
| float stepLarge; | |||
| ParameterRanges() | |||
| : def(0.0f), | |||
| min(0.0f), | |||
| max(1.0f), | |||
| step(0.001f), | |||
| stepSmall(0.00001f), | |||
| stepLarge(0.01f) {} | |||
| ParameterRanges(float def, float min, float max) | |||
| : step(0.001f), | |||
| stepSmall(0.00001f), | |||
| stepLarge(0.01f) | |||
| { | |||
| this->def = def; | |||
| this->min = min; | |||
| this->max = max; | |||
| } | |||
| ParameterRanges(float def, float min, float max, float step, float stepSmall, float stepLarge) | |||
| { | |||
| this->def = def; | |||
| this->min = min; | |||
| this->max = max; | |||
| this->step = step; | |||
| this->stepSmall = stepSmall; | |||
| this->stepLarge = stepLarge; | |||
| } | |||
| void fixValue(float& value) const | |||
| { | |||
| if (value < min) | |||
| value = min; | |||
| else if (value > max) | |||
| value = max; | |||
| } | |||
| float normalizeValue(const float& value) const | |||
| { | |||
| return (value - min) / (max - min); | |||
| } | |||
| float unnormalizeValue(const float& value) const | |||
| { | |||
| return value * (max - min) + min; | |||
| } | |||
| }; | |||
| // ------------------------------------------------- | |||
| // Parameter | |||
| struct Parameter { | |||
| uint32_t hints; | |||
| d_string name; | |||
| d_string symbol; | |||
| d_string unit; | |||
| ParameterRanges ranges; | |||
| Parameter() | |||
| : hints(0x0) {} | |||
| }; | |||
| // ------------------------------------------------- | |||
| // MidiEvent | |||
| struct MidiEvent { | |||
| uint32_t frame; | |||
| uint8_t buffer[3]; | |||
| MidiEvent() | |||
| { | |||
| clear(); | |||
| } | |||
| void clear() | |||
| { | |||
| frame = 0; | |||
| buffer[0] = 0; | |||
| buffer[1] = 0; | |||
| buffer[2] = 0; | |||
| } | |||
| }; | |||
| // ------------------------------------------------- | |||
| // TimePos | |||
| struct TimePos { | |||
| double bpm; | |||
| TimePos() | |||
| : bpm(120.0) {} | |||
| }; | |||
| // ------------------------------------------------- | |||
| // Plugin | |||
| struct PluginPrivateData; | |||
| class Plugin | |||
| { | |||
| public: | |||
| Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCount); | |||
| virtual ~Plugin(); | |||
| // --------------------------------------------- | |||
| // Host state | |||
| uint32_t d_bufferSize() const; | |||
| double d_sampleRate() const; | |||
| const TimePos& d_timePos() const; | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| void d_setLatency(uint32_t frames); | |||
| #endif | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| virtual const char* d_name() const { return DISTRHO_PLUGIN_NAME; } | |||
| virtual const char* d_label() const = 0; | |||
| virtual const char* d_maker() const = 0; | |||
| virtual const char* d_license() const = 0; | |||
| virtual uint32_t d_version() const = 0; | |||
| virtual long d_uniqueId() const = 0; | |||
| // --------------------------------------------- | |||
| // Init | |||
| virtual void d_initParameter(uint32_t index, Parameter& parameter) = 0; | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| virtual void d_initProgramName(uint32_t index, d_string& programName) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| virtual void d_initStateKey(uint32_t index, d_string& stateKey) = 0; | |||
| #endif | |||
| // --------------------------------------------- | |||
| // Internal data | |||
| virtual float d_parameterValue(uint32_t index) = 0; | |||
| virtual void d_setParameterValue(uint32_t index, float value) = 0; | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| virtual void d_setProgram(uint32_t index) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| virtual void d_setState(const char* key, const char* value) = 0; | |||
| #endif | |||
| // --------------------------------------------- | |||
| // Process | |||
| virtual void d_activate() {} | |||
| virtual void d_deactivate() {} | |||
| virtual void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents) = 0; | |||
| // --------------------------------------------- | |||
| // Callbacks (optional) | |||
| virtual void d_bufferSizeChanged(uint32_t newBufferSize); | |||
| virtual void d_sampleRateChanged(double newSampleRate); | |||
| // --------------------------------------------- | |||
| private: | |||
| PluginPrivateData* const pData; | |||
| friend class PluginInternal; | |||
| }; | |||
| // ------------------------------------------------- | |||
| Plugin* createPlugin(); | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_PLUGIN_HPP__ | |||
| @@ -0,0 +1,27 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #include "src/DistrhoPlugin.cpp" | |||
| #if defined(DISTRHO_PLUGIN_TARGET_JACK) | |||
| # include "src/DistrhoPluginJACK.cpp" | |||
| #elif defined(DISTRHO_PLUGIN_TARGET_LADSPA) || defined(DISTRHO_PLUGIN_TARGET_DSSI) | |||
| # include "src/DistrhoPluginLADSPA+DSSI.cpp" | |||
| #elif defined(DISTRHO_PLUGIN_TARGET_LV2) | |||
| # include "src/DistrhoPluginLV2.cpp" | |||
| #elif defined(DISTRHO_PLUGIN_TARGET_VST) | |||
| # include "src/DistrhoPluginVST.cpp" | |||
| #endif | |||
| @@ -0,0 +1,100 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_UI_HPP__ | |||
| #define __DISTRHO_UI_HPP__ | |||
| #include "DistrhoUtils.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| // UI | |||
| struct UIPrivateData; | |||
| class UI | |||
| { | |||
| public: | |||
| UI(); | |||
| virtual ~UI(); | |||
| // --------------------------------------------- | |||
| // Host DSP State | |||
| double d_sampleRate() const; | |||
| void d_editParameter(uint32_t index, bool started); | |||
| void d_setParameterValue(uint32_t index, float value); | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| void d_setState(const char* key, const char* value); | |||
| #endif | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| void d_sendNote(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity); | |||
| #endif | |||
| // --------------------------------------------- | |||
| // Host UI State | |||
| void d_uiResize(unsigned int width, unsigned int height); | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| virtual const char* d_name() const { return DISTRHO_PLUGIN_NAME; } | |||
| virtual unsigned int d_width() const = 0; | |||
| virtual unsigned int d_height() const = 0; | |||
| // --------------------------------------------- | |||
| // DSP Callbacks | |||
| virtual void d_parameterChanged(uint32_t index, float value) = 0; | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| virtual void d_programChanged(uint32_t index) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| virtual void d_stateChanged(const char* key, const char* value) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| virtual void d_noteReceived(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) = 0; | |||
| #endif | |||
| // --------------------------------------------- | |||
| // UI Callbacks | |||
| virtual void d_uiIdle() = 0; | |||
| // --------------------------------------------- | |||
| private: | |||
| UIPrivateData* const pData; | |||
| friend class UIInternal; | |||
| #ifdef DISTRHO_UI_QT4 | |||
| friend class Qt4UI; | |||
| #else | |||
| friend class OpenGLUI; | |||
| #endif | |||
| }; | |||
| // ------------------------------------------------- | |||
| UI* createUI(); | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_UI_HPP__ | |||
| @@ -0,0 +1,33 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #include "src/DistrhoUI.cpp" | |||
| #if defined(DISTRHO_PLUGIN_TARGET_JACK) | |||
| // nothing | |||
| #elif defined(DISTRHO_PLUGIN_TARGET_DSSI) | |||
| # include "src/DistrhoUIDSSI.cpp" | |||
| #elif defined(DISTRHO_PLUGIN_TARGET_LV2) | |||
| # include "src/DistrhoUILV2.cpp" | |||
| #elif defined(DISTRHO_PLUGIN_TARGET_VST) | |||
| // nothing | |||
| #endif | |||
| #ifdef DISTRHO_UI_QT4 | |||
| # include "src/DistrhoUIQt4.cpp" | |||
| #else | |||
| # include "src/DistrhoUIOpenGL.cpp" | |||
| #endif | |||
| @@ -0,0 +1,78 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_UI_QT4_HPP__ | |||
| #define __DISTRHO_UI_QT4_HPP__ | |||
| #include "DistrhoUI.hpp" | |||
| #include <QtGui/QWidget> | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| // Qt4 UI | |||
| class Qt4UI : public UI, | |||
| public QWidget | |||
| { | |||
| public: | |||
| Qt4UI(); | |||
| virtual ~Qt4UI(); | |||
| protected: | |||
| // --------------------------------------------- | |||
| // Information | |||
| virtual bool d_resizable() { return false; } | |||
| virtual uint d_minimumWidth() { return 100; } | |||
| virtual uint d_minimumHeight() { return 100; } | |||
| // --------------------------------------------- | |||
| // DSP Callbacks | |||
| virtual void d_parameterChanged(uint32_t index, float value) = 0; | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| virtual void d_programChanged(uint32_t index) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| virtual void d_stateChanged(const char* key, const char* value) = 0; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| virtual void d_noteReceived(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) = 0; | |||
| #endif | |||
| // --------------------------------------------- | |||
| // UI Callbacks | |||
| virtual void d_uiIdle(); | |||
| private: | |||
| friend class UIInternal; | |||
| // --------------------------------------------- | |||
| // Implement resize internally | |||
| void d_uiResize(unsigned int width, unsigned int height); | |||
| unsigned int d_width() const { return width(); } | |||
| unsigned int d_height() const { return height(); } | |||
| }; | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_UI_QT4_HPP__ | |||
| @@ -0,0 +1,500 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_UTILS_HPP__ | |||
| #define __DISTRHO_UTILS_HPP__ | |||
| #include "src/DistrhoDefines.h" | |||
| #include <cassert> | |||
| #include <cstdio> | |||
| #include <cstdlib> | |||
| #include <cstring> | |||
| #ifdef DISTRHO_OS_WINDOWS | |||
| # include <windows.h> | |||
| #else | |||
| # include <unistd.h> | |||
| #endif | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| static inline | |||
| long d_cconst(int a, int b, int c, int d) | |||
| { | |||
| return (a << 24) | (b << 16) | (c << 8) | (d << 0); | |||
| } | |||
| // ------------------------------------------------- | |||
| static inline | |||
| void d_sleep(unsigned int secs) | |||
| { | |||
| #ifdef DISTRHO_OS_WINDOWS | |||
| Sleep(secs * 1000); | |||
| #else | |||
| sleep(secs); | |||
| #endif | |||
| } | |||
| static inline | |||
| void d_msleep(unsigned int msecs) | |||
| { | |||
| #ifdef DISTRHO_OS_WINDOWS | |||
| Sleep(msecs); | |||
| #else | |||
| usleep(msecs * 1000); | |||
| #endif | |||
| } | |||
| static inline | |||
| void d_usleep(unsigned int usecs) | |||
| { | |||
| #ifdef DISTRHO_OS_WINDOWS | |||
| Sleep(usecs / 1000); | |||
| #else | |||
| usleep(usecs); | |||
| #endif | |||
| } | |||
| // ------------------------------------------------- | |||
| static inline | |||
| void d_setenv(const char* key, const char* value) | |||
| { | |||
| #if DISTRHO_OS_WINDOWS | |||
| SetEnvironmentVariableA(key, value); | |||
| #else | |||
| setenv(key, value, 1); | |||
| #endif | |||
| } | |||
| // ------------------------------------------------- | |||
| class d_string | |||
| { | |||
| public: | |||
| // --------------------------------------------- | |||
| // constructors (no explicit conversions allowed) | |||
| explicit d_string() | |||
| { | |||
| _init(); | |||
| _dup(nullptr); | |||
| } | |||
| explicit d_string(char* const strBuf) | |||
| { | |||
| _init(); | |||
| _dup(strBuf); | |||
| } | |||
| explicit d_string(const char* const strBuf) | |||
| { | |||
| _init(); | |||
| _dup(strBuf); | |||
| } | |||
| explicit d_string(const int value) | |||
| { | |||
| const size_t strBufSize = std::abs(value/10) + 3; | |||
| char strBuf[strBufSize]; | |||
| std::snprintf(strBuf, strBufSize, "%d", value); | |||
| _init(); | |||
| _dup(strBuf, strBufSize); | |||
| } | |||
| explicit d_string(const unsigned int value, const bool hexadecimal = false) | |||
| { | |||
| const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0); | |||
| char strBuf[strBufSize]; | |||
| std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%x" : "%u", value); | |||
| _init(); | |||
| _dup(strBuf, strBufSize); | |||
| } | |||
| explicit d_string(const long int value) | |||
| { | |||
| const size_t strBufSize = std::abs(value/10) + 3; | |||
| char strBuf[strBufSize]; | |||
| std::snprintf(strBuf, strBufSize, "%ld", value); | |||
| _init(); | |||
| _dup(strBuf, strBufSize); | |||
| } | |||
| explicit d_string(const unsigned long int value, const bool hexadecimal = false) | |||
| { | |||
| const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0); | |||
| char strBuf[strBufSize]; | |||
| std::snprintf(strBuf, strBufSize, hexadecimal ? "0x%lx" : "%lu", value); | |||
| _init(); | |||
| _dup(strBuf, strBufSize); | |||
| } | |||
| explicit d_string(const float value) | |||
| { | |||
| char strBuf[0xff]; | |||
| std::snprintf(strBuf, 0xff, "%f", value); | |||
| _init(); | |||
| _dup(strBuf); | |||
| } | |||
| explicit d_string(const double value) | |||
| { | |||
| char strBuf[0xff]; | |||
| std::snprintf(strBuf, 0xff, "%g", value); | |||
| _init(); | |||
| _dup(strBuf); | |||
| } | |||
| // --------------------------------------------- | |||
| // non-explicit constructor | |||
| d_string(const d_string& str) | |||
| { | |||
| _init(); | |||
| _dup(str.buffer); | |||
| } | |||
| // --------------------------------------------- | |||
| // deconstructor | |||
| ~d_string() | |||
| { | |||
| assert(buffer != nullptr); | |||
| delete[] buffer; | |||
| } | |||
| // --------------------------------------------- | |||
| // public methods | |||
| size_t length() const | |||
| { | |||
| return bufferLen; | |||
| } | |||
| bool isEmpty() const | |||
| { | |||
| return (bufferLen == 0); | |||
| } | |||
| bool isNotEmpty() const | |||
| { | |||
| return (bufferLen != 0); | |||
| } | |||
| #if __USE_GNU | |||
| bool contains(const char* const strBuf, const bool ignoreCase = false) const | |||
| { | |||
| if (strBuf == nullptr) | |||
| return false; | |||
| if (ignoreCase) | |||
| return (strcasestr(buffer, strBuf) != nullptr); | |||
| else | |||
| return (std::strstr(buffer, strBuf) != nullptr); | |||
| } | |||
| bool contains(const d_string& str, const bool ignoreCase = false) const | |||
| { | |||
| return contains(str.buffer, ignoreCase); | |||
| } | |||
| #else | |||
| bool contains(const char* const strBuf) const | |||
| { | |||
| if (strBuf == nullptr) | |||
| return false; | |||
| return (std::strstr(buffer, strBuf) != nullptr); | |||
| } | |||
| bool contains(const d_string& str) const | |||
| { | |||
| return contains(str.buffer); | |||
| } | |||
| #endif | |||
| bool isDigit(const size_t pos) const | |||
| { | |||
| if (pos >= bufferLen) | |||
| return false; | |||
| return (buffer[pos] >= '0' && buffer[pos] <= '9'); | |||
| } | |||
| void clear() | |||
| { | |||
| truncate(0); | |||
| } | |||
| size_t find(const char c) | |||
| { | |||
| for (size_t i=0; i < bufferLen; i++) | |||
| { | |||
| if (buffer[i] == c) | |||
| return i; | |||
| } | |||
| return 0; | |||
| } | |||
| size_t rfind(const char c) | |||
| { | |||
| size_t pos = 0; | |||
| for (size_t i=0; i < bufferLen; i++) | |||
| { | |||
| if (buffer[i] == c) | |||
| pos = i; | |||
| } | |||
| return pos; | |||
| } | |||
| void replace(const char before, const char after) | |||
| { | |||
| if (after == '\0') | |||
| return; | |||
| for (size_t i=0; i < bufferLen; i++) | |||
| { | |||
| if (buffer[i] == before) | |||
| buffer[i] = after; | |||
| else if (buffer[i] == '\0') | |||
| break; | |||
| } | |||
| } | |||
| void truncate(const size_t n) | |||
| { | |||
| if (n >= bufferLen) | |||
| return; | |||
| for (size_t i=n; i < bufferLen; i++) | |||
| buffer[i] = '\0'; | |||
| bufferLen = n; | |||
| } | |||
| void toBasic() | |||
| { | |||
| for (size_t i=0; i < bufferLen; i++) | |||
| { | |||
| if (buffer[i] >= '0' && buffer[i] <= '9') | |||
| continue; | |||
| if (buffer[i] >= 'A' && buffer[i] <= 'Z') | |||
| continue; | |||
| if (buffer[i] >= 'a' && buffer[i] <= 'z') | |||
| continue; | |||
| if (buffer[i] == '_') | |||
| continue; | |||
| buffer[i] = '_'; | |||
| } | |||
| } | |||
| void toLower() | |||
| { | |||
| static const char charDiff = 'a' - 'A'; | |||
| for (size_t i=0; i < bufferLen; i++) | |||
| { | |||
| if (buffer[i] >= 'A' && buffer[i] <= 'Z') | |||
| buffer[i] += charDiff; | |||
| } | |||
| } | |||
| void toUpper() | |||
| { | |||
| static const char charDiff = 'a' - 'A'; | |||
| for (size_t i=0; i < bufferLen; i++) | |||
| { | |||
| if (buffer[i] >= 'a' && buffer[i] <= 'z') | |||
| buffer[i] -= charDiff; | |||
| } | |||
| } | |||
| // --------------------------------------------- | |||
| // public operators | |||
| operator const char*() const | |||
| { | |||
| return buffer; | |||
| } | |||
| char& operator[](const size_t pos) | |||
| { | |||
| return buffer[pos]; | |||
| } | |||
| bool operator==(const char* const strBuf) const | |||
| { | |||
| return (strBuf != nullptr && std::strcmp(buffer, strBuf) == 0); | |||
| } | |||
| bool operator==(const d_string& str) const | |||
| { | |||
| return operator==(str.buffer); | |||
| } | |||
| bool operator!=(const char* const strBuf) const | |||
| { | |||
| return !operator==(strBuf); | |||
| } | |||
| bool operator!=(const d_string& str) const | |||
| { | |||
| return !operator==(str.buffer); | |||
| } | |||
| d_string& operator=(const char* const strBuf) | |||
| { | |||
| _dup(strBuf); | |||
| return *this; | |||
| } | |||
| d_string& operator=(const d_string& str) | |||
| { | |||
| return operator=(str.buffer); | |||
| } | |||
| d_string& operator+=(const char* const strBuf) | |||
| { | |||
| const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1; | |||
| char newBuf[newBufSize]; | |||
| std::strcpy(newBuf, buffer); | |||
| std::strcat(newBuf, strBuf); | |||
| _dup(newBuf, newBufSize-1); | |||
| return *this; | |||
| } | |||
| d_string& operator+=(const d_string& str) | |||
| { | |||
| return operator+=(str.buffer); | |||
| } | |||
| d_string operator+(const char* const strBuf) | |||
| { | |||
| const size_t newBufSize = bufferLen + ((strBuf != nullptr) ? std::strlen(strBuf) : 0) + 1; | |||
| char newBuf[newBufSize]; | |||
| std::strcpy(newBuf, buffer); | |||
| std::strcat(newBuf, strBuf); | |||
| return d_string(newBuf); | |||
| } | |||
| d_string operator+(const d_string& str) | |||
| { | |||
| return operator+(str.buffer); | |||
| } | |||
| // --------------------------------------------- | |||
| private: | |||
| char* buffer; | |||
| size_t bufferLen; | |||
| bool firstInit; | |||
| void _init() | |||
| { | |||
| buffer = nullptr; | |||
| bufferLen = 0; | |||
| firstInit = true; | |||
| } | |||
| // allocate string strBuf if not null | |||
| // size > 0 only if strBuf is valid | |||
| void _dup(const char* const strBuf, const size_t size = 0) | |||
| { | |||
| if (strBuf != nullptr) | |||
| { | |||
| // don't recreate string if contents match | |||
| if (firstInit || std::strcmp(buffer, strBuf) != 0) | |||
| { | |||
| if (! firstInit) | |||
| { | |||
| assert(buffer != nullptr); | |||
| delete[] buffer; | |||
| } | |||
| bufferLen = (size > 0) ? size : std::strlen(strBuf); | |||
| buffer = new char[bufferLen+1]; | |||
| std::strcpy(buffer, strBuf); | |||
| buffer[bufferLen] = '\0'; | |||
| firstInit = false; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| assert(size == 0); | |||
| // don't recreate null string | |||
| if (firstInit || bufferLen != 0) | |||
| { | |||
| if (! firstInit) | |||
| { | |||
| assert(buffer != nullptr); | |||
| delete[] buffer; | |||
| } | |||
| bufferLen = 0; | |||
| buffer = new char[1]; | |||
| buffer[0] = '\0'; | |||
| firstInit = false; | |||
| } | |||
| } | |||
| } | |||
| }; | |||
| // ------------------------------------------------- | |||
| static inline | |||
| d_string operator+(const char* const strBufBefore, const d_string& strAfter) | |||
| { | |||
| const char* const strBufAfter = (const char*)strAfter; | |||
| const size_t newBufSize = ((strBufBefore != nullptr) ? std::strlen(strBufBefore) : 0) + strAfter.length() + 1; | |||
| char newBuf[newBufSize]; | |||
| std::strcpy(newBuf, strBufBefore); | |||
| std::strcat(newBuf, strBufAfter); | |||
| return d_string(newBuf); | |||
| } | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __UTILS_HPP__ | |||
| @@ -0,0 +1,95 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_DEFINES_H__ | |||
| #define __DISTRHO_DEFINES_H__ | |||
| #include "DistrhoPluginInfo.h" | |||
| #ifndef DISTRHO_PLUGIN_NAME | |||
| # error DISTRHO_PLUGIN_NAME undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_HAS_UI | |||
| # error DISTRHO_PLUGIN_HAS_UI undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_IS_SYNTH | |||
| # error DISTRHO_PLUGIN_IS_SYNTH undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_NUM_INPUTS | |||
| # error DISTRHO_PLUGIN_NUM_INPUTS undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_NUM_OUTPUTS | |||
| # error DISTRHO_PLUGIN_NUM_OUTPUTS undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_WANT_LATENCY | |||
| # error DISTRHO_PLUGIN_WANT_LATENCY undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| # error DISTRHO_PLUGIN_WANT_PROGRAMS undefined! | |||
| #endif | |||
| #ifndef DISTRHO_PLUGIN_WANT_STATE | |||
| # error DISTRHO_PLUGIN_WANT_STATE undefined! | |||
| #endif | |||
| #if defined(__WIN32__) || defined(__WIN64__) | |||
| # define DISTRHO_PLUGIN_EXPORT extern "C" __declspec (dllexport) | |||
| # define DISTRHO_OS_WINDOWS 1 | |||
| # define DISTRHO_DLL_EXTENSION "dll" | |||
| #else | |||
| # define DISTRHO_PLUGIN_EXPORT extern "C" __attribute__ ((visibility("default"))) | |||
| # if defined(__APPLE__) | |||
| # define DISTRHO_OS_MAC 1 | |||
| # define DISTRHO_DLL_EXTENSION "dylib" | |||
| # elif defined(__HAIKU__) | |||
| # define DISTRHO_OS_HAIKU 1 | |||
| # define DISTRHO_DLL_EXTENSION "so" | |||
| # elif defined(__linux__) | |||
| # define DISTRHO_OS_LINUX 1 | |||
| # define DISTRHO_DLL_EXTENSION "so" | |||
| # endif | |||
| #endif | |||
| #ifndef DISTRHO_DLL_EXTENSION | |||
| # define DISTRHO_DLL_EXTENSION "so" | |||
| #endif | |||
| #ifndef DISTRHO_NO_NAMESPACE | |||
| # ifndef DISTRHO_NAMESPACE | |||
| # define DISTRHO_NAMESPACE DISTRHO | |||
| # endif | |||
| # define START_NAMESPACE_DISTRHO namespace DISTRHO_NAMESPACE { | |||
| # define END_NAMESPACE_DISTRHO } | |||
| # define USE_NAMESPACE_DISTRHO using namespace DISTRHO_NAMESPACE; | |||
| #else | |||
| # define START_NAMESPACE_DISTRHO | |||
| # define END_NAMESPACE_DISTRHO | |||
| # define USE_NAMESPACE_DISTRHO | |||
| #endif | |||
| #ifndef DISTRHO_UI_QT4 | |||
| # define DISTRHO_UI_OPENGL | |||
| #endif | |||
| #define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" | |||
| #endif // __DISTRHO_DEFINES_H__ | |||
| @@ -0,0 +1,105 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #include "DistrhoPluginInternal.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| // Static data | |||
| uint32_t d_lastBufferSize = 0; | |||
| double d_lastSampleRate = 0.0; | |||
| // ------------------------------------------------- | |||
| // Static, fallback data | |||
| const d_string PluginInternal::sFallbackString; | |||
| const ParameterRanges PluginInternal::sFallbackRanges; | |||
| // ------------------------------------------------- | |||
| // Plugin | |||
| Plugin::Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCount) | |||
| : pData(new PluginPrivateData) | |||
| { | |||
| if (parameterCount > 0) | |||
| { | |||
| pData->parameterCount = parameterCount; | |||
| pData->parameters = new Parameter[parameterCount]; | |||
| } | |||
| if (programCount > 0) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| pData->programCount = programCount; | |||
| pData->programNames = new d_string[programCount]; | |||
| #endif | |||
| } | |||
| if (stateCount > 0) | |||
| { | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| pData->stateCount = stateCount; | |||
| pData->stateKeys = new d_string[stateCount]; | |||
| #endif | |||
| } | |||
| } | |||
| Plugin::~Plugin() | |||
| { | |||
| delete pData; | |||
| } | |||
| // ------------------------------------------------- | |||
| // Host state | |||
| uint32_t Plugin::d_bufferSize() const | |||
| { | |||
| return pData->bufferSize; | |||
| } | |||
| double Plugin::d_sampleRate() const | |||
| { | |||
| return pData->sampleRate; | |||
| } | |||
| const TimePos& Plugin::d_timePos() const | |||
| { | |||
| return pData->timePos; | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| void Plugin::d_setLatency(uint32_t frames) | |||
| { | |||
| pData->latency = frames; | |||
| } | |||
| #endif | |||
| // ------------------------------------------------- | |||
| // Callbacks | |||
| void Plugin::d_bufferSizeChanged(uint32_t) | |||
| { | |||
| } | |||
| void Plugin::d_sampleRateChanged(double) | |||
| { | |||
| } | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,358 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_PLUGIN_INTERNAL_HPP__ | |||
| #define __DISTRHO_PLUGIN_INTERNAL_HPP__ | |||
| #include "../DistrhoPlugin.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| #define MAX_MIDI_EVENTS 512 | |||
| extern uint32_t d_lastBufferSize; | |||
| extern double d_lastSampleRate; | |||
| struct PluginPrivateData { | |||
| uint32_t bufferSize; | |||
| double sampleRate; | |||
| uint32_t parameterCount; | |||
| Parameter* parameters; | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| uint32_t programCount; | |||
| d_string* programNames; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| uint32_t stateCount; | |||
| d_string* stateKeys; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| uint32_t latency; | |||
| #endif | |||
| TimePos timePos; | |||
| PluginPrivateData() | |||
| : bufferSize(d_lastBufferSize), | |||
| sampleRate(d_lastSampleRate), | |||
| parameterCount(0), | |||
| parameters(nullptr), | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| programCount(0), | |||
| programNames(nullptr), | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| stateCount(0), | |||
| stateKeys(nullptr), | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| latency(0), | |||
| #endif | |||
| timePos() | |||
| { | |||
| assert(d_lastBufferSize != 0); | |||
| assert(d_lastSampleRate != 0.0); | |||
| } | |||
| ~PluginPrivateData() | |||
| { | |||
| if (parameterCount > 0 && parameters != nullptr) | |||
| delete[] parameters; | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| if (programCount > 0 && programNames != nullptr) | |||
| delete[] programNames; | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| if (stateCount > 0 && stateKeys != nullptr) | |||
| delete[] stateKeys; | |||
| #endif | |||
| } | |||
| }; | |||
| // ------------------------------------------------- | |||
| class PluginInternal | |||
| { | |||
| public: | |||
| PluginInternal() | |||
| : kPlugin(createPlugin()), | |||
| kData((kPlugin != nullptr) ? kPlugin->pData : nullptr) | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| if (kPlugin == nullptr) | |||
| return; | |||
| for (uint32_t i=0, count=kData->parameterCount; i < count; i++) | |||
| kPlugin->d_initParameter(i, kData->parameters[i]); | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| for (uint32_t i=0, count=kData->programCount; i < count; i++) | |||
| kPlugin->d_initProgramName(i, kData->programNames[i]); | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| for (uint32_t i=0, count=kData->stateCount; i < count; i++) | |||
| kPlugin->d_initStateKey(i, kData->stateKeys[i]); | |||
| #endif | |||
| } | |||
| ~PluginInternal() | |||
| { | |||
| if (kPlugin != nullptr) | |||
| delete kPlugin; | |||
| } | |||
| // --------------------------------------------- | |||
| const char* name() const | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| return (kPlugin != nullptr) ? kPlugin->d_name() : ""; | |||
| } | |||
| const char* label() const | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| return (kPlugin != nullptr) ? kPlugin->d_label() : ""; | |||
| } | |||
| const char* maker() const | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| return (kPlugin != nullptr) ? kPlugin->d_maker() : ""; | |||
| } | |||
| const char* license() const | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| return (kPlugin != nullptr) ? kPlugin->d_license() : ""; | |||
| } | |||
| uint32_t version() const | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| return (kPlugin != nullptr) ? kPlugin->d_version() : 1000; | |||
| } | |||
| long uniqueId() const | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| return (kPlugin != nullptr) ? kPlugin->d_uniqueId() : 0; | |||
| } | |||
| // --------------------------------------------- | |||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||
| uint32_t latency() const | |||
| { | |||
| assert(kData != nullptr); | |||
| return (kData != nullptr) ? kData->latency : 0; | |||
| } | |||
| #endif | |||
| uint32_t parameterCount() const | |||
| { | |||
| assert(kData != nullptr); | |||
| return (kData != nullptr) ? kData->parameterCount : 0; | |||
| } | |||
| uint32_t parameterHints(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->parameterCount); | |||
| return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].hints : 0x0; | |||
| } | |||
| bool parameterIsOutput(uint32_t index) const | |||
| { | |||
| uint32_t hints = parameterHints(index); | |||
| return (hints & PARAMETER_IS_OUTPUT); | |||
| } | |||
| const d_string& parameterName(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->parameterCount); | |||
| return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].name : sFallbackString; | |||
| } | |||
| const d_string& parameterSymbol(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->parameterCount); | |||
| return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].symbol : sFallbackString; | |||
| } | |||
| const d_string& parameterUnit(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->parameterCount); | |||
| return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].unit : sFallbackString; | |||
| } | |||
| const ParameterRanges& parameterRanges(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->parameterCount); | |||
| return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].ranges : sFallbackRanges; | |||
| } | |||
| float parameterValue(uint32_t index) | |||
| { | |||
| assert(kPlugin != nullptr && index < kData->parameterCount); | |||
| return (kPlugin != nullptr && index < kData->parameterCount) ? kPlugin->d_parameterValue(index) : 0.0f; | |||
| } | |||
| void setParameterValue(uint32_t index, float value) | |||
| { | |||
| assert(kPlugin != nullptr && index < kData->parameterCount); | |||
| if (kPlugin != nullptr && index < kData->parameterCount) | |||
| kPlugin->d_setParameterValue(index, value); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| uint32_t programCount() const | |||
| { | |||
| assert(kData != nullptr); | |||
| return (kData != nullptr) ? kData->programCount : 0; | |||
| } | |||
| const d_string& programName(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->programCount); | |||
| return (kData != nullptr && index < kData->programCount) ? kData->programNames[index] : sFallbackString; | |||
| } | |||
| void setProgram(uint32_t index) | |||
| { | |||
| assert(kPlugin != nullptr && index < kData->programCount); | |||
| if (kPlugin != nullptr && index < kData->programCount) | |||
| kPlugin->d_setProgram(index); | |||
| } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| uint32_t stateCount() const | |||
| { | |||
| assert(kData != nullptr); | |||
| return kData != nullptr ? kData->stateCount : 0; | |||
| } | |||
| const d_string& stateKey(uint32_t index) const | |||
| { | |||
| assert(kData != nullptr && index < kData->stateCount); | |||
| return (kData != nullptr && index < kData->stateCount) ? kData->stateKeys[index] : sFallbackString; | |||
| } | |||
| void setState(const char* key, const char* value) | |||
| { | |||
| assert(kPlugin && key && value); | |||
| if (kPlugin && key && value) | |||
| kPlugin->d_setState(key, value); | |||
| } | |||
| #endif | |||
| // --------------------------------------------- | |||
| void activate() | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| if (kPlugin != nullptr) | |||
| kPlugin->d_activate(); | |||
| } | |||
| void deactivate() | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| if (kPlugin != nullptr) | |||
| kPlugin->d_deactivate(); | |||
| } | |||
| void run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents) | |||
| { | |||
| assert(kPlugin != nullptr); | |||
| if (kPlugin != nullptr) | |||
| kPlugin->d_run(inputs, outputs, frames, midiEventCount, midiEvents); | |||
| } | |||
| // --------------------------------------------- | |||
| void setBufferSize(uint32_t bufferSize, bool callback = false) | |||
| { | |||
| assert(kData != nullptr && kPlugin && bufferSize >= 2); | |||
| if (kData != nullptr) | |||
| { | |||
| if (callback && kData->bufferSize == bufferSize) | |||
| callback = false; | |||
| kData->bufferSize = bufferSize; | |||
| } | |||
| if (kPlugin != nullptr && callback) | |||
| { | |||
| kPlugin->d_deactivate(); | |||
| kPlugin->d_bufferSizeChanged(bufferSize); | |||
| kPlugin->d_activate(); | |||
| } | |||
| } | |||
| void setSampleRate(double sampleRate, bool callback = false) | |||
| { | |||
| assert(kData != nullptr && kPlugin != nullptr && sampleRate > 0.0); | |||
| if (kData != nullptr) | |||
| { | |||
| if (callback && kData->sampleRate == sampleRate) | |||
| callback = false; | |||
| kData->sampleRate = sampleRate; | |||
| } | |||
| if (kPlugin != nullptr && callback) | |||
| { | |||
| kPlugin->d_deactivate(); | |||
| kPlugin->d_sampleRateChanged(sampleRate); | |||
| kPlugin->d_activate(); | |||
| } | |||
| } | |||
| // --------------------------------------------- | |||
| protected: | |||
| Plugin* const kPlugin; | |||
| PluginPrivateData* const kData; | |||
| private: | |||
| static const d_string sFallbackString; | |||
| static const ParameterRanges sFallbackRanges; | |||
| }; | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_PLUGIN_INTERNAL_HPP__ | |||
| @@ -0,0 +1,92 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #include "DistrhoUIInternal.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| // Static data | |||
| double d_lastUiSampleRate = 0.0; | |||
| // ------------------------------------------------- | |||
| // UI | |||
| UI::UI() | |||
| : pData(new UIPrivateData) | |||
| { | |||
| #if (defined(DISTRHO_PLUGIN_TARGET_DSSI) || defined(DISTRHO_PLUGIN_TARGET_LV2)) | |||
| pData->parameterOffset = DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS; | |||
| # if DISTRHO_PLUGIN_WANT_LATENCY | |||
| pData->parameterOffset += 1; // latency | |||
| # endif | |||
| pData->parameterOffset += 1; // sample-rate | |||
| #endif | |||
| #ifdef DISTRHO_UI_QT4 | |||
| pData->widget = (Qt4UI*)this; | |||
| #endif | |||
| } | |||
| UI::~UI() | |||
| { | |||
| delete pData; | |||
| } | |||
| // ------------------------------------------------- | |||
| // Host DSP State | |||
| double UI::d_sampleRate() const | |||
| { | |||
| return pData->sampleRate; | |||
| } | |||
| void UI::d_editParameter(uint32_t index, bool started) | |||
| { | |||
| pData->editParamCallback(index, started); | |||
| } | |||
| void UI::d_setParameterValue(uint32_t index, float value) | |||
| { | |||
| pData->setParamCallback(index + pData->parameterOffset, value); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| void UI::d_setState(const char* key, const char* value) | |||
| { | |||
| pData->setStateCallback(key, value); | |||
| } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| void UI::d_sendNote(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) | |||
| { | |||
| pData->sendNoteCallback(onOff, channel, note, velocity); | |||
| } | |||
| #endif | |||
| // ------------------------------------------------- | |||
| // Host UI State | |||
| void UI::d_uiResize(unsigned int width, unsigned int height) | |||
| { | |||
| pData->uiResizeCallback(width, height); | |||
| } | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| @@ -0,0 +1,455 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #ifndef __DISTRHO_UI_INTERNAL_HPP__ | |||
| #define __DISTRHO_UI_INTERNAL_HPP__ | |||
| #include "DistrhoDefines.h" | |||
| //#ifdef DISTRHO_UI_OPENGL | |||
| //# include "DistrhoUIOpenGL.h" | |||
| // START_NAMESPACE_DISTRHO | |||
| //# include "pugl/pugl.h" | |||
| // END_NAMESPACE_DISTRHO | |||
| //#else | |||
| # include "../DistrhoUIQt4.hpp" | |||
| # include <QtGui/QMouseEvent> | |||
| # include <QtGui/QResizeEvent> | |||
| # include <QtGui/QSizeGrip> | |||
| # include <QtGui/QVBoxLayout> | |||
| # ifdef Q_WS_X11 | |||
| # include <QtGui/QX11EmbedWidget> | |||
| # endif | |||
| //#endif | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| //#ifdef DISTRHO_UI_OPENGL | |||
| //typedef PuglView NativeWidget; | |||
| //#else | |||
| typedef QWidget NativeWidget; | |||
| //#endif | |||
| typedef void (*editParamFunc) (void* ptr, uint32_t index, bool started); | |||
| typedef void (*setParamFunc) (void* ptr, uint32_t index, float value); | |||
| typedef void (*setStateFunc) (void* ptr, const char* key, const char* value); | |||
| typedef void (*sendNoteFunc) (void* ptr, bool onOff, uint8_t channel, uint8_t note, uint8_t velo); | |||
| typedef void (*uiResizeFunc) (void* ptr, unsigned int width, unsigned int height); | |||
| extern double d_lastUiSampleRate; | |||
| // ------------------------------------------------- | |||
| //#ifdef DISTRHO_UI_QT4 | |||
| # ifdef Q_WS_X11 | |||
| class QEmbedWidget : public QX11EmbedWidget | |||
| # else | |||
| class QEmbedWidget : public QWidget | |||
| # endif | |||
| { | |||
| public: | |||
| QEmbedWidget(); | |||
| ~QEmbedWidget(); | |||
| void embedInto(WId id); | |||
| WId containerWinId() const; | |||
| }; | |||
| //#endif | |||
| // ------------------------------------------------- | |||
| struct UIPrivateData { | |||
| // DSP | |||
| double sampleRate; | |||
| uint32_t parameterOffset; | |||
| // UI | |||
| void* ptr; | |||
| NativeWidget* widget; | |||
| // Callbacks | |||
| editParamFunc editParamCallbackFunc; | |||
| setParamFunc setParamCallbackFunc; | |||
| setStateFunc setStateCallbackFunc; | |||
| sendNoteFunc sendNoteCallbackFunc; | |||
| uiResizeFunc uiResizeCallbackFunc; | |||
| UIPrivateData() | |||
| : sampleRate(d_lastUiSampleRate), | |||
| parameterOffset(0), | |||
| ptr(nullptr), | |||
| widget(nullptr), | |||
| editParamCallbackFunc(nullptr), | |||
| setParamCallbackFunc(nullptr), | |||
| setStateCallbackFunc(nullptr), | |||
| sendNoteCallbackFunc(nullptr), | |||
| uiResizeCallbackFunc(nullptr) | |||
| { | |||
| assert(d_lastUiSampleRate != 0.0); | |||
| } | |||
| ~UIPrivateData() | |||
| { | |||
| } | |||
| void editParamCallback(uint32_t index, bool started) | |||
| { | |||
| if (editParamCallbackFunc != nullptr) | |||
| editParamCallbackFunc(ptr, index, started); | |||
| } | |||
| void setParamCallback(uint32_t rindex, float value) | |||
| { | |||
| if (setParamCallbackFunc != nullptr) | |||
| setParamCallbackFunc(ptr, rindex, value); | |||
| } | |||
| void setStateCallback(const char* key, const char* value) | |||
| { | |||
| if (setStateCallbackFunc != nullptr) | |||
| setStateCallbackFunc(ptr, key, value); | |||
| } | |||
| void sendNoteCallback(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) | |||
| { | |||
| if (sendNoteCallbackFunc != nullptr) | |||
| sendNoteCallbackFunc(ptr, onOff, channel, note, velocity); | |||
| } | |||
| void uiResizeCallback(unsigned int width, unsigned int height) | |||
| { | |||
| if (uiResizeCallbackFunc != nullptr) | |||
| uiResizeCallbackFunc(ptr, width, height); | |||
| } | |||
| }; | |||
| // ------------------------------------------------- | |||
| #ifdef DISTRHO_UI_QT4 | |||
| class UIInternal : public QObject // needed for eventFilter() | |||
| #else | |||
| class UIInternal | |||
| #endif | |||
| { | |||
| public: | |||
| UIInternal(void* ptr, intptr_t winId, editParamFunc editParamCall, setParamFunc setParamCall, setStateFunc setStateCall, sendNoteFunc sendNoteCall, uiResizeFunc uiResizeCall) | |||
| : kUi(createUI()), | |||
| kData((kUi != nullptr) ? kUi->pData : nullptr), | |||
| #ifdef DISTRHO_UI_QT4 | |||
| qtMouseDown(false), | |||
| qtGrip(nullptr), | |||
| qtWidget(nullptr) | |||
| #else | |||
| glInitiated(false) | |||
| #endif | |||
| { | |||
| assert(kUi != nullptr); | |||
| assert(winId != 0); | |||
| if (kUi == nullptr || winId == 0) | |||
| return; | |||
| kData->ptr = ptr; | |||
| kData->editParamCallbackFunc = editParamCall; | |||
| kData->setParamCallbackFunc = setParamCall; | |||
| kData->setStateCallbackFunc = setStateCall; | |||
| kData->sendNoteCallbackFunc = sendNoteCall; | |||
| kData->uiResizeCallbackFunc = uiResizeCall; | |||
| createWindow(winId); | |||
| } | |||
| ~UIInternal() | |||
| { | |||
| if (kUi != nullptr) | |||
| { | |||
| destroyWindow(); | |||
| delete kUi; | |||
| } | |||
| } | |||
| // --------------------------------------------- | |||
| const char* name() const | |||
| { | |||
| assert(kUi != nullptr); | |||
| return (kUi != nullptr) ? kUi->d_name() : ""; | |||
| } | |||
| unsigned int width() | |||
| { | |||
| assert(kUi != nullptr); | |||
| return (kUi != nullptr) ? kUi->d_width() : 0; | |||
| } | |||
| unsigned int height() | |||
| { | |||
| assert(kUi != nullptr); | |||
| return (kUi != nullptr) ? kUi->d_height() : 0; | |||
| } | |||
| // --------------------------------------------- | |||
| void parameterChanged(uint32_t index, float value) | |||
| { | |||
| assert(kUi != nullptr); | |||
| if (kUi != nullptr) | |||
| kUi->d_parameterChanged(index, value); | |||
| } | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| void programChanged(uint32_t index) | |||
| { | |||
| assert(kUi != nullptr); | |||
| if (kUi != nullptr) | |||
| kUi->d_programChanged(index); | |||
| } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_STATE | |||
| void stateChanged(const char* key, const char* value) | |||
| { | |||
| assert(kUi != nullptr); | |||
| if (kUi != nullptr) | |||
| kUi->d_stateChanged(key, value); | |||
| } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_IS_SYNTH | |||
| void noteReceived(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) | |||
| { | |||
| assert(kUi != nullptr); | |||
| if (kUi != nullptr) | |||
| kUi->d_noteReceived(onOff, channel, note, velocity); | |||
| } | |||
| #endif | |||
| // --------------------------------------------- | |||
| void idle() | |||
| { | |||
| assert(kUi != nullptr); | |||
| if (kUi != nullptr) | |||
| kUi->d_uiIdle(); | |||
| } | |||
| intptr_t getWindowId() | |||
| { | |||
| #ifdef DISTRHO_UI_QT4 | |||
| assert(qtWidget != nullptr); | |||
| return (qtWidget != nullptr) ? qtWidget->winId() : 0; | |||
| #else | |||
| #endif | |||
| } | |||
| // --------------------------------------------- | |||
| void createWindow(intptr_t parent) | |||
| { | |||
| #ifdef DISTRHO_UI_QT4 | |||
| assert(kUi != nullptr); | |||
| assert(kData != nullptr); | |||
| assert(kData->widget != nullptr); | |||
| assert(qtGrip == nullptr); | |||
| assert(qtWidget == nullptr); | |||
| if (kUi == nullptr) | |||
| return; | |||
| if (kData == nullptr) | |||
| return; | |||
| if (kData->widget == nullptr) | |||
| return; | |||
| if (qtGrip != nullptr) | |||
| return; | |||
| if (qtWidget != nullptr) | |||
| return; | |||
| qtMouseDown = false; | |||
| // create embedable widget | |||
| qtWidget = new QEmbedWidget; | |||
| // set layout | |||
| qtWidget->setLayout(new QVBoxLayout(qtWidget)); | |||
| qtWidget->layout()->addWidget(kData->widget); | |||
| qtWidget->layout()->setContentsMargins(0, 0, 0, 0); | |||
| qtWidget->setFixedSize(kUi->d_width(), kUi->d_height()); | |||
| // set resize grip | |||
| if (((Qt4UI*)kUi)->d_resizable()) | |||
| { | |||
| // listen for resize on the plugin widget | |||
| kData->widget->installEventFilter(this); | |||
| // create resize grip on bottom-right | |||
| qtGrip = new QSizeGrip(qtWidget); | |||
| qtGrip->resize(qtGrip->sizeHint()); | |||
| qtGrip->setCursor(Qt::SizeFDiagCursor); | |||
| qtGrip->move(kUi->d_width() - qtGrip->width(), kUi->d_height() - qtGrip->height()); | |||
| qtGrip->show(); | |||
| qtGrip->raise(); | |||
| qtGrip->installEventFilter(this); | |||
| } | |||
| // reparent widget | |||
| qtWidget->embedInto(parent); | |||
| // show it | |||
| qtWidget->show(); | |||
| #else | |||
| #endif | |||
| } | |||
| void destroyWindow() | |||
| { | |||
| #ifdef DISTRHO_UI_QT4 | |||
| assert(kData != nullptr); | |||
| assert(kData->widget != nullptr); | |||
| assert(qtWidget != nullptr); | |||
| if (kData == nullptr) | |||
| return; | |||
| if (kData->widget == nullptr) | |||
| return; | |||
| if (qtWidget == nullptr) | |||
| return; | |||
| // remove main widget, to prevent it from being auto-deleted | |||
| kData->widget->hide(); | |||
| qtWidget->layout()->removeWidget(kData->widget); | |||
| kData->widget->setParent(nullptr); | |||
| kData->widget->close(); | |||
| qtWidget->close(); | |||
| qtWidget->removeEventFilter(this); | |||
| if (qtGrip != nullptr) | |||
| { | |||
| qtGrip->removeEventFilter(this); | |||
| delete qtGrip; | |||
| qtGrip = nullptr; | |||
| } | |||
| delete qtWidget; | |||
| qtWidget = nullptr; | |||
| #else | |||
| #endif | |||
| } | |||
| // --------------------------------------------- | |||
| protected: | |||
| UI* const kUi; | |||
| UIPrivateData* const kData; | |||
| #ifdef DISTRHO_UI_QT4 | |||
| // FIXME - remove qtMouseDown usage | |||
| bool eventFilter(QObject* obj, QEvent* event) | |||
| { | |||
| assert(kUi != nullptr); | |||
| assert(kData != nullptr); | |||
| assert(kData->widget != nullptr); | |||
| assert(qtGrip != nullptr); | |||
| assert(qtWidget != nullptr); | |||
| if (kUi == nullptr) | |||
| return false; | |||
| if (kData == nullptr) | |||
| return false; | |||
| if (kData->widget == nullptr) | |||
| return false; | |||
| if (qtGrip == nullptr) | |||
| return false; | |||
| if (qtWidget == nullptr) | |||
| return false; | |||
| if (obj == nullptr) | |||
| { | |||
| // nothing | |||
| } | |||
| else if (obj == qtGrip) | |||
| { | |||
| if (event->type() == QEvent::MouseButtonPress) | |||
| { | |||
| QMouseEvent* mEvent = (QMouseEvent*)event; | |||
| if (mEvent->button() == Qt::LeftButton) | |||
| qtMouseDown = true; | |||
| } | |||
| else if (event->type() == QEvent::MouseMove) | |||
| { | |||
| if (qtMouseDown) | |||
| { | |||
| Qt4UI* qtUi = (Qt4UI*)kUi; | |||
| QMouseEvent* mEvent = (QMouseEvent*)event; | |||
| unsigned int width = qtUi->d_width() + mEvent->x() - qtGrip->width(); | |||
| unsigned int height = qtUi->d_height() + mEvent->y() - qtGrip->height(); | |||
| if (width < qtUi->d_minimumWidth()) | |||
| width = qtUi->d_minimumWidth(); | |||
| if (height < qtUi->d_minimumHeight()) | |||
| height = qtUi->d_minimumHeight(); | |||
| kData->widget->setFixedSize(width, height); | |||
| return true; | |||
| } | |||
| } | |||
| else if (event->type() == QEvent::MouseButtonRelease) | |||
| { | |||
| QMouseEvent* mEvent = (QMouseEvent*)event; | |||
| if (mEvent->button() == Qt::LeftButton) | |||
| qtMouseDown = false; | |||
| } | |||
| } | |||
| else if (obj == kData->widget && event->type() == QEvent::Resize) | |||
| { | |||
| QResizeEvent* rEvent = (QResizeEvent*)event; | |||
| const QSize& size = rEvent->size(); | |||
| qtWidget->setFixedSize(size.width(), size.height()); | |||
| qtGrip->move(size.width() - qtGrip->width(), size.height() - qtGrip->height()); | |||
| kUi->d_uiResize(size.width(), size.height()); | |||
| } | |||
| return QObject::eventFilter(obj, event); | |||
| } | |||
| #endif | |||
| private: | |||
| #ifdef DISTRHO_UI_QT4 | |||
| bool qtMouseDown; | |||
| QSizeGrip* qtGrip; | |||
| QEmbedWidget* qtWidget; | |||
| #else | |||
| bool glInitiated; | |||
| #endif | |||
| }; | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||
| #endif // __DISTRHO_UI_INTERNAL_HPP__ | |||
| @@ -0,0 +1,78 @@ | |||
| /* | |||
| * DISTRHO Plugin Toolkit (DPT) | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | |||
| * | |||
| * For a full copy of the license see the LGPL.txt file | |||
| */ | |||
| #include "DistrhoUIInternal.hpp" | |||
| START_NAMESPACE_DISTRHO | |||
| // ------------------------------------------------- | |||
| // QEmbedWidget | |||
| QEmbedWidget::QEmbedWidget() | |||
| { | |||
| } | |||
| QEmbedWidget::~QEmbedWidget() | |||
| { | |||
| } | |||
| void QEmbedWidget::embedInto(WId id) | |||
| { | |||
| #ifdef Q_WS_X11 | |||
| QX11EmbedWidget::embedInto(id); | |||
| #endif | |||
| } | |||
| WId QEmbedWidget::containerWinId() const | |||
| { | |||
| #ifdef Q_WS_X11 | |||
| return QX11EmbedWidget::containerWinId(); | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| // ------------------------------------------------- | |||
| // Qt4UI | |||
| Qt4UI::Qt4UI() | |||
| : UI(), | |||
| QWidget(nullptr) | |||
| { | |||
| } | |||
| Qt4UI::~Qt4UI() | |||
| { | |||
| } | |||
| // ------------------------------------------------- | |||
| // UI Callbacks | |||
| void Qt4UI::d_uiIdle() | |||
| { | |||
| } | |||
| // ------------------------------------------------- | |||
| // Implement resize internally | |||
| void Qt4UI::d_uiResize(unsigned int width, unsigned int height) | |||
| { | |||
| UI::d_uiResize(width, height); | |||
| } | |||
| // ------------------------------------------------- | |||
| END_NAMESPACE_DISTRHO | |||