diff --git a/c++/carla-native/3bandeq.cpp b/c++/carla-native/3bandeq.cpp index fc8e2ba..1180eae 100644 --- a/c++/carla-native/3bandeq.cpp +++ b/c++/carla-native/3bandeq.cpp @@ -35,8 +35,8 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------- static PluginDescriptor tBandEqDesc = { - /* category */ PLUGIN_CATEGORY_EQ, - /* hints */ 0x0, + /* category */ ::PLUGIN_CATEGORY_EQ, + /* hints */ ::PLUGIN_HAS_GUI, /* audioIns */ DISTRHO_PLUGIN_NUM_INPUTS, /* audioOuts */ DISTRHO_PLUGIN_NUM_OUTPUTS, /* midiIns */ 0, @@ -47,7 +47,7 @@ static PluginDescriptor tBandEqDesc = { /* label */ "3BandEQ", /* maker */ "falkTX", /* copyright */ "LGPL", - PluginDescriptorFILL(CarlaDistrhoPlugin) + PluginDescriptorFILL(PluginCarla) }; END_NAMESPACE_DISTRHO diff --git a/c++/carla-native/3bandsplitter.cpp b/c++/carla-native/3bandsplitter.cpp index ad376a4..a0ea82d 100644 --- a/c++/carla-native/3bandsplitter.cpp +++ b/c++/carla-native/3bandsplitter.cpp @@ -35,8 +35,8 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------- static PluginDescriptor tBandSplitterDesc = { - /* category */ PLUGIN_CATEGORY_EQ, - /* hints */ 0x0, + /* category */ ::PLUGIN_CATEGORY_EQ, + /* hints */ ::PLUGIN_HAS_GUI, /* audioIns */ DISTRHO_PLUGIN_NUM_INPUTS, /* audioOuts */ DISTRHO_PLUGIN_NUM_OUTPUTS, /* midiIns */ 0, @@ -47,7 +47,7 @@ static PluginDescriptor tBandSplitterDesc = { /* label */ "3BandSplitter", /* maker */ "falkTX", /* copyright */ "LGPL", - PluginDescriptorFILL(CarlaDistrhoPlugin) + PluginDescriptorFILL(PluginCarla) }; END_NAMESPACE_DISTRHO diff --git a/c++/carla-native/carla_native.h b/c++/carla-native/carla_native.h index 587f055..f431792 100644 --- a/c++/carla-native/carla_native.h +++ b/c++/carla-native/carla_native.h @@ -129,21 +129,25 @@ typedef struct _HostDescriptor { double (*get_sample_rate)(HostHandle handle); const TimeInfo* (*get_time_info)(HostHandle handle); bool (*write_midi_event)(HostHandle handle, MidiEvent* event); + + void (*ui_parameter_changed)(PluginHandle handle, uint32_t index, float value); + //void (*ui_midi_program_changed)(PluginHandle handle, uint32_t bank, uint32_t program); + void (*ui_custom_data_changed)(PluginHandle handle, const char* key, const char* value); } HostDescriptor; typedef struct _PluginDescriptor { - PluginCategory category; - uint32_t hints; - uint32_t audioIns; - uint32_t audioOuts; - uint32_t midiIns; - uint32_t midiOuts; - uint32_t parameterIns; - uint32_t parameterOuts; - const char* name; - const char* label; - const char* maker; - const char* copyright; + const PluginCategory category; + const uint32_t hints; + const uint32_t audioIns; + const uint32_t audioOuts; + const uint32_t midiIns; + const uint32_t midiOuts; + const uint32_t parameterIns; + const uint32_t parameterOuts; + const char* const name; + const char* const label; + const char* const maker; + const char* const copyright; PluginHandle (*instantiate)(struct _PluginDescriptor* _this_, HostDescriptor* host); diff --git a/c++/carla-native/carla_native.hpp b/c++/carla-native/carla_native.hpp index 1ad6ca2..8688e27 100644 --- a/c++/carla-native/carla_native.hpp +++ b/c++/carla-native/carla_native.hpp @@ -78,6 +78,22 @@ public: host->write_midi_event(host->handle, event); } + void uiParameterChanged(uint32_t index, float value) + { + CARLA_ASSERT(host); + + if (host) + host->ui_parameter_changed(host->handle, index, value); + } + + void uiCustomDataChanged(const char* key, const char* value) + { + CARLA_ASSERT(host); + + if (host) + host->ui_custom_data_changed(host->handle, key, value); + } + protected: // ------------------------------------------------------------------- // Plugin parameter calls @@ -126,7 +142,7 @@ protected: // ------------------------------------------------------------------- // Plugin state calls - virtual void setParameterValue(uint32_t index, double value) + virtual void setParameterValue(uint32_t index, float value) { CARLA_ASSERT(index < getParameterCount()); Q_UNUSED(value); @@ -156,7 +172,7 @@ protected: { } - virtual void uiSetParameterValue(uint32_t index, double value) + virtual void uiSetParameterValue(uint32_t index, float value) { CARLA_ASSERT(index < getParameterCount()); Q_UNUSED(value); diff --git a/c++/carla-native/carla_native.pro b/c++/carla-native/carla_native.pro index 1df4dc9..d8598e5 100644 --- a/c++/carla-native/carla_native.pro +++ b/c++/carla-native/carla_native.pro @@ -17,7 +17,7 @@ TARGET = carla_native TEMPLATE = lib VERSION = 0.5.0 -SOURCES = \ +SOURCES = \ bypass.c \ midi-split.cpp \ zynaddsubfx.cpp \ @@ -27,12 +27,16 @@ SOURCES += \ 3bandeq.cpp \ 3bandeq-src.cpp \ 3bandsplitter.cpp \ + 3bandsplitter-src.cpp \ distrho/pugl.cpp -HEADERS = \ +HEADERS = \ carla_native.h \ carla_native.hpp +HEADERS += \ + distrho/DistrhoPluginCarla.cpp + INCLUDEPATH = . distrho \ ../carla-includes \ ../carla-utils \ diff --git a/c++/carla-native/distrho/DistrhoPluginCarla.cpp b/c++/carla-native/distrho/DistrhoPluginCarla.cpp index ccbc620..23f49a9 100644 --- a/c++/carla-native/distrho/DistrhoPluginCarla.cpp +++ b/c++/carla-native/distrho/DistrhoPluginCarla.cpp @@ -20,20 +20,147 @@ #include "DistrhoPluginMain.cpp" #include "DistrhoUIMain.cpp" +#ifdef QTCREATOR_TEST +# define DISTRHO_PLUGIN_HAS_UI 1 +//# define DISTRHO_PLUGIN_IS_SYNTH 1 +# define DISTRHO_PLUGIN_WANT_PROGRAMS 1 +//# define DISTRHO_PLUGIN_WANT_STATE 1 +#endif + // ------------------------------------------------- START_NAMESPACE_DISTRHO -class CarlaDistrhoPlugin : public PluginDescriptorClass +#if DISTRHO_PLUGIN_HAS_UI +class UICarla +{ +public: + UICarla(const HostDescriptor* const host, PluginInternal* plugin, intptr_t winId) + : m_host(host), + m_plugin(plugin), + ui(this, winId, setParameterCallback, setStateCallback, uiEditParameterCallback, uiSendNoteCallback, uiResizeCallback) + { + } + + ~UICarla() + { + } + +protected: + void setParameterValue(uint32_t index, float value) + { + m_host->ui_parameter_changed(m_host->handle, index, value); + } + +#if DISTRHO_PLUGIN_WANT_STATE + void setState(const char* key, const char* value) + { + m_host->ui_custom_data_changed(m_host->handle, key, value); + } +#endif + + void uiEditParameter(uint32_t, bool) + { + // TODO + } + +#if DISTRHO_PLUGIN_IS_SYNTH + void uiSendNote(bool, uint8_t, uint8_t, uint8_t) + { + // TODO + } +#endif + + void uiResize(unsigned int width, unsigned int height) + { + //hostCallback(audioMasterSizeWindow, width, height, nullptr, 0.0f); + Q_UNUSED(width); + Q_UNUSED(height); + } + +private: + // Carla stuff + const HostDescriptor* const m_host; + PluginInternal* const m_plugin; + + // Plugin UI + UIInternal ui; + + // --------------------------------------------- + // Callbacks + + static void setParameterCallback(void* ptr, uint32_t rindex, float value) + { + UICarla* _this_ = (UICarla*)ptr; + CARLA_ASSERT(_this_); + + _this_->setParameterValue(rindex, value); + } + + static void setStateCallback(void* ptr, const char* key, const char* value) + { +#if DISTRHO_PLUGIN_WANT_STATE + UICarla* _this_ = (UICarla*)ptr; + CARLA_ASSERT(_this_); + + _this_->setState(key, value); +#else + Q_UNUSED(ptr); + Q_UNUSED(key); + Q_UNUSED(value); +#endif + } + + static void uiEditParameterCallback(void* ptr, uint32_t index, bool started) + { + UICarla* _this_ = (UICarla*)ptr; + CARLA_ASSERT(_this_); + + _this_->uiEditParameter(index, started); + } + + static void uiSendNoteCallback(void* ptr, bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) + { +#if DISTRHO_PLUGIN_IS_SYNTH + UICarla* _this_ = (UICarla*)ptr; + CARLA_ASSERT(_this_); + + _this_->uiSendNote(onOff, channel, note, velocity); +#else + Q_UNUSED(ptr); + Q_UNUSED(onOff); + Q_UNUSED(channel); + Q_UNUSED(note); + Q_UNUSED(velocity); +#endif + } + + static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height) + { + UICarla* _this_ = (UICarla*)ptr; + CARLA_ASSERT(_this_); + + _this_->uiResize(width, height); + } + + friend class PluginCarla; +}; +#endif + +class PluginCarla : public PluginDescriptorClass { public: - CarlaDistrhoPlugin(const HostDescriptor* host) - : PluginDescriptorClass(host) + PluginCarla(const HostDescriptor* host) + : PluginDescriptorClass(host), + m_host(host) { + uiPtr = nullptr; } - ~CarlaDistrhoPlugin() + ~PluginCarla() { + if (uiPtr) + delete uiPtr; } protected: @@ -49,16 +176,20 @@ protected: { static ::Parameter param; - param.hints = 0x0; -#if DISTRHO_PLUGIN_IS_SYNTH - param.hints |= PLUGIN_IS_SYNTH; -#endif -#if DISTRHO_PLUGIN_HAS_UI - param.hints |= PLUGIN_HAS_GUI; -# ifdef DISTRHO_UI_QT4 - param.hints |= PLUGIN_USES_SINGLE_THREAD; -# endif -#endif + { + uint32_t paramHints = plugin.parameterHints(index); + + if (paramHints & PARAMETER_IS_AUTOMABLE) + param.hints |= ::PARAMETER_IS_AUTOMABLE; + if (paramHints & PARAMETER_IS_BOOLEAN) + param.hints |= ::PARAMETER_IS_BOOLEAN; + if (paramHints & PARAMETER_IS_INTEGER) + param.hints |= ::PARAMETER_IS_INTEGER; + if (paramHints & PARAMETER_IS_LOGARITHMIC) + param.hints |= ::PARAMETER_IS_LOGARITHMIC; + if (paramHints & PARAMETER_IS_OUTPUT) + param.hints |= ::PARAMETER_IS_OUTPUT; + } param.name = plugin.parameterName(index); param.unit = plugin.parameterUnit(index); @@ -88,78 +219,86 @@ protected: // Plugin midi-program calls #if DISTRHO_PLUGIN_WANT_PROGRAMS - // TODO virtual uint32_t getMidiProgramCount() { - return 0; + return plugin.programCount(); } - virtual const MidiProgram* getMidiProgramInfo(uint32_t index) + virtual const ::MidiProgram* getMidiProgramInfo(uint32_t index) { - return nullptr; + static ::MidiProgram midiProgram; + midiProgram.bank = index / 128; + midiProgram.program = index % 128; + midiProgram.name = plugin.programName(index); + return &midiProgram; } #endif // ------------------------------------------------------------------- // Plugin state calls - void setParameterValue(uint32_t index, double value) + void setParameterValue(uint32_t index, float value) { plugin.setParameterValue(index, value); } #if DISTRHO_PLUGIN_WANT_PROGRAMS - // TODO void setMidiProgram(uint32_t bank, uint32_t program) { - Q_UNUSED(bank); - Q_UNUSED(program); + uint32_t realProgram = bank * 128 + program; + plugin.setProgram(realProgram); } #endif #if DISTRHO_PLUGIN_WANT_STATE - // TODO void setCustomData(const char* key, const char* value) { - CARLA_ASSERT(key); - CARLA_ASSERT(value); + plugin.setState(key, value); } #endif // ------------------------------------------------------------------- // Plugin UI calls +#if DISTRHO_PLUGIN_HAS_UI void uiShow(bool show) { - Q_UNUSED(show); + if (show) + createUiIfNeeded(); + + //if (uiPtr) + // uiPtr->setVisible(show); } void uiIdle() { + if (uiPtr) + uiPtr->ui.idle(); } - void uiSetParameterValue(uint32_t index, double value) + void uiSetParameterValue(uint32_t index, float value) { - CARLA_ASSERT(index < getParameterCount()); - Q_UNUSED(value); + if (uiPtr) + uiPtr->ui.parameterChanged(index, value); } -#if DISTRHO_PLUGIN_WANT_PROGRAMS - // TODO +# if DISTRHO_PLUGIN_WANT_PROGRAMS void uiSetMidiProgram(uint32_t bank, uint32_t program) { - Q_UNUSED(bank); - Q_UNUSED(program); + uint32_t realProgram = bank * 128 + program; + + if (uiPtr) + uiPtr->ui.programChanged(realProgram); } -#endif +# endif -#if DISTRHO_PLUGIN_WANT_STATE - // TODO +# if DISTRHO_PLUGIN_WANT_STATE void uiSetCustomData(const char* key, const char* value) { - CARLA_ASSERT(key); - CARLA_ASSERT(value); + if (uiPtr) + uiPtr->ui.stateChanged(key, value); } +# endif #endif // ------------------------------------------------------------------- @@ -182,13 +321,22 @@ protected: // ------------------------------------------------------------------- -protected: +private: PluginInternal plugin; + const HostDescriptor* const m_host; + +#if DISTRHO_PLUGIN_HAS_UI + // UI + UICarla* uiPtr; +#endif -private: void createUiIfNeeded() { - setLastUiSampleRate(d_lastSampleRate); + if (! uiPtr) + { + setLastUiSampleRate(getSampleRate()); + uiPtr = new UICarla(m_host, &plugin, 0); + } } // ------------------------------------------------------------------- @@ -198,12 +346,12 @@ public: { d_lastBufferSize = host->get_buffer_size(host->handle); d_lastSampleRate = host->get_sample_rate(host->handle); - return new CarlaDistrhoPlugin(host); + return new PluginCarla(host); } static void _cleanup(PluginHandle handle) { - delete (CarlaDistrhoPlugin*)handle; + delete (PluginCarla*)handle; } }; diff --git a/c++/carla-plugin/dssi.cpp b/c++/carla-plugin/dssi.cpp index 3dcff3f..fda003b 100644 --- a/c++/carla-plugin/dssi.cpp +++ b/c++/carla-plugin/dssi.cpp @@ -124,7 +124,7 @@ public: unsigned long dataSize = 0; - if (descriptor->get_custom_data(handle, dataPtr, &dataSize)) + if (descriptor->get_custom_data && descriptor->get_custom_data(handle, dataPtr, &dataSize)) return dataSize; return 0; diff --git a/c++/carla-plugin/native.cpp b/c++/carla-plugin/native.cpp index f221305..aae56e6 100644 --- a/c++/carla-plugin/native.cpp +++ b/c++/carla-plugin/native.cpp @@ -49,6 +49,8 @@ public: host.get_sample_rate = carla_host_get_sample_rate; host.get_time_info = carla_host_get_time_info; host.write_midi_event = carla_host_write_midi_event; + host.ui_parameter_changed = carla_host_ui_parameter_changed; + host.ui_custom_data_changed = carla_host_ui_custom_data_changed; isProcessing = false; @@ -287,6 +289,12 @@ public: CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf); } + void getGuiInfo(GuiType* const type, bool* const resizable) + { + *type = GUI_EXTERNAL_OSC; // FIXME, should be _LV2 but as _PLUGIN + *resizable = false; + } + // ------------------------------------------------------------------- // Set data (plugin-specific stuff) @@ -1455,6 +1463,16 @@ public: return true; } + void handleUiParameterChanged(uint32_t index, float value) + { + setParameterValue(index, value, false, true, true); + } + + void handleUiCustomDataChanged(const char* key, const char* value) + { + setCustomData(CUSTOM_DATA_STRING, key, value, false); + } + static uint32_t carla_host_get_buffer_size(HostHandle handle) { CARLA_ASSERT(handle); @@ -1479,6 +1497,18 @@ public: return ((NativePlugin*)handle)->handleWriteMidiEvent(event); } + static void carla_host_ui_parameter_changed(HostHandle handle, uint32_t index, float value) + { + CARLA_ASSERT(handle); + ((NativePlugin*)handle)->handleUiParameterChanged(index, value); + } + + static void carla_host_ui_custom_data_changed(HostHandle handle, const char* key, const char* value) + { + CARLA_ASSERT(handle); + ((NativePlugin*)handle)->handleUiCustomDataChanged(key, value); + } + // ------------------------------------------------------------------- static size_t getPluginCount()