diff --git a/.gitmodules b/.gitmodules index d5a4ba4..b92c213 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "dpf-widgets"] path = dpf-widgets url = https://github.com/DISTRHO/DPF-Widgets.git +[submodule "carla"] + path = carla + url = git@github.com:falkTX/Carla.git diff --git a/Makefile b/Makefile index ca9e5c7..7f20055 100644 --- a/Makefile +++ b/Makefile @@ -6,14 +6,17 @@ include dpf/Makefile.base.mk -all: dgl plugins gen +all: carla dgl plugins gen # -------------------------------------------------------------- +carla: + $(MAKE) -C carla plugin HAVE_ALSA=false HAVE_DGL=false HAVE_HYLIA=false HAVE_JACK=false HAVE_LIBLO=false HAVE_PYQT=false HAVE_QT4=false HAVE_QT5=false HAVE_QT5PKG=false HAVE_PULSEAUDIO=false USING_JUCE_AUDIO_DEVICES=false + dgl: $(MAKE) -C dpf/dgl opengl -plugins: dgl +plugins: carla dgl $(MAKE) all -C plugins/FX ifneq ($(CROSS_COMPILING),true) @@ -32,6 +35,7 @@ endif # -------------------------------------------------------------- clean: + $(MAKE) clean -C carla $(MAKE) clean -C dpf/dgl $(MAKE) clean -C dpf/utils/lv2-ttl-generator $(MAKE) clean -C plugins/FX @@ -39,4 +43,4 @@ clean: # -------------------------------------------------------------- -.PHONY: plugins +.PHONY: carla plugins diff --git a/carla b/carla new file mode 160000 index 0000000..db46099 --- /dev/null +++ b/carla @@ -0,0 +1 @@ +Subproject commit db46099c084af7a90a1a5df31a7d5b11ed0a4dd8 diff --git a/plugins/Common/IldaeilPlugin.cpp b/plugins/Common/IldaeilPlugin.cpp index 0faa341..3b9e364 100644 --- a/plugins/Common/IldaeilPlugin.cpp +++ b/plugins/Common/IldaeilPlugin.cpp @@ -35,6 +35,7 @@ static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpc class IldaeilPlugin : public Plugin { +public: const NativePluginDescriptor* fCarlaPluginDescriptor; NativePluginHandle fCarlaPluginHandle; @@ -45,7 +46,11 @@ class IldaeilPlugin : public Plugin UI* fUI; -public: + void setUI(UI* const ui) + { + fUI = ui; + } + IldaeilPlugin() : Plugin(0, 0, 0), fCarlaPluginDescriptor(nullptr), @@ -60,7 +65,7 @@ public: memset(&fCarlaTimeInfo, 0, sizeof(fCarlaTimeInfo)); fCarlaHostDescriptor.handle = this; - fCarlaHostDescriptor.resourceDir = carla_get_library_folder(); + fCarlaHostDescriptor.resourceDir = "/Users/falktx/Source/Ildaeil"; // carla_get_library_folder(); fCarlaHostDescriptor.uiName = "Ildaeil"; fCarlaHostDescriptor.uiParentId = 0; @@ -118,6 +123,7 @@ public: { DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); + d_stdout("resizing ui to %u %u", width, height); fUI->setSize(width, height); } diff --git a/plugins/Common/IldaeilUI.cpp b/plugins/Common/IldaeilUI.cpp index 73eeb5b..69eb0b0 100644 --- a/plugins/Common/IldaeilUI.cpp +++ b/plugins/Common/IldaeilUI.cpp @@ -17,14 +17,12 @@ #include "CarlaNativePlugin.h" -#include -#include - #include "../FX/DistrhoPluginInfo.h" #include "DistrhoUI.hpp" #include "DistrhoPlugin.hpp" -#include "ResizeHandle.hpp" +#include "SizeUtils.hpp" +#include "extra/Thread.hpp" START_NAMESPACE_DISTRHO @@ -39,81 +37,168 @@ public: UI* fUI; + void setUI(UI* const ui) + { + fUI = ui; + } + // ... }; // ----------------------------------------------------------------------------------------------------------- +using namespace CarlaBackend; + // shared resource pointer // carla_juce_init(); -class IldaeilUI : public UI +class IldaeilUI : public UI, public Thread { + enum { + kDrawingInit, + kDrawingError, + kDrawingLoading, + kDrawingPluginList, + kDrawingPluginCustomUI, + kDrawingPluginGenericUI + } fDrawingState; + IldaeilPlugin* const fPlugin; - // ResizeHandle fResizeHandle; uint fPluginCount; uint fPluginSelected; + CarlaCachedPluginInfo* fPlugins; + + bool fPluginSearchActive; + char fPluginSearchString[0xff]; - ::Window fHostWindowLookingToResize; + bool fInitialSizeHasBeenSet; + const uintptr_t fOurWindowId; public: IldaeilUI() : UI(1280, 720), + Thread("IldaeilScanner"), + fDrawingState(kDrawingInit), fPlugin((IldaeilPlugin*)getPluginInstancePointer()), - // fResizeHandle(this), fPluginCount(0), fPluginSelected(0), - fHostWindowLookingToResize(0) + fPlugins(nullptr), + fPluginSearchActive(false), + fInitialSizeHasBeenSet(false), + fOurWindowId(getWindow().getNativeWindowHandle()) { - using namespace CarlaBackend; - if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) + { + fDrawingState = kDrawingError; return; + } + + fPlugin->setUI(this); const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; if (carla_get_current_plugin_count(handle) != 0) { - const CarlaPluginInfo* const info = carla_get_plugin_info(handle, 0); + showPluginUI(handle); + return; + } - 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); + std::strcpy(fPluginSearchString, "Search..."); + } - fHostWindowLookingToResize = (::Window)winId; - tryResizingToChildWindowContent(); - } + ~IldaeilUI() override + { + if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) + return; + + stopThread(-1); + + fPlugin->fUI = nullptr; + + if (fDrawingState == kDrawingPluginCustomUI) + carla_show_custom_ui(fPlugin->fCarlaHostHandle, 0, false); + + delete[] fPlugins; + } + + void showPluginUI(const CarlaHostHandle handle) + { + const CarlaPluginInfo* const info = carla_get_plugin_info(handle, 0); + + if (info->hints & PLUGIN_HAS_CUSTOM_UI) // FIXME use PLUGIN_HAS_CUSTOM_EMBED_UI + { + // carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); + carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, getScaleFactor()*1000, nullptr); + + carla_embed_custom_ui(handle, 0, (void*)fOurWindowId); + + // tryResizingToChildWindowContent(); + fDrawingState = kDrawingPluginCustomUI; } + } - // start cache/lookup, maybe spawn thread for this? - fPluginCount = carla_get_cached_plugin_count(PLUGIN_LV2, nullptr); - for (uint i=0; ifCarlaPluginDescriptor->ui_idle(fPlugin->fCarlaPluginHandle); + + if (! fInitialSizeHasBeenSet) + tryResizingToChildWindowContent(); } - ~IldaeilUI() override + void run() override { - if (fPlugin != nullptr) + fPluginCount = carla_get_cached_plugin_count(PLUGIN_LV2, nullptr); + + if (fPluginCount != 0) { - fPlugin->fUI = nullptr; + fPlugins = new CarlaCachedPluginInfo[fPluginCount]; - if (fPlugin->fCarlaHostHandle != nullptr) - carla_show_custom_ui(fPlugin->fCarlaHostHandle, 0, false); + for (uint i=0; i < fPluginCount && !shouldThreadExit(); ++i) + { + std::memcpy(&fPlugins[i], carla_get_cached_plugin_info(PLUGIN_LV2, i), sizeof(CarlaCachedPluginInfo)); + // TODO fix leaks + fPlugins[i].name = strdup(fPlugins[i].name); + fPlugins[i].label = strdup(fPlugins[i].label); + } } + + if (!shouldThreadExit()) + fDrawingState = kDrawingPluginList; } void onImGuiDisplay() override { - if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) + switch (fDrawingState) + { + case kDrawingPluginList: + break; + case kDrawingError: + // TODO display error message + return; + case kDrawingLoading: + // TODO display loading message return; + default: + 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; @@ -123,37 +208,28 @@ public: 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::InputText("", fPluginSearchString, sizeof(fPluginSearchString)-1, ImGuiInputTextFlags_CharsNoBlank|ImGuiInputTextFlags_AutoSelectAll)) + fPluginSearchActive = true; if (ImGui::Button("Load Plugin")) { do { - const CarlaCachedPluginInfo* info = carla_get_cached_plugin_info(PLUGIN_LV2, fPluginSelected); - DISTRHO_SAFE_ASSERT_BREAK(info != nullptr); + const CarlaCachedPluginInfo& info(fPlugins[fPluginSelected]); - const char* const slash = std::strchr(info->label, DISTRHO_OS_SEP); + const char* const slash = std::strchr(info.label, DISTRHO_OS_SEP); DISTRHO_SAFE_ASSERT_BREAK(slash != nullptr); - d_stdout("Loading %s...", info->name); + 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(); - } - + showPluginUI(handle); repaint(); + + delete[] fPlugins; + fPlugins = nullptr; + fPluginCount = 0; } } while (false); @@ -168,46 +244,44 @@ public: ImGui::TableSetupColumn("URI"); ImGui::TableHeadersRow(); - const char* const search = searchBuf[0] != 0 && std::strcmp(searchBuf, "Search...") != 0 ? searchBuf : nullptr; + const char* const search = fPluginSearchActive && fPluginSearchString[0] != '\0' ? fPluginSearchString : 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; - } + const CarlaCachedPluginInfo& info(fPlugins[i]); + + /* + #if DISTRHO_PLUGIN_IS_SYNTH + if (info.midiIns != 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(); @@ -219,82 +293,16 @@ public: ImGui::End(); } - 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); + const Size size(getChildWindowSize(fOurWindowId)); - if (numChildren > 0 && childWindows != nullptr) + if (size.isValid()) { - ret = childWindows[0]; - XFree(childWindows); + fInitialSizeHasBeenSet = true; + setSize(size); } - - return ret; } protected: @@ -305,7 +313,7 @@ protected: A parameter has changed on the plugin side. This is called by the host to inform the UI about parameter changes. */ - void parameterChanged(uint32_t index, float value) override + void parameterChanged(uint32_t, float) override { } diff --git a/plugins/Common/SizeUtils.cpp b/plugins/Common/SizeUtils.cpp new file mode 100644 index 0000000..fdfae34 --- /dev/null +++ b/plugins/Common/SizeUtils.cpp @@ -0,0 +1,112 @@ +/* + * DISTRHO Ildaeil Plugin + * Copyright (C) 2021 Filipe Coelho + * + * 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 LICENSE file. + */ + +#include "src/DistrhoDefines.h" + +#if defined(DISTRHO_OS_HAIKU) +#elif defined(DISTRHO_OS_MAC) +# import +#elif defined(DISTRHO_OS_WINDOWS) +#else +# include +# include +#endif + +#include "SizeUtils.hpp" + +START_NAMESPACE_DGL + +#if defined(DISTRHO_OS_HAIKU) +#elif defined(DISTRHO_OS_MAC) +#elif defined(DISTRHO_OS_WINDOWS) +#else +::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; +} +#endif + +Size getChildWindowSize(const uintptr_t winId) +{ +#if defined(DISTRHO_OS_HAIKU) +#elif defined(DISTRHO_OS_MAC) + for (NSView* subview in [(NSView*)winId subviews]) + { + // [subview setFrame:NSMakeRect(0, 0, width, height)]; + d_stdout("found subview"); + return Size(subview.frame.size.width, subview.frame.size.height); + } +#elif defined(DISTRHO_OS_WINDOWS) +#else + if (::Display* const display = XOpenDisplay(nullptr)) + { + if (const ::Window childWindow = getChildWindow(display, fOurWindowLookingToResize)) + { + 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) + return Size(static_cast(width), static_cast(height)); + } + else + d_stdout("child window without bounds"); + } + + XCloseDisplay(display); + } +#endif + return Size(0, 0); +} + +END_NAMESPACE_DGL diff --git a/plugins/Common/SizeUtils.hpp b/plugins/Common/SizeUtils.hpp new file mode 100644 index 0000000..828f044 --- /dev/null +++ b/plugins/Common/SizeUtils.hpp @@ -0,0 +1,24 @@ +/* + * DISTRHO Ildaeil Plugin + * Copyright (C) 2021 Filipe Coelho + * + * 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 LICENSE file. + */ + +#include "Geometry.hpp" + +START_NAMESPACE_DGL + +Size getChildWindowSize(uintptr_t winId); + +END_NAMESPACE_DGL diff --git a/plugins/FX/Makefile b/plugins/FX/Makefile index 5dad9ad..36e34d6 100644 --- a/plugins/FX/Makefile +++ b/plugins/FX/Makefile @@ -17,8 +17,39 @@ FILES_DSP = \ FILES_UI = \ IldaeilUI.cpp \ + ../common/SizeUtils.cpp \ ../../dpf-widgets/opengl/DearImGui.cpp +# -------------------------------------------------------------- +# Carla stuff + +CARLA_BUILD_DIR = ../../carla/build +ifeq ($(DEBUG),true) +CARLA_BUILD_TYPE = Debug +else +CARLA_BUILD_TYPE = Release +endif + +EXTRA_LIBS += $(CARLA_BUILD_DIR)/plugin/$(CARLA_BUILD_TYPE)/carla-host-plugin.cpp.o +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/carla_engine_plugin.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/carla_plugin.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/audio_decoder.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/jackbridge.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/lilv.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/native-plugins.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/rtmempool.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/sfzero.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/water.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/zita-resampler.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_audio_basics.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_audio_processors.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_core.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_data_structures.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_events.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_graphics.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_gui_basics.a +EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/juce_gui_extra.a + # -------------------------------------------------------------- # Do some magic @@ -28,8 +59,27 @@ 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) +BUILD_CXX_FLAGS += -DREAL_BUILD +BUILD_CXX_FLAGS += -I../../carla/source/backend +BUILD_CXX_FLAGS += -I../../carla/source/includes + +ifeq ($(MACOS),true) +$(BUILD_DIR)/../common/SizeUtils.cpp.o: BUILD_CXX_FLAGS += -ObjC++ +LINK_FLAGS += -framework AppKit +LINK_FLAGS += -framework Accelerate +LINK_FLAGS += -framework AudioToolbox +LINK_FLAGS += -framework CoreFoundation +LINK_FLAGS += -framework AppKit +LINK_FLAGS += -framework AudioUnit +LINK_FLAGS += -framework CoreAudio +LINK_FLAGS += -framework CoreAudioKit +LINK_FLAGS += -framework Carbon +LINK_FLAGS += -framework QuartzCore +LINK_FLAGS += -framework IOKit +endif + +# 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