Mercurial > hg > pub > prymula > com
view DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoPluginCarla.cpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
line wrap: on
line source
/* * DISTRHO Plugin Framework (DPF) * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with * or without fee is hereby granted, provided that the above copyright notice and this * permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "DistrhoPluginInternal.hpp" #if DISTRHO_PLUGIN_HAS_UI # include "DistrhoUIInternal.hpp" #endif #include "CarlaNative.hpp" // TODO #undef DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST #define DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST 0 // ----------------------------------------------------------------------- START_NAMESPACE_DISTRHO #if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT static constexpr const writeMidiFunc writeMidiCallback = nullptr; #endif #if ! DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST static constexpr const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr; #endif // TODO static constexpr const updateStateValueFunc updateStateValueCallback = nullptr; #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), fUI(this, 0, plugin->getSampleRate(), editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, nullptr, // window size nullptr, // TODO file request nullptr, // bundle path plugin->getInstancePointer()) { fUI.setWindowTitle(host->uiName); if (host->uiParentId != 0) fUI.setWindowTransientWinId(host->uiParentId); } ~UICarla() { fUI.quit(); } // --------------------------------------------- void carla_show(const bool yesNo) { fUI.setWindowVisible(yesNo); } bool carla_idle() { return fUI.plugin_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.programLoaded(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.setWindowTitle(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); } #if DISTRHO_PLUGIN_WANT_STATE void handleSetState(const char* const key, const char* const value) { fHost->ui_custom_data_changed(fHost->handle, key, value); } #endif #if DISTRHO_PLUGIN_IS_SYNTH void handleSendNote(const uint8_t, const uint8_t, const uint8_t) { // TODO } #endif // --------------------------------------------- private: // Plugin stuff const NativeHostDescriptor* const fHost; // 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 #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), fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback), fScalePointsCache(nullptr) { #if DISTRHO_PLUGIN_HAS_UI fUiPtr = nullptr; #endif } ~PluginCarla() override { #if DISTRHO_PLUGIN_HAS_UI if (fUiPtr != nullptr) { delete fUiPtr; fUiPtr = nullptr; } #endif if (fScalePointsCache != nullptr) { delete[] fScalePointsCache; fScalePointsCache = nullptr; } } protected: // ------------------------------------------------------------------- // Plugin parameter calls uint32_t getParameterCount() const override { return fPlugin.getParameterCount(); } const NativeParameter* getParameterInfo(const uint32_t index) const override { CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(), nullptr); static NativeParameter param; param.scalePointCount = 0; param.scalePoints = nullptr; { int nativeParamHints = ::NATIVE_PARAMETER_IS_ENABLED; const uint32_t paramHints = fPlugin.getParameterHints(index); if (paramHints & kParameterIsAutomatable) nativeParamHints |= ::NATIVE_PARAMETER_IS_AUTOMABLE; if (paramHints & kParameterIsBoolean) nativeParamHints |= ::NATIVE_PARAMETER_IS_BOOLEAN; if (paramHints & kParameterIsInteger) nativeParamHints |= ::NATIVE_PARAMETER_IS_INTEGER; if (paramHints & kParameterIsLogarithmic) nativeParamHints |= ::NATIVE_PARAMETER_IS_LOGARITHMIC; if (paramHints & kParameterIsOutput) nativeParamHints |= ::NATIVE_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; } { const ParameterEnumerationValues& enumValues(fPlugin.getParameterEnumValues(index)); if (const uint32_t scalePointCount = enumValues.count) { NativeParameterScalePoint* const scalePoints = new NativeParameterScalePoint[scalePointCount]; for (uint32_t i=0; i<scalePointCount; ++i) { scalePoints[i].label = enumValues.values[i].label.buffer(); scalePoints[i].value = enumValues.values[i].value; } param.scalePoints = scalePoints; param.scalePointCount = scalePointCount; if (enumValues.restrictedMode) param.hints = static_cast<NativeParameterHints>(param.hints|::NATIVE_PARAMETER_USES_SCALEPOINTS); } else if (fScalePointsCache != nullptr) { delete[] fScalePointsCache; fScalePointsCache = nullptr; } } return ¶m; } float getParameterValue(const uint32_t index) const override { CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(), 0.0f); 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_SAFE_ASSERT_RETURN(index < getMidiProgramCount(), 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_SAFE_ASSERT_RETURN(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); CARLA_SAFE_ASSERT_RETURN(realProgram < getMidiProgramCount(),); fPlugin.loadProgram(realProgram); } #endif #if DISTRHO_PLUGIN_WANT_STATE void setCustomData(const char* const key, const char* const value) override { CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(value != nullptr,); fPlugin.setState(key, value); } #endif // ------------------------------------------------------------------- // Plugin process calls void activate() override { fPlugin.activate(); } void deactivate() override { fPlugin.deactivate(); } #if DISTRHO_PLUGIN_WANT_MIDI_INPUT void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override { MidiEvent realMidiEvents[midiEventCount]; for (uint32_t i=0; i < midiEventCount; ++i) { const NativeMidiEvent& midiEvent(midiEvents[i]); MidiEvent& realMidiEvent(realMidiEvents[i]); realMidiEvent.frame = midiEvent.time; realMidiEvent.size = midiEvent.size; uint8_t j=0; for (; j<midiEvent.size; ++j) realMidiEvent.data[j] = midiEvent.data[j]; for (; j<midiEvent.size; ++j) realMidiEvent.data[j] = midiEvent.data[j]; realMidiEvent.dataExt = nullptr; } fPlugin.run(const_cast<const float**>(inBuffer), outBuffer, frames, realMidiEvents, midiEventCount); } #else void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const, const uint32_t) override { fPlugin.run(const_cast<const float**>(inBuffer), outBuffer, frames); } #endif // ------------------------------------------------------------------- // Plugin UI calls #if DISTRHO_PLUGIN_HAS_UI void uiShow(const bool show) override { if (show) { createUiIfNeeded(); CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); fUiPtr->carla_show(show); } else if (fUiPtr != nullptr) { delete fUiPtr; fUiPtr = nullptr; } } void uiIdle() override { CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); if (! fUiPtr->carla_idle()) { uiClosed(); delete fUiPtr; fUiPtr = nullptr; } } void uiSetParameterValue(const uint32_t index, const float value) override { CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),); 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_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); const uint32_t realProgram(bank * 128 + program); CARLA_SAFE_ASSERT_RETURN(realProgram < getMidiProgramCount(),); fUiPtr->carla_setMidiProgram(realProgram); } # endif # if DISTRHO_PLUGIN_WANT_STATE void uiSetCustomData(const char* const key, const char* const value) override { CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(value != 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 { CARLA_SAFE_ASSERT_RETURN(fUiPtr != nullptr,); fUiPtr->carla_setUiTitle(uiName); } #endif // ------------------------------------------------------------------- private: PluginExporter fPlugin; mutable NativeParameterScalePoint* fScalePointsCache; #if DISTRHO_PLUGIN_HAS_UI // UI UICarla* fUiPtr; void createUiIfNeeded() { if (fUiPtr == nullptr) fUiPtr = new UICarla(getHostHandle(), &fPlugin); } #endif #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT static bool writeMidiCallback(void* ptr, const MidiEvent& midiEvent) { if (midiEvent.size > 4) return; const NativeMidiEvent event = { midiEvent.frame, 0, midiEvent.size, midiEvent.data }; return ((PluginCarla*)ptr)->fPlugin.writeMidiEvent(midiEvent); } #endif #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST bool requestParameterValueChange(const uint32_t index, const float value) { // TODO implementation return false; } static bool requestParameterValueChangeCallback(void* ptr, const uint32_t index, const float value) { return thisPtr->requestParameterValueChange(index, value); } #endif CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginCarla) // ------------------------------------------------------------------- public: static NativePluginHandle _instantiate(const NativeHostDescriptor* host) { d_nextBufferSize = host->get_buffer_size(host->handle); d_nextSampleRate = host->get_sample_rate(host->handle); return new PluginCarla(host); } static void _cleanup(NativePluginHandle handle) { delete (PluginCarla*)handle; } }; END_NAMESPACE_DISTRHO // -----------------------------------------------------------------------