diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6bd5436 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/build/ +.kdev4/ diff --git a/plugins/Common/.kdev_include_paths b/plugins/Common/.kdev_include_paths new file mode 100644 index 0000000..ca17ce3 --- /dev/null +++ b/plugins/Common/.kdev_include_paths @@ -0,0 +1,5 @@ +../../dpf/dgl/ +../../dpf/distrho/ +../../dpf-widgets/generic +../../dpf-widgets/opengl +/usr/include/carla diff --git a/plugins/Common/IldaeilPlugin.cpp b/plugins/Common/IldaeilPlugin.cpp index bba032d..495ca4e 100644 --- a/plugins/Common/IldaeilPlugin.cpp +++ b/plugins/Common/IldaeilPlugin.cpp @@ -15,22 +15,110 @@ * For a full copy of the GNU General Public License see the LICENSE file. */ +#include "CarlaNativePlugin.h" + #include "DistrhoPlugin.hpp" +#include "DistrhoUI.hpp" START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------------------------------------------- +static uint32_t host_get_buffer_size(NativeHostHandle); +static double host_get_sample_rate(NativeHostHandle); +static bool host_is_offline(NativeHostHandle); +static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle); +static bool host_write_midi_event(NativeHostHandle handle, const NativeMidiEvent* event); +static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt); + +// ----------------------------------------------------------------------------------------------------------- + class IldaeilPlugin : public Plugin { + const NativePluginDescriptor* fCarlaPluginDescriptor; + NativePluginHandle fCarlaPluginHandle; + + NativeHostDescriptor fCarlaHostDescriptor; + CarlaHostHandle fCarlaHostHandle; + + NativeTimeInfo fCarlaTimeInfo; + + UI* fUI; + public: IldaeilPlugin() - : Plugin(0, 0, 0) + : Plugin(0, 0, 0), + fCarlaPluginDescriptor(nullptr), + fCarlaPluginHandle(nullptr), + fCarlaHostHandle(nullptr), + fUI(nullptr) { + fCarlaPluginDescriptor = carla_get_native_rack_plugin(); + DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginDescriptor != nullptr,); + + memset(&fCarlaHostDescriptor, 0, sizeof(fCarlaHostDescriptor)); + memset(&fCarlaTimeInfo, 0, sizeof(fCarlaTimeInfo)); + + fCarlaHostDescriptor.handle = this; + fCarlaHostDescriptor.resourceDir = carla_get_library_folder(); + fCarlaHostDescriptor.uiName = "Ildaeil"; + fCarlaHostDescriptor.uiParentId = 0; + + fCarlaHostDescriptor.get_buffer_size = host_get_buffer_size; + fCarlaHostDescriptor.get_sample_rate = host_get_sample_rate; + fCarlaHostDescriptor.is_offline = host_is_offline; + + fCarlaHostDescriptor.get_time_info = host_get_time_info; + fCarlaHostDescriptor.write_midi_event = host_write_midi_event; + fCarlaHostDescriptor.ui_parameter_changed = nullptr; + fCarlaHostDescriptor.ui_midi_program_changed = nullptr; + fCarlaHostDescriptor.ui_custom_data_changed = nullptr; + fCarlaHostDescriptor.ui_closed = nullptr; + fCarlaHostDescriptor.ui_open_file = nullptr; + fCarlaHostDescriptor.ui_save_file = nullptr; + fCarlaHostDescriptor.dispatcher = host_dispatcher; + + fCarlaPluginHandle = fCarlaPluginDescriptor->instantiate(&fCarlaHostDescriptor); + DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginHandle != nullptr,); + + fCarlaHostHandle = carla_create_native_plugin_host_handle(fCarlaPluginDescriptor, fCarlaPluginHandle); } ~IldaeilPlugin() override { + if (fCarlaHostHandle != nullptr) + { + carla_host_handle_free(fCarlaHostHandle); + } + + if (fCarlaPluginHandle != nullptr) + fCarlaPluginDescriptor->cleanup(fCarlaPluginHandle); + } + + const NativeTimeInfo* getTimeInfo() + { + const TimePosition& timePos(getTimePosition()); + + fCarlaTimeInfo.playing = timePos.playing; + fCarlaTimeInfo.frame = timePos.frame; + fCarlaTimeInfo.bbt.valid = timePos.bbt.valid; + fCarlaTimeInfo.bbt.bar = timePos.bbt.bar; + fCarlaTimeInfo.bbt.beat = timePos.bbt.beat; + fCarlaTimeInfo.bbt.tick = timePos.bbt.tick; + fCarlaTimeInfo.bbt.barStartTick = timePos.bbt.barStartTick; + fCarlaTimeInfo.bbt.beatsPerBar = timePos.bbt.beatsPerBar; + fCarlaTimeInfo.bbt.beatType = timePos.bbt.beatType; + fCarlaTimeInfo.bbt.ticksPerBeat = timePos.bbt.ticksPerBeat; + fCarlaTimeInfo.bbt.beatsPerMinute = timePos.bbt.beatsPerMinute; + + return &fCarlaTimeInfo; + } + + void resizeUI(const uint width, const uint height) + { + DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); + + fUI->setSize(width, height); } protected: @@ -43,7 +131,13 @@ protected: */ const char* getLabel() const override { - return "Ildaeil"; +#if DISTRHO_PLUGIN_IS_SYNTH + return "IldaeilSynth"; +#elif DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + return "IldaeilMIDI"; +#else + return "IldaeilFX"; +#endif } /** @@ -51,7 +145,7 @@ protected: */ const char* getDescription() const override { - return "..."; + return "Ildaeil is a mini-plugin host working as a plugin, allowing one-to-one plugin format reusage."; } /** @@ -111,17 +205,29 @@ protected: /* -------------------------------------------------------------------------------------------------------- * Process */ - /** - Run/process function for plugins without MIDI input. - */ - void run(const float** inputs, float** outputs, uint32_t frames) override + void activate() override + { + if (fCarlaPluginHandle != nullptr) + fCarlaPluginDescriptor->activate(fCarlaPluginHandle); + } + + void deactivate() override { - // copy inputs over outputs if needed - if (outputs[0] != inputs[0]) - std::memcpy(outputs[0], inputs[0], sizeof(float)*frames); + if (fCarlaPluginHandle != nullptr) + fCarlaPluginDescriptor->deactivate(fCarlaPluginHandle); + } - if (outputs[1] != inputs[1]) - std::memcpy(outputs[1], inputs[1], sizeof(float)*frames); + void run(const float** inputs, float** outputs, uint32_t frames) override + { + if (fCarlaPluginHandle != nullptr) + { + fCarlaPluginDescriptor->process(fCarlaPluginHandle, (float**)inputs, outputs, frames, nullptr, 0); + } + else + { + std::memset(outputs[0], 0, sizeof(float)*frames); + std::memset(outputs[1], 0, sizeof(float)*frames); + } } // ------------------------------------------------------------------------------------------------------- @@ -133,6 +239,48 @@ private: DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(IldaeilPlugin) }; +// ----------------------------------------------------------------------------------------------------------- + +static uint32_t host_get_buffer_size(const NativeHostHandle handle) +{ + return static_cast(handle)->getBufferSize(); +} + +static double host_get_sample_rate(const NativeHostHandle handle) +{ + return static_cast(handle)->getSampleRate(); +} + +static bool host_is_offline(NativeHostHandle) +{ + return false; +} + +static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle) +{ + return static_cast(handle)->getTimeInfo(); +} + +static bool host_write_midi_event(NativeHostHandle handle, const NativeMidiEvent* event) +{ + return false; +} + +static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode, + int32_t index, intptr_t value, void* ptr, float opt) +{ + switch (opcode) + { + case NATIVE_HOST_OPCODE_UI_RESIZE: + static_cast(handle)->resizeUI(index, value); + break; + default: + break; + } + + return 0; +} + /* ------------------------------------------------------------------------------------------------------------ * Plugin entry point, called by DPF to create a new plugin instance. */ diff --git a/plugins/Common/IldaeilUI.cpp b/plugins/Common/IldaeilUI.cpp index 3a37eab..48ff771 100644 --- a/plugins/Common/IldaeilUI.cpp +++ b/plugins/Common/IldaeilUI.cpp @@ -15,32 +15,105 @@ * For a full copy of the GNU General Public License see the LICENSE file. */ +#include "CarlaNativePlugin.h" + +#include +#include + +#include "../FX/DistrhoPluginInfo.h" + #include "DistrhoUI.hpp" +#include "DistrhoPlugin.hpp" #include "ResizeHandle.hpp" START_NAMESPACE_DISTRHO +class IldaeilPlugin : public Plugin +{ +public: + const NativePluginDescriptor* fCarlaPluginDescriptor; + NativePluginHandle fCarlaPluginHandle; + + NativeHostDescriptor fCarlaHostDescriptor; + CarlaHostHandle fCarlaHostHandle; + + UI* fUI; + + // ... +}; + // ----------------------------------------------------------------------------------------------------------- +// shared resource pointer +// carla_juce_init(); + class IldaeilUI : public UI { - void* fContext; - ResizeHandle fResizeHandle; + IldaeilPlugin* const fPlugin; + // ResizeHandle fResizeHandle; + + uint fPluginCount; + uint fPluginSelected; + + ::Window fHostWindowLookingToResize; public: IldaeilUI() : UI(1280, 720), - fContext(getPluginInstancePointer()), - fResizeHandle(this) + fPlugin((IldaeilPlugin*)getPluginInstancePointer()), + // fResizeHandle(this), + fPluginCount(0), + fPluginSelected(0), + fHostWindowLookingToResize(0) { + using namespace CarlaBackend; + + if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) + return; + + const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; + + if (carla_get_current_plugin_count(handle) != 0) + { + const CarlaPluginInfo* const info = carla_get_plugin_info(handle, 0); + + if (info->hints & PLUGIN_HAS_CUSTOM_UI) // FIXME use PLUGIN_HAS_CUSTOM_EMBED_UI + { + const uintptr_t winId = getWindow().getNativeWindowHandle(); + carla_embed_custom_ui(handle, 0, (void*)winId); + + fHostWindowLookingToResize = (::Window)winId; + tryResizingToChildWindowContent(); + } + } + + // start cache/lookup, maybe spawn thread for this? + fPluginCount = carla_get_cached_plugin_count(PLUGIN_LV2, nullptr); + for (uint i=0; ifUI = nullptr; + + if (fPlugin->fCarlaHostHandle != nullptr) + carla_show_custom_ui(fPlugin->fCarlaHostHandle, 0, false); + } } void onImGuiDisplay() override { + if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) + return; + + const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; + + if (carla_get_current_plugin_count(handle) != 0) + return; + float width = getWidth(); float height = getHeight(); float margin = 20.0f; @@ -48,8 +121,99 @@ public: ImGui::SetNextWindowPos(ImVec2(margin, margin)); ImGui::SetNextWindowSize(ImVec2(width - 2 * margin, height - 2 * margin)); - if (ImGui::Begin("Plugin List")) + if (ImGui::Begin("Plugin List", nullptr, ImGuiWindowFlags_NoResize)) { + static char searchBuf[0xff] = "Search..."; + ImGui::InputText("", searchBuf, sizeof(searchBuf)-1, ImGuiInputTextFlags_CharsNoBlank|ImGuiInputTextFlags_AutoSelectAll); + + using namespace CarlaBackend; + + if (ImGui::Button("Load Plugin")) + { + do { + const CarlaCachedPluginInfo* info = carla_get_cached_plugin_info(PLUGIN_LV2, fPluginSelected); + DISTRHO_SAFE_ASSERT_BREAK(info != nullptr); + + const char* const slash = std::strchr(info->label, DISTRHO_OS_SEP); + DISTRHO_SAFE_ASSERT_BREAK(slash != nullptr); + + d_stdout("Loading %s...", info->name); + + if (carla_add_plugin(handle, BINARY_NATIVE, PLUGIN_LV2, nullptr, nullptr, + slash+1, 0, 0x0, PLUGIN_OPTIONS_NULL)) + { + const CarlaPluginInfo* const info = carla_get_plugin_info(handle, 0); + + if (info->hints & PLUGIN_HAS_CUSTOM_UI) // FIXME use PLUGIN_HAS_CUSTOM_EMBED_UI + { + const uintptr_t winId = getWindow().getNativeWindowHandle(); + carla_embed_custom_ui(handle, 0, (void*)winId); + + fHostWindowLookingToResize = (::Window)winId; + tryResizingToChildWindowContent(); + } + + repaint(); + } + + } while (false); + } + + if (ImGui::BeginChild("pluginlistwindow")) + { + if (ImGui::BeginTable("pluginlist", 3, ImGuiTableFlags_NoSavedSettings|ImGuiTableFlags_NoClip)) + { + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Bundle"); + ImGui::TableSetupColumn("URI"); + ImGui::TableHeadersRow(); + + const char* const search = searchBuf[0] != 0 && std::strcmp(searchBuf, "Search...") != 0 ? searchBuf : nullptr; + + if (fPluginCount != 0) + { + for (uint i=0; imidiIns != 1 || info->audioOuts != 2) + continue; + #elif DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + if (info->midiIns != 1 || info->midiOuts != 1) + continue; + if (info->audioIns != 0 || info->audioOuts != 0) + continue; + #else + if (info->audioIns != 2 || info->audioOuts != 2) + continue; + #endif + + const char* const slash = std::strchr(info->label, DISTRHO_OS_SEP); + DISTRHO_SAFE_ASSERT_CONTINUE(slash != nullptr); + + if (search != nullptr && strcasestr(info->name, search) == nullptr) + continue; + + bool selected = fPluginSelected == i; + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Selectable(info->name, &selected); + ImGui::TableSetColumnIndex(1); + ImGui::Selectable(slash+1, &selected); + ImGui::TableSetColumnIndex(2); + ImGui::TextUnformatted(info->label, slash); + + if (selected) + fPluginSelected = i; + } + } + + ImGui::EndTable(); + } + ImGui::EndChild(); + } } ImGui::End(); @@ -57,6 +221,80 @@ public: void uiIdle() override { + if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) + return; + + fPlugin->fCarlaPluginDescriptor->ui_idle(fPlugin->fCarlaPluginHandle); + + if (fHostWindowLookingToResize == 0) + return; + tryResizingToChildWindowContent(); + } + +private: + void tryResizingToChildWindowContent() + { + if (::Display* const display = XOpenDisplay(nullptr)) + { + if (const ::Window childWindow = getChildWindow(display, fHostWindowLookingToResize)) + { + d_stdout("found child window"); + + XSizeHints sizeHints; + memset(&sizeHints, 0, sizeof(sizeHints)); + + if (XGetNormalHints(display, childWindow, &sizeHints)) + { + int width = 0; + int height = 0; + + if (sizeHints.flags & PSize) + { + width = sizeHints.width; + height = sizeHints.height; + } + else if (sizeHints.flags & PBaseSize) + { + width = sizeHints.base_width; + height = sizeHints.base_height; + } + else if (sizeHints.flags & PMinSize) + { + width = sizeHints.min_width; + height = sizeHints.min_height; + } + + d_stdout("child window bounds %u %u", width, height); + + if (width > 1 && height > 1) + { + fHostWindowLookingToResize = 0; + setSize(static_cast(width), static_cast(height)); + } + } + else + d_stdout("child window without bounds"); + } + + XCloseDisplay(display); + } + } + + ::Window getChildWindow(::Display* const display, const ::Window hostWindow) const + { + ::Window rootWindow, parentWindow, ret = 0; + ::Window* childWindows = nullptr; + uint numChildren = 0; + + XQueryTree(display, hostWindow, &rootWindow, &parentWindow, &childWindows, &numChildren); + + if (numChildren > 0 && childWindows != nullptr) + { + ret = childWindows[0]; + XFree(childWindows); + } + + return ret; } protected: diff --git a/plugins/Common/ResizeHandle.hpp b/plugins/Common/ResizeHandle.hpp deleted file mode 100644 index 3753b3d..0000000 --- a/plugins/Common/ResizeHandle.hpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Resize handle for DPF - * Copyright (C) 2021 Filipe Coelho - * - * 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. - */ - -#pragma once - -#include "TopLevelWidget.hpp" -#include "../dgl/Color.hpp" - -START_NAMESPACE_DGL - -/** Resize handle for DPF windows, will sit on bottom-right. */ -class ResizeHandle : public TopLevelWidget -{ -public: - /** Constructor for placing this handle on top of a window. */ - explicit ResizeHandle(Window& window) - : TopLevelWidget(window), - handleSize(16), - resizing(false) - { - resetArea(); - } - - /** Overloaded constructor, will fetch the window from an existing top-level widget. */ - explicit ResizeHandle(TopLevelWidget* const tlw) - : TopLevelWidget(tlw->getWindow()), - handleSize(16), - resizing(false) - { - resetArea(); - } - - /** Set the handle size, minimum 16. */ - void setHandleSize(const uint size) - { - handleSize = std::max(16u, size); - resetArea(); - } - -protected: - void onDisplay() override - { - const GraphicsContext& context(getGraphicsContext()); - const double lineWidth = 1.0 * getScaleFactor(); - -#ifdef DGL_OPENGL - // glUseProgram(0); - glMatrixMode(GL_MODELVIEW); -#endif - - // draw white lines, 1px wide - Color(1.0f, 1.0f, 1.0f).setFor(context); - l1.draw(context, lineWidth); - l2.draw(context, lineWidth); - l3.draw(context, lineWidth); - - // draw black lines, offset by 1px and 1px wide - Color(0.0f, 0.0f, 0.0f).setFor(context); - Line l1b(l1), l2b(l2), l3b(l3); - l1b.moveBy(lineWidth, lineWidth); - l2b.moveBy(lineWidth, lineWidth); - l3b.moveBy(lineWidth, lineWidth); - l1b.draw(context, lineWidth); - l2b.draw(context, lineWidth); - l3b.draw(context, lineWidth); - } - - bool onMouse(const MouseEvent& ev) override - { - if (ev.button != 1) - return false; - - if (ev.press && area.contains(ev.pos)) - { - resizing = true; - resizingSize = Size(getWidth(), getHeight()); - lastResizePoint = ev.pos; - return true; - } - - if (resizing && ! ev.press) - { - resizing = false; - return true; - } - - return false; - } - - bool onMotion(const MotionEvent& ev) override - { - if (! resizing) - return false; - - const Size offset(ev.pos.getX() - lastResizePoint.getX(), - ev.pos.getY() - lastResizePoint.getY()); - - resizingSize += offset; - lastResizePoint = ev.pos; - - // TODO min width, min height - const uint minWidth = 16; - const uint minHeight = 16; - - if (resizingSize.getWidth() < minWidth) - resizingSize.setWidth(minWidth); - if (resizingSize.getWidth() > 16384) - resizingSize.setWidth(16384); - if (resizingSize.getHeight() < minHeight) - resizingSize.setHeight(minHeight); - if (resizingSize.getHeight() > 16384) - resizingSize.setHeight(16384); - - setSize(resizingSize.getWidth(), resizingSize.getHeight()); - return true; - } - - void onResize(const ResizeEvent& ev) override - { - TopLevelWidget::onResize(ev); - resetArea(); - } - -private: - Rectangle area; - Line l1, l2, l3; - uint handleSize; - - // event handling state - bool resizing; - Point lastResizePoint; - Size resizingSize; - - void resetArea() - { - const double scaleFactor = getScaleFactor(); - const uint margin = 0.0 * scaleFactor; - const uint size = handleSize * scaleFactor; - - area = Rectangle(getWidth() - size - margin, - getHeight() - size - margin, - size, size); - - recreateLines(area.getX(), area.getY(), size); - } - - void recreateLines(const uint x, const uint y, const uint size) - { - uint linesize = size; - uint offset = 0; - - // 1st line, full diagonal size - l1.setStartPos(x + size, y); - l1.setEndPos(x, y + size); - - // 2nd line, bit more to the right and down, cropped - offset += size / 3; - linesize -= size / 3; - l2.setStartPos(x + linesize + offset, y + offset); - l2.setEndPos(x + offset, y + linesize + offset); - - // 3rd line, even more right and down - offset += size / 3; - linesize -= size / 3; - l3.setStartPos(x + linesize + offset, y + offset); - l3.setEndPos(x + offset, y + linesize + offset); - } - - DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ResizeHandle) -}; - -END_NAMESPACE_DGL diff --git a/plugins/FX/.kdev_include_paths b/plugins/FX/.kdev_include_paths new file mode 100644 index 0000000..338c6cf --- /dev/null +++ b/plugins/FX/.kdev_include_paths @@ -0,0 +1,6 @@ +../Common/ +../../dpf/dgl/ +../../dpf/distrho/ +../../dpf-widgets/generic +../../dpf-widgets/opengl +/usr/include/carla diff --git a/plugins/FX/DistrhoPluginInfo.h b/plugins/FX/DistrhoPluginInfo.h index 9b307e6..c54b279 100644 --- a/plugins/FX/DistrhoPluginInfo.h +++ b/plugins/FX/DistrhoPluginInfo.h @@ -30,7 +30,7 @@ #define DISTRHO_PLUGIN_WANT_MIDI_INPUT 0 #define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0 #define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 -#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 +#define DISTRHO_PLUGIN_WANT_TIMEPOS 1 #define DISTRHO_UI_USE_CUSTOM 1 #define DISTRHO_UI_USER_RESIZABLE 0 #define DISTRHO_UI_CUSTOM_INCLUDE_PATH "DearImGui.hpp" diff --git a/plugins/FX/Makefile b/plugins/FX/Makefile index 8f27d31..5dad9ad 100644 --- a/plugins/FX/Makefile +++ b/plugins/FX/Makefile @@ -25,8 +25,12 @@ FILES_UI = \ include ../../dpf/Makefile.plugins.mk BUILD_CXX_FLAGS += -I../Common +BUILD_CXX_FLAGS += -I../../dpf-widgets/generic BUILD_CXX_FLAGS += -I../../dpf-widgets/opengl +BUILD_CXX_FLAGS += $(shell pkg-config --cflags carla-host-plugin carla-native-plugin carla-utils) +LINK_FLAGS += $(shell pkg-config --libs carla-host-plugin carla-native-plugin carla-utils) + # -------------------------------------------------------------- # Enable all possible plugin types diff --git a/plugins/MIDI/DistrhoPluginInfo.h b/plugins/MIDI/DistrhoPluginInfo.h index d222c25..e365cd7 100644 --- a/plugins/MIDI/DistrhoPluginInfo.h +++ b/plugins/MIDI/DistrhoPluginInfo.h @@ -29,7 +29,7 @@ #define DISTRHO_PLUGIN_WANT_LATENCY 1 #define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1 #define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 1 -#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 +#define DISTRHO_PLUGIN_WANT_TIMEPOS 1 #define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 #define DISTRHO_UI_USE_CUSTOM 1 #define DISTRHO_UI_USER_RESIZABLE 0 diff --git a/plugins/Synth/DistrhoPluginInfo.h b/plugins/Synth/DistrhoPluginInfo.h index 93e8626..fce0e8b 100644 --- a/plugins/Synth/DistrhoPluginInfo.h +++ b/plugins/Synth/DistrhoPluginInfo.h @@ -29,7 +29,7 @@ #define DISTRHO_PLUGIN_WANT_LATENCY 1 #define DISTRHO_PLUGIN_WANT_MIDI_INPUT 1 #define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0 -#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 +#define DISTRHO_PLUGIN_WANT_TIMEPOS 1 #define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 #define DISTRHO_UI_USE_CUSTOM 1 #define DISTRHO_UI_USER_RESIZABLE 0