commit a589df54d335d33b75f3af2f01c5f587af14a63e
parent 229df759a35318804d9963fafef6491b4031d9ad
Author: falkTX <falktx@gmail.com>
Date: Sun, 9 Mar 2014 15:58:31 +0000
Add carla plugin code
Diffstat:
1 file changed, 471 insertions(+), 0 deletions(-)
diff --git a/distrho/src/DistrhoPluginCarla.cpp b/distrho/src/DistrhoPluginCarla.cpp
@@ -0,0 +1,471 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2014 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"
+
+#if DISTRHO_PLUGIN_HAS_UI
+# include "DistrhoUIInternal.hpp"
+#endif
+
+#include "CarlaNative.hpp"
+
+// -----------------------------------------------------------------------
+
+START_NAMESPACE_DISTRHO
+
+#if DISTRHO_PLUGIN_HAS_UI
+// -----------------------------------------------------------------------
+// Carla UI
+
+#if ! DISTRHO_PLUGIN_WANT_STATE
+static const setStateFunc setStateCallback = nullptr;
+#endif
+#if ! DISTRHO_PLUGIN_IS_SYNTH
+static const sendNoteFunc sendNoteCallback = nullptr;
+#endif
+
+class UICarla
+{
+public:
+ UICarla(const NativeHostDescriptor* const host, PluginExporter* const plugin)
+ : fHost(host),
+ fPlugin(plugin),
+ fUI(this, 0, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback)
+ {
+ fUI.setTitle(host->uiName);
+ }
+
+ // ---------------------------------------------
+
+ void carla_show(const bool yesNo)
+ {
+ fUI.setVisible(yesNo);
+ }
+
+ void carla_idle()
+ {
+ fUI.idle();
+ }
+
+ void carla_setParameterValue(const uint32_t index, const float value)
+ {
+ fUI.parameterChanged(index, value);
+ }
+
+#if DISTRHO_PLUGIN_WANT_PROGRAMS
+ void carla_setMidiProgram(const uint32_t realProgram)
+ {
+ fUI.programChanged(realProgram);
+ }
+#endif
+
+#if DISTRHO_PLUGIN_WANT_STATE
+ void carla_setCustomData(const char* const key, const char* const value)
+ {
+ fUI.stateChanged(key, value);
+ }
+#endif
+
+ void carla_setUiTitle(const char* const uiTitle)
+ {
+ fUI.setTitle(uiTitle);
+ }
+
+ // ---------------------------------------------
+
+protected:
+ void handleEditParameter(const uint32_t, const bool)
+ {
+ // TODO
+ }
+
+ void handleSetParameterValue(const uint32_t rindex, const float value)
+ {
+ fHost->ui_parameter_changed(fHost->handle, rindex, value);
+ }
+
+ void handleSetState(const char* const key, const char* const value)
+ {
+ fHost->ui_custom_data_changed(fHost->handle, key, value);
+ }
+
+ void handleSendNote(const uint8_t, const uint8_t, const uint8_t)
+ {
+ // TODO
+ }
+
+ void handleUiResize(const unsigned int width, const unsigned int height)
+ {
+ fUI.setSize(width, height);
+ }
+
+ // ---------------------------------------------
+
+private:
+ // Plugin stuff
+ const NativeHostDescriptor* const fHost;
+ PluginExporter* const fPlugin;
+
+ // UI
+ UIExporter fUI;
+
+ // ---------------------------------------------
+ // Callbacks
+
+ #define handlePtr ((UICarla*)ptr)
+
+ static void editParameterCallback(void* ptr, uint32_t index, bool started)
+ {
+ handlePtr->handleEditParameter(index, started);
+ }
+
+ static void setParameterCallback(void* ptr, uint32_t rindex, float value)
+ {
+ handlePtr->handleSetParameterValue(rindex, value);
+ }
+
+#if DISTRHO_PLUGIN_WANT_STATE
+ static void setStateCallback(void* ptr, const char* key, const char* value)
+ {
+ handlePtr->handleSetState(key, value);
+ }
+#endif
+
+#if DISTRHO_PLUGIN_IS_SYNTH
+ static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity)
+ {
+ handlePtr->handleSendNote(channel, note, velocity);
+ }
+#endif
+
+ static void uiResizeCallback(void* ptr, unsigned int width, unsigned int height)
+ {
+ handlePtr->handleUiResize(width, height);
+ }
+
+ #undef handlePtr
+
+ CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UICarla)
+};
+#endif // DISTRHO_PLUGIN_HAS_UI
+
+// -----------------------------------------------------------------------
+// Carla Plugin
+
+class PluginCarla : public NativePluginClass
+{
+public:
+ PluginCarla(const NativeHostDescriptor* const host)
+ : NativePluginClass(host)
+ {
+#if DISTRHO_PLUGIN_HAS_UI
+ fUiPtr = nullptr;
+#endif
+ }
+
+ ~PluginCarla() override
+ {
+#if DISTRHO_PLUGIN_HAS_UI
+ if (fUiPtr != nullptr)
+ {
+ delete fUiPtr;
+ fUiPtr = nullptr;
+ }
+#endif
+ }
+
+protected:
+ // -------------------------------------------------------------------
+ // Plugin parameter calls
+
+ uint32_t getParameterCount() const override
+ {
+ return fPlugin.getParameterCount();
+ }
+
+ const NativeParameter* getParameterInfo(const uint32_t index) const override
+ {
+ CARLA_ASSERT(index < getParameterCount());
+
+ static NativeParameter param;
+
+ // reset
+ param.hints = ::PARAMETER_IS_ENABLED;
+ param.scalePointCount = 0;
+ param.scalePoints = nullptr;
+
+ {
+ int nativeParamHints = ::PARAMETER_IS_ENABLED;
+ const uint32_t paramHints = fPlugin.getParameterHints(index);
+
+ if (paramHints & PARAMETER_IS_AUTOMABLE)
+ nativeParamHints |= ::PARAMETER_IS_AUTOMABLE;
+ if (paramHints & PARAMETER_IS_BOOLEAN)
+ nativeParamHints |= ::PARAMETER_IS_BOOLEAN;
+ if (paramHints & PARAMETER_IS_INTEGER)
+ nativeParamHints |= ::PARAMETER_IS_INTEGER;
+ if (paramHints & PARAMETER_IS_LOGARITHMIC)
+ nativeParamHints |= ::PARAMETER_IS_LOGARITHMIC;
+ if (paramHints & PARAMETER_IS_OUTPUT)
+ nativeParamHints |= ::PARAMETER_IS_OUTPUT;
+
+ param.hints = static_cast<NativeParameterHints>(nativeParamHints);
+ }
+
+ param.name = fPlugin.getParameterName(index);
+ param.unit = fPlugin.getParameterUnit(index);
+
+ {
+ const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
+
+ param.ranges.def = ranges.def;
+ param.ranges.min = ranges.min;
+ param.ranges.max = ranges.max;
+ //param.ranges.step = ranges.step;
+ //param.ranges.stepSmall = ranges.stepSmall;
+ //param.ranges.stepLarge = ranges.stepLarge;
+ }
+
+ return ¶m;
+ }
+
+ float getParameterValue(const uint32_t index) const override
+ {
+ CARLA_ASSERT(index < getParameterCount());
+
+ return fPlugin.getParameterValue(index);
+ }
+
+ // -------------------------------------------------------------------
+ // Plugin midi-program calls
+
+#if DISTRHO_PLUGIN_WANT_PROGRAMS
+ uint32_t getMidiProgramCount() const override
+ {
+ return fPlugin.getProgramCount();
+ }
+
+ const NativeMidiProgram* getMidiProgramInfo(const uint32_t index) const override
+ {
+ CARLA_ASSERT(index < getMidiProgramCount());
+
+ if (index >= fPlugin.getProgramCount())
+ return nullptr;
+
+ static NativeMidiProgram midiProgram;
+
+ midiProgram.bank = index / 128;
+ midiProgram.program = index % 128;
+ midiProgram.name = fPlugin.getProgramName(index);
+
+ return &midiProgram;
+ }
+#endif
+
+ // -------------------------------------------------------------------
+ // Plugin state calls
+
+ void setParameterValue(const uint32_t index, const float value) override
+ {
+ CARLA_ASSERT(index < getParameterCount());
+
+ fPlugin.setParameterValue(index, value);
+ }
+
+#if DISTRHO_PLUGIN_WANT_PROGRAMS
+ void setMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override
+ {
+ const uint32_t realProgram(bank * 128 + program);
+
+ if (realProgram >= fPlugin.getProgramCount())
+ return;
+
+ fPlugin.setProgram(realProgram);
+ }
+#endif
+
+#if DISTRHO_PLUGIN_WANT_STATE
+ void setCustomData(const char* const key, const char* const value) override
+ {
+ CARLA_ASSERT(key != nullptr);
+ CARLA_ASSERT(value != nullptr);
+
+ fPlugin.setState(key, value);
+ }
+#endif
+
+ // -------------------------------------------------------------------
+ // Plugin process calls
+
+ void activate() override
+ {
+ fPlugin.activate();
+ }
+
+ void deactivate() override
+ {
+ fPlugin.deactivate();
+ }
+
+#if DISTRHO_PLUGIN_IS_SYNTH
+ void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override
+ {
+ uint32_t i;
+
+ for (i=0; i < midiEventCount && i < kMaxMidiEvents; ++i)
+ {
+ const NativeMidiEvent* const midiEvent(&midiEvents[i]);
+ MidiEvent* const realMidiEvent(&fRealMidiEvents[i]);
+
+ realMidiEvent->frame = midiEvent->time;
+ realMidiEvent->size = midiEvent->size;
+
+ for (uint8_t j=0; j < midiEvent->size; ++j)
+ realMidiEvent->buf[j] = midiEvent->data[j];
+ }
+
+ fPlugin.run(inBuffer, outBuffer, frames, fRealMidiEvents, i);
+ }
+#else
+ void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const, const uint32_t) override
+ {
+ fPlugin.run(inBuffer, outBuffer, frames);
+ }
+#endif
+
+ // -------------------------------------------------------------------
+ // Plugin UI calls
+
+#if DISTRHO_PLUGIN_HAS_UI
+ void uiShow(const bool show) override
+ {
+ if (show)
+ createUiIfNeeded();
+
+ if (fUiPtr != nullptr)
+ fUiPtr->carla_show(show);
+ }
+
+ void uiIdle() override
+ {
+ CARLA_ASSERT(fUiPtr != nullptr);
+
+ if (fUiPtr != nullptr)
+ fUiPtr->carla_idle();
+ }
+
+ void uiSetParameterValue(const uint32_t index, const float value) override
+ {
+ CARLA_ASSERT(fUiPtr != nullptr);
+ CARLA_ASSERT(index < getParameterCount());
+
+ if (fUiPtr != nullptr)
+ fUiPtr->carla_setParameterValue(index, value);
+ }
+
+# if DISTRHO_PLUGIN_WANT_PROGRAMS
+ void uiSetMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override
+ {
+ CARLA_ASSERT(fUiPtr != nullptr);
+
+ const uint32_t realProgram(bank * 128 + program);
+
+ if (realProgram >= fPlugin.getProgramCount())
+ return;
+
+ if (fUiPtr != nullptr)
+ fUiPtr->carla_setMidiProgram(realProgram);
+ }
+# endif
+
+# if DISTRHO_PLUGIN_WANT_STATE
+ void uiSetCustomData(const char* const key, const char* const value) override
+ {
+ CARLA_ASSERT(fUiPtr != nullptr);
+ CARLA_ASSERT(key != nullptr);
+ CARLA_ASSERT(value != nullptr);
+
+ if (fUiPtr != nullptr)
+ fUiPtr->carla_setCustomData(key, value);
+ }
+# endif
+#endif
+
+ // -------------------------------------------------------------------
+ // Plugin dispatcher calls
+
+ void bufferSizeChanged(const uint32_t bufferSize) override
+ {
+ fPlugin.setBufferSize(bufferSize, true);
+ }
+
+ void sampleRateChanged(const double sampleRate) override
+ {
+ fPlugin.setSampleRate(sampleRate, true);
+ }
+
+#if DISTRHO_PLUGIN_HAS_UI
+ void uiNameChanged(const char* const uiName) override
+ {
+ if (fUiPtr != nullptr)
+ fUiPtr->carla_setUiTitle(uiName);
+ }
+#endif
+
+ // -------------------------------------------------------------------
+
+private:
+ PluginExporter fPlugin;
+
+#if DISTRHO_PLUGIN_IS_SYNTH
+ MidiEvent fRealMidiEvents[kMaxMidiEvents];
+#endif
+
+#if DISTRHO_PLUGIN_HAS_UI
+ // UI
+ UICarla* fUiPtr;
+
+ void createUiIfNeeded()
+ {
+ if (fUiPtr == nullptr)
+ {
+ d_lastUiSampleRate = getSampleRate();
+ fUiPtr = new UICarla(getHostHandle(), &fPlugin);
+ }
+ }
+#endif
+
+ CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginCarla)
+
+ // -------------------------------------------------------------------
+
+public:
+ static NativePluginHandle _instantiate(const NativeHostDescriptor* host)
+ {
+ d_lastBufferSize = host->get_buffer_size(host->handle);
+ d_lastSampleRate = host->get_sample_rate(host->handle);
+ return new PluginCarla(host);
+ }
+
+ static void _cleanup(NativePluginHandle handle)
+ {
+ delete (PluginCarla*)handle;
+ }
+};
+
+END_NAMESPACE_DISTRHO
+
+// -----------------------------------------------------------------------