@@ -202,6 +202,7 @@ void carla_register_native_plugin_midiThrough(); | |||||
void carla_register_native_plugin_3BandEQ(); | void carla_register_native_plugin_3BandEQ(); | ||||
void carla_register_native_plugin_3BandSplitter(); | void carla_register_native_plugin_3BandSplitter(); | ||||
void carla_register_native_plugin_PingPongPan(); | void carla_register_native_plugin_PingPongPan(); | ||||
void carla_register_native_plugin_Notes(); | |||||
#ifdef WANT_AUDIOFILE | #ifdef WANT_AUDIOFILE | ||||
void carla_register_native_plugin_audiofile(); | void carla_register_native_plugin_audiofile(); | ||||
@@ -39,10 +39,10 @@ public: | |||||
DistrhoPlugin3BandEQ(); | DistrhoPlugin3BandEQ(); | ||||
~DistrhoPlugin3BandEQ(); | ~DistrhoPlugin3BandEQ(); | ||||
// --------------------------------------------- | |||||
protected: | protected: | ||||
// --------------------------------------------- | |||||
// Information | // Information | ||||
const char* d_label() const | const char* d_label() const | ||||
{ | { | ||||
return "3BandEQ"; | return "3BandEQ"; | ||||
@@ -68,27 +68,28 @@ protected: | |||||
return d_cconst('D', '3', 'E', 'Q'); | return d_cconst('D', '3', 'E', 'Q'); | ||||
} | } | ||||
// --------------------------------------------- | |||||
// Init | // Init | ||||
void d_initParameter(uint32_t index, Parameter& parameter); | void d_initParameter(uint32_t index, Parameter& parameter); | ||||
void d_initProgramName(uint32_t index, d_string& programName); | void d_initProgramName(uint32_t index, d_string& programName); | ||||
// --------------------------------------------- | |||||
// Internal data | // Internal data | ||||
float d_parameterValue(uint32_t index); | float d_parameterValue(uint32_t index); | ||||
void d_setParameterValue(uint32_t index, float value); | void d_setParameterValue(uint32_t index, float value); | ||||
void d_setProgram(uint32_t index); | void d_setProgram(uint32_t index); | ||||
// --------------------------------------------- | |||||
// Process | // Process | ||||
void d_activate(); | void d_activate(); | ||||
void d_deactivate(); | void d_deactivate(); | ||||
void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | 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: | private: | ||||
float fLow, fMid, fHigh, fMaster, fLowMidFreq, fMidHighFreq; | float fLow, fMid, fHigh, fMaster, fLowMidFreq, fMidHighFreq; | ||||
@@ -39,10 +39,10 @@ public: | |||||
DistrhoPlugin3BandSplitter(); | DistrhoPlugin3BandSplitter(); | ||||
~DistrhoPlugin3BandSplitter(); | ~DistrhoPlugin3BandSplitter(); | ||||
// --------------------------------------------- | |||||
protected: | protected: | ||||
// --------------------------------------------- | |||||
// Information | // Information | ||||
const char* d_label() const | const char* d_label() const | ||||
{ | { | ||||
return "3BandSplitter"; | return "3BandSplitter"; | ||||
@@ -68,16 +68,22 @@ protected: | |||||
return d_cconst('D', '3', 'E', 'S'); | return d_cconst('D', '3', 'E', 'S'); | ||||
} | } | ||||
// --------------------------------------------- | |||||
// Init | // Init | ||||
void d_initParameter(uint32_t index, Parameter& parameter); | void d_initParameter(uint32_t index, Parameter& parameter); | ||||
void d_initProgramName(uint32_t index, d_string& programName); | void d_initProgramName(uint32_t index, d_string& programName); | ||||
// --------------------------------------------- | |||||
// Internal data | // Internal data | ||||
float d_parameterValue(uint32_t index); | float d_parameterValue(uint32_t index); | ||||
void d_setParameterValue(uint32_t index, float value); | void d_setParameterValue(uint32_t index, float value); | ||||
void d_setProgram(uint32_t index); | void d_setProgram(uint32_t index); | ||||
// --------------------------------------------- | |||||
// Process | // Process | ||||
void d_activate(); | void d_activate(); | ||||
void d_deactivate(); | void d_deactivate(); | ||||
void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | 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 += -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) | ifeq ($(HAVE_AF_DEPS),true) | ||||
AF_CXX_FLAGS = $(BUILD_CXX_FLAGS) | AF_CXX_FLAGS = $(BUILD_CXX_FLAGS) | ||||
@@ -20,8 +20,8 @@ endif | |||||
ifeq ($(HAVE_ZYN_DEPS),true) | ifeq ($(HAVE_ZYN_DEPS),true) | ||||
ZYN_CXX_FLAGS = $(BUILD_CXX_FLAGS) | 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 | endif | ||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
@@ -36,7 +36,8 @@ OBJS = \ | |||||
OBJS += \ | OBJS += \ | ||||
distrho-3bandeq.cpp.o \ | distrho-3bandeq.cpp.o \ | ||||
distrho-3bandsplitter.cpp.o \ | distrho-3bandsplitter.cpp.o \ | ||||
distrho-pingpongpan.cpp.o | |||||
distrho-pingpongpan.cpp.o \ | |||||
distrho-notes.cpp.o | |||||
ifeq ($(HAVE_AF_DEPS),true) | ifeq ($(HAVE_AF_DEPS),true) | ||||
OBJS += \ | OBJS += \ | ||||
@@ -88,8 +89,16 @@ distrho-3bandsplitter.cpp.o: distrho-3bandsplitter.cpp | |||||
distrho-pingpongpan.cpp.o: distrho-pingpongpan.cpp | distrho-pingpongpan.cpp.o: distrho-pingpongpan.cpp | ||||
$(CXX) $< $(BUILD_CXX_FLAGS) -Ipingpongpan -DDISTRHO_NAMESPACE=DISTRHO_PingPongPan -c -o $@ | $(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 | zynaddsubfx.cpp.o: zynaddsubfx.cpp | ||||
$(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ | $(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ | ||||
zynaddsubfx-src.cpp.o: zynaddsubfx-src.cpp | zynaddsubfx-src.cpp.o: zynaddsubfx-src.cpp | ||||
$(CXX) $< $(ZYN_CXX_FLAGS) -c -o $@ | $(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" | #include "DistrhoPluginMain.cpp" | ||||
// TODO | // TODO | ||||
#undef DISTRHO_PLUGIN_HAS_UI | |||||
//#undef DISTRHO_PLUGIN_HAS_UI | |||||
#if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
#include <QtGui/QMainWindow> | #include <QtGui/QMainWindow> | ||||
@@ -43,11 +43,11 @@ public: | |||||
kHost(host), | kHost(host), | ||||
kPlugin(plugin), | kPlugin(plugin), | ||||
fWidget(this), | 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); | setCentralWidget(&fWidget); | ||||
setFixedSize(fUi.getWidth(), fUi.getHeight()); | |||||
setWindowTitle(fUi.getName()); | |||||
setFixedSize(fUi.width(), fUi.height()); | |||||
setWindowTitle(fUi.name()); | |||||
} | } | ||||
~UICarla() | ~UICarla() | ||||
@@ -73,17 +73,35 @@ public: | |||||
void carla_setMidiProgram(const uint32_t realProgram) | void carla_setMidiProgram(const uint32_t realProgram) | ||||
{ | { | ||||
#if DISTRHO_PLUGIN_WANT_PROGRAMS | |||||
fUi.programChanged(realProgram); | fUi.programChanged(realProgram); | ||||
#else | |||||
return; | |||||
// unused | |||||
(void)realProgram; | |||||
#endif | |||||
} | } | ||||
void carla_setCustomData(const char* const key, const char* const value) | void carla_setCustomData(const char* const key, const char* const value) | ||||
{ | { | ||||
#if DISTRHO_PLUGIN_WANT_STATE | |||||
fUi.stateChanged(key, value); | fUi.stateChanged(key, value); | ||||
#else | |||||
return; | |||||
// unused | |||||
(void)key; | |||||
(void)value; | |||||
#endif | |||||
} | } | ||||
// --------------------------------------------- | // --------------------------------------------- | ||||
protected: | protected: | ||||
void editParameter(uint32_t, bool) | |||||
{ | |||||
// TODO | |||||
} | |||||
void setParameterValue(uint32_t rindex, float value) | void setParameterValue(uint32_t rindex, float value) | ||||
{ | { | ||||
kHost->ui_parameter_changed(kHost->handle, rindex, value); | kHost->ui_parameter_changed(kHost->handle, rindex, value); | ||||
@@ -94,17 +112,12 @@ protected: | |||||
kHost->ui_custom_data_changed(kHost->handle, key, value); | kHost->ui_custom_data_changed(kHost->handle, key, value); | ||||
} | } | ||||
void uiEditParameter(uint32_t, bool) | |||||
void sendNote(bool, uint8_t, uint8_t, uint8_t) | |||||
{ | { | ||||
// TODO | // 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); | setFixedSize(width, height); | ||||
} | } | ||||
@@ -137,6 +150,11 @@ private: | |||||
#define handlePtr ((UICarla*)ptr) | #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) | static void setParameterCallback(void* ptr, uint32_t rindex, float value) | ||||
{ | { | ||||
handlePtr->setParameterValue(rindex, value); | handlePtr->setParameterValue(rindex, value); | ||||
@@ -147,17 +165,12 @@ private: | |||||
handlePtr->setState(key, value); | 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); | handlePtr->uiResize(width, height); | ||||
} | } | ||||
@@ -178,14 +191,14 @@ public: | |||||
: PluginDescriptorClass(host) | : PluginDescriptorClass(host) | ||||
{ | { | ||||
#if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
fUi = nullptr; | |||||
fUiPtr = nullptr; | |||||
#endif | #endif | ||||
} | } | ||||
~PluginCarla() | ~PluginCarla() | ||||
{ | { | ||||
#if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
fUi = nullptr; | |||||
fUiPtr = nullptr; | |||||
#endif | #endif | ||||
} | } | ||||
@@ -358,51 +371,51 @@ protected: | |||||
if (show) | if (show) | ||||
createUiIfNeeded(); | createUiIfNeeded(); | ||||
if (uiPtr != nullptr) | |||||
uiPtr->carla_show(show); | |||||
if (fUiPtr != nullptr) | |||||
fUiPtr->carla_show(show); | |||||
} | } | ||||
void uiIdle() | 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) | void uiSetParameterValue(const uint32_t index, const float value) | ||||
{ | { | ||||
CARLA_ASSERT(uiPtr != nullptr); | |||||
CARLA_ASSERT(fUiPtr != nullptr); | |||||
CARLA_ASSERT(index < getParameterCount()); | 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 | # if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
void uiSetMidiProgram(const uint32_t bank, const uint32_t program) | void uiSetMidiProgram(const uint32_t bank, const uint32_t program) | ||||
{ | { | ||||
CARLA_ASSERT(uiPtr); | |||||
CARLA_ASSERT(fUiPtr != nullptr); | |||||
uint32_t realProgram = bank * 128 + program; | uint32_t realProgram = bank * 128 + program; | ||||
if (realProgram >= plugin.programCount()) | |||||
if (realProgram >= fPlugin.programCount()) | |||||
return; | return; | ||||
if (uiPtr != nullptr) | |||||
uiPtr->carla_setMidiProgram(realProgram); | |||||
if (fUiPtr != nullptr) | |||||
fUiPtr->carla_setMidiProgram(realProgram); | |||||
} | } | ||||
# endif | # endif | ||||
# if DISTRHO_PLUGIN_WANT_STATE | # if DISTRHO_PLUGIN_WANT_STATE | ||||
void uiSetCustomData(const char* const key, const char* const value) | void uiSetCustomData(const char* const key, const char* const value) | ||||
{ | { | ||||
CARLA_ASSERT(uiPtr != nullptr); | |||||
CARLA_ASSERT(fUiPtr != nullptr); | |||||
CARLA_ASSERT(key != nullptr); | CARLA_ASSERT(key != nullptr); | ||||
CARLA_ASSERT(value != nullptr); | CARLA_ASSERT(value != nullptr); | ||||
if (uiPtr != nullptr) | |||||
uiPtr->carla_setCustomData(key, value); | |||||
if (fUiPtr != nullptr) | |||||
fUiPtr->carla_setCustomData(key, value); | |||||
} | } | ||||
# endif | # endif | ||||
#endif | #endif | ||||
@@ -418,14 +431,14 @@ private: | |||||
#if DISTRHO_PLUGIN_HAS_UI | #if DISTRHO_PLUGIN_HAS_UI | ||||
// UI | // UI | ||||
ScopedPointer<UICarla> fUi; | |||||
ScopedPointer<UICarla> fUiPtr; | |||||
void createUiIfNeeded() | void createUiIfNeeded() | ||||
{ | { | ||||
if (fUi == nullptr) | |||||
if (fUiPtr == nullptr) | |||||
{ | { | ||||
d_lastUiSampleRate = getSampleRate(); | d_lastUiSampleRate = getSampleRate(); | ||||
fUi = new UICarla(getHostHandle(), &fPlugin); | |||||
fUiPtr = new UICarla(getHostHandle(), &fPlugin); | |||||
} | } | ||||
} | } | ||||
#endif | #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(); | ||||
~DistrhoPluginPingPongPan(); | ~DistrhoPluginPingPongPan(); | ||||
// --------------------------------------------- | |||||
protected: | protected: | ||||
// --------------------------------------------- | |||||
// Information | // Information | ||||
const char* d_label() const | const char* d_label() const | ||||
{ | { | ||||
return "PingPongPan"; | return "PingPongPan"; | ||||
@@ -64,16 +64,22 @@ protected: | |||||
return d_cconst('D', 'P', 'P', 'P'); | return d_cconst('D', 'P', 'P', 'P'); | ||||
} | } | ||||
// --------------------------------------------- | |||||
// Init | // Init | ||||
void d_initParameter(uint32_t index, Parameter& parameter); | void d_initParameter(uint32_t index, Parameter& parameter); | ||||
void d_initProgramName(uint32_t index, d_string& programName); | void d_initProgramName(uint32_t index, d_string& programName); | ||||
// --------------------------------------------- | |||||
// Internal data | // Internal data | ||||
float d_parameterValue(uint32_t index); | float d_parameterValue(uint32_t index); | ||||
void d_setParameterValue(uint32_t index, float value); | void d_setParameterValue(uint32_t index, float value); | ||||
void d_setProgram(uint32_t index); | void d_setProgram(uint32_t index); | ||||
// --------------------------------------------- | |||||
// Process | // Process | ||||
void d_activate(); | void d_activate(); | ||||
void d_deactivate(); | void d_deactivate(); | ||||
void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | 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_3BandEQ(); | ||||
carla_register_native_plugin_3BandSplitter(); | carla_register_native_plugin_3BandSplitter(); | ||||
carla_register_native_plugin_PingPongPan(); | carla_register_native_plugin_PingPongPan(); | ||||
carla_register_native_plugin_Notes(); | |||||
# ifdef WANT_AUDIOFILE | # ifdef WANT_AUDIOFILE | ||||
carla_register_native_plugin_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 |