diff --git a/Makefile b/Makefile index f0a412a..8c4c2ed 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ endif CARLA_TARGETS = static-plugin ifneq ($(USE_SYSTEM_CARLA_BINS),true) -CARLA_TARGETS += bridges-plugin bridges-ui +CARLA_TARGETS += bridges-plugin bridges-ui discovery ifeq ($(CARLA_EXTRA_TARGETS),true) @@ -157,6 +157,9 @@ else gen: endif +jack: carla dgl + $(MAKE) $(CARLA_EXTRA_ARGS) $(ILDAEIL_FX_ARGS) -C plugins/Standalone + # --------------------------------------------------------------------------------------------------------------------- install: diff --git a/carla b/carla index f1a3053..7321be6 160000 --- a/carla +++ b/carla @@ -1 +1 @@ -Subproject commit f1a30531b9cd50cbbc7c73e6e5cba2e4b9f5555b +Subproject commit 7321be60c6c523cc755b0979571a0a6a5e0c7085 diff --git a/dpf b/dpf index a0963ec..0f43c51 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit a0963ec1555484e2b34ac07bf3815e56136a41fa +Subproject commit 0f43c511160f3301ae52624971112305de4d8aca diff --git a/dpf-widgets b/dpf-widgets index a0aa731..5acb1b9 160000 --- a/dpf-widgets +++ b/dpf-widgets @@ -1 +1 @@ -Subproject commit a0aa73171e2f266a0bde484f4c01bfbdd3b38b4b +Subproject commit 5acb1b9f0424eb2eee73fd759722017cf818cd49 diff --git a/plugins/Common/IldaeilBasePlugin.hpp b/plugins/Common/IldaeilBasePlugin.hpp index b2eca07..8302561 100644 --- a/plugins/Common/IldaeilBasePlugin.hpp +++ b/plugins/Common/IldaeilBasePlugin.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Ildaeil Plugin - * Copyright (C) 2021-2022 Filipe Coelho + * Copyright (C) 2021-2023 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 @@ -20,6 +20,7 @@ #include "CarlaNativePlugin.h" #include "DistrhoPlugin.hpp" #include "extra/Mutex.hpp" +#include "extra/String.hpp" // generates a warning if this is defined as anything else #define CARLA_API @@ -32,7 +33,7 @@ class IldaeilBasePlugin : public Plugin { public: static Mutex sPluginInfoLoadMutex; - static const char* getPathForJSFX(); + static const char* getPluginPath(PluginType ptype); const NativePluginDescriptor* fCarlaPluginDescriptor; NativePluginHandle fCarlaPluginHandle; @@ -40,6 +41,8 @@ public: NativeHostDescriptor fCarlaHostDescriptor; CarlaHostHandle fCarlaHostHandle; + String fDiscoveryTool; + void* fUI; IldaeilBasePlugin() diff --git a/plugins/Common/IldaeilPlugin.cpp b/plugins/Common/IldaeilPlugin.cpp index 9cee6b4..2f81222 100644 --- a/plugins/Common/IldaeilPlugin.cpp +++ b/plugins/Common/IldaeilPlugin.cpp @@ -47,14 +47,161 @@ Mutex IldaeilBasePlugin::sPluginInfoLoadMutex; // -------------------------------------------------------------------------------------------------------------------- -const char* IldaeilBasePlugin::getPathForJSFX() +#ifndef CARLA_OS_WIN +static water::String getHomePath() +{ + static water::String path(water::File::getSpecialLocation(water::File::userHomeDirectory).getFullPathName()); + return path; +} +#endif + +static const char* getPathForLADSPA() +{ + static water::String path; + + if (path.isEmpty()) + { + #if defined(CARLA_OS_HAIKU) + path = getHomePath() + "/.ladspa:/system/add-ons/media/ladspaplugins:/system/lib/ladspa"; + #elif defined(CARLA_OS_MAC) + ladspa = getHomePath() + "/Library/Audio/Plug-Ins/LADSPA:/Library/Audio/Plug-Ins/LADSPA"; + #elif defined(CARLA_OS_WASM) + path = "/ladspa"; + #elif defined(CARLA_OS_WIN) + path = water::File::getSpecialLocation(water::File::winAppData).getFullPathName() + "\\LADSPA;"; + path += water::File::getSpecialLocation(water::File::winProgramFiles).getFullPathName() + "\\LADSPA"; + #else + path = getHomePath() + "/.ladspa:/usr/lib/ladspa:/usr/local/lib/ladspa"; + #endif + } + + return path.toRawUTF8(); +} + +static const char* getPathForDSSI() +{ + static water::String path; + + if (path.isEmpty()) + { + #if defined(CARLA_OS_HAIKU) + path = getHomePath() + "/.dssi:/system/add-ons/media/dssiplugins:/system/lib/dssi"; + #elif defined(CARLA_OS_MAC) + path = getHomePath() + "/Library/Audio/Plug-Ins/DSSI:/Library/Audio/Plug-Ins/DSSI"; + #elif defined(CARLA_OS_WASM) + path = "/dssi"; + #elif defined(CARLA_OS_WIN) + path = water::File::getSpecialLocation(water::File::winAppData).getFullPathName() + "\\DSSI;"; + path += water::File::getSpecialLocation(water::File::winProgramFiles).getFullPathName() + "\\DSSI"; + #else + path = getHomePath() + "/.dssi:/usr/lib/dssi:/usr/local/lib/dssi"; + #endif + } + + return path.toRawUTF8(); +} + +static const char* getPathForLV2() +{ + static water::String path; + + if (path.isEmpty()) + { + #if defined(CARLA_OS_HAIKU) + path = getHomePath() + "/.lv2:/system/add-ons/media/lv2plugins"; + #elif defined(CARLA_OS_MAC) + path = getHomePath() + "/Library/Audio/Plug-Ins/LV2:/Library/Audio/Plug-Ins/LV2"; + #elif defined(CARLA_OS_WASM) + path = "/lv2"; + #elif defined(CARLA_OS_WIN) + path = water::File::getSpecialLocation(water::File::winAppData).getFullPathName() + "\\LV2;"; + path += water::File::getSpecialLocation(water::File::winCommonProgramFiles).getFullPathName() + "\\LV2"; + #else + path = getHomePath() + "/.lv2:/usr/lib/lv2:/usr/local/lib/lv2"; + #endif + } + + return path.toRawUTF8(); +} + +static const char* getPathForVST2() +{ + static water::String path; + + if (path.isEmpty()) + { + #if defined(CARLA_OS_HAIKU) + path = getHomePath() + "/.vst:/system/add-ons/media/vstplugins"; + #elif defined(CARLA_OS_MAC) + path = getHomePath() + "/Library/Audio/Plug-Ins/VST:/Library/Audio/Plug-Ins/VST"; + #elif defined(CARLA_OS_WASM) + path = "/vst"; + #elif defined(CARLA_OS_WIN) + path = water::File::getSpecialLocation(water::File::winProgramFiles).getFullPathName() + "\\VstPlugins;"; + path += water::File::getSpecialLocation(water::File::winProgramFiles).getFullPathName() + "\\Steinberg\\VstPlugins;"; + path += water::File::getSpecialLocation(water::File::winCommonProgramFiles).getFullPathName() + "\\VST2"; + #else + path = getHomePath() + "/.vst:/usr/lib/vst:/usr/local/lib/vst"; + #endif + } + + return path.toRawUTF8(); +} + +static const char* getPathForVST3() +{ + static water::String path; + + if (path.isEmpty()) + { + #if defined(CARLA_OS_HAIKU) + path = getHomePath() + "/.vst3:/system/add-ons/media/dssiplugins"; + #elif defined(CARLA_OS_MAC) + path = getHomePath() + "/Library/Audio/Plug-Ins/VST3:/Library/Audio/Plug-Ins/VST3"; + #elif defined(CARLA_OS_WASM) + path = "/vst3"; + #elif defined(CARLA_OS_WIN) + path = water::File::getSpecialLocation(water::File::winAppData).getFullPathName() + "\\VST3;"; + path += water::File::getSpecialLocation(water::File::winCommonProgramFiles).getFullPathName() + "\\VST3"; + #else + path = getHomePath() + "/.vst3:/usr/lib/vst3:/usr/local/lib/vst3"; + #endif + } + + return path.toRawUTF8(); +} + +static const char* getPathForCLAP() +{ + static water::String path; + + if (path.isEmpty()) + { + #if defined(CARLA_OS_HAIKU) + path = getHomePath() + "/.clap:/system/add-ons/media/clapplugins"; + #elif defined(CARLA_OS_MAC) + path = getHomePath() + "/Library/Audio/Plug-Ins/CLAP:/Library/Audio/Plug-Ins/CLAP"; + #elif defined(CARLA_OS_WASM) + path = "/clap"; + #elif defined(CARLA_OS_WIN) + path = water::File::getSpecialLocation(water::File::winAppData).getFullPathName() + "\\CLAP;"; + path += water::File::getSpecialLocation(water::File::winCommonProgramFiles).getFullPathName() + "\\CLAP"; + #else + path = getHomePath() + "/.clap:/usr/lib/clap:/usr/local/lib/clap"; + #endif + } + + return path.toRawUTF8(); +} + +static const char* getPathForJSFX() { static water::String path; if (path.isEmpty()) { #if defined(CARLA_OS_MAC) - path = water::File::getSpecialLocation(water::File::userHomeDirectory).getFullPathName() + path = getHomePath() + "/Library/Application Support/REAPER/Effects"; if (! water::File(path).isDirectory()) path = "/Applications/REAPER.app/Contents/InstallFiles/Effects"; @@ -69,7 +216,7 @@ const char* IldaeilBasePlugin::getPathForJSFX() if (const char* const configHome = std::getenv("XDG_CONFIG_HOME")) path = configHome; else - path = water::File::getSpecialLocation(water::File::userHomeDirectory).getFullPathName() + "/.config"; + path = getHomePath() + "/.config"; path += "/REAPER/Effects"; #endif } @@ -77,6 +224,41 @@ const char* IldaeilBasePlugin::getPathForJSFX() return path.toRawUTF8(); } +const char* IldaeilBasePlugin::getPluginPath(const PluginType ptype) +{ + switch (ptype) + { + case PLUGIN_LADSPA: + if (const char* const path = std::getenv("LADSPA_PATH")) + return path; + return getPathForLADSPA(); + case PLUGIN_DSSI: + if (const char* const path = std::getenv("DSSI_PATH")) + return path; + return getPathForDSSI(); + case PLUGIN_LV2: + if (const char* const path = std::getenv("LV2_PATH")) + return path; + return getPathForLV2(); + case PLUGIN_VST2: + if (const char* const path = std::getenv("VST_PATH")) + return path; + return getPathForVST2(); + case PLUGIN_VST3: + if (const char* const path = std::getenv("VST3_PATH")) + return path; + return getPathForVST3(); + case PLUGIN_CLAP: + if (const char* const path = std::getenv("CLAP_PATH")) + return path; + return getPathForCLAP(); + case PLUGIN_JSFX: + return getPathForJSFX(); + default: + return nullptr; + } +} + // -------------------------------------------------------------------------------------------------------------------- class IldaeilPlugin : public IldaeilBasePlugin @@ -145,26 +327,34 @@ public: if (bundlePath != nullptr && water::File(bundlePath + water::String(DISTRHO_OS_SEP_STR "carla-bridge-native" EXT)).existsAsFile()) { + fDiscoveryTool = bundlePath; carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_BINARIES, 0, bundlePath); // carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_RESOURCES, 0, ""); } else { #ifdef CARLA_OS_MAC + fDiscoveryTool = "/Applications/Carla.app/Contents/MacOS"; carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_BINARIES, 0, "/Applications/Carla.app/Contents/MacOS"); carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_RESOURCES, 0, "/Applications/Carla.app/Contents/MacOS/resources"); #else + fDiscoveryTool = "/usr/lib/carla"; carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_BINARIES, 0, "/usr/lib/carla"); carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PATH_RESOURCES, 0, "/usr/share/carla/resources"); #endif } - #undef EXT + fDiscoveryTool += DISTRHO_OS_SEP_STR "carla-discovery-native" EXT; - if (const char* const path = std::getenv("LV2_PATH")) - carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LV2, path); + #undef EXT - carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, getPathForJSFX()); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LADSPA, getPluginPath(PLUGIN_LADSPA)); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, getPluginPath(PLUGIN_DSSI)); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LV2, getPluginPath(PLUGIN_LV2)); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST2, getPluginPath(PLUGIN_VST2)); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, getPluginPath(PLUGIN_VST3)); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_CLAP, getPluginPath(PLUGIN_CLAP)); + carla_set_engine_option(fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, getPluginPath(PLUGIN_JSFX)); fCarlaPluginDescriptor->dispatcher(fCarlaPluginHandle, NATIVE_PLUGIN_OPCODE_HOST_USES_EMBED, 0, 0, nullptr, 0.0f); diff --git a/plugins/Common/IldaeilUI.cpp b/plugins/Common/IldaeilUI.cpp index af2bca6..f6c4932 100644 --- a/plugins/Common/IldaeilUI.cpp +++ b/plugins/Common/IldaeilUI.cpp @@ -29,6 +29,7 @@ // IDE helper #include "DearImGui.hpp" +#include #include // strcasestr @@ -64,18 +65,11 @@ class IldaeilUI : public UI, static constexpr const uint kButtonHeight = 20; struct PluginInfoCache { - char* name; - char* label; - - PluginInfoCache() - : name(nullptr), - label(nullptr) {} - - ~PluginInfoCache() - { - std::free(name); - std::free(label); - } + BinaryType btype; + uint64_t uniqueId; + std::string filename; + std::string name; + std::string label; }; struct PluginGenericUI { @@ -164,7 +158,6 @@ class IldaeilUI : public UI, PluginType fPluginType; PluginType fNextPluginType; - uint fPluginCount; uint fPluginId; int fPluginSelected; bool fPluginScanningFinished; @@ -174,7 +167,9 @@ class IldaeilUI : public UI, bool fPluginHasOutputParameters; bool fPluginRunning; bool fPluginWillRunInBridgeMode; - PluginInfoCache* fPlugins; + Mutex fPluginsMutex; + PluginInfoCache fCurrentPluginInfo; + std::vector fPlugins; ScopedPointer fPluginGenericUI; bool fPluginSearchActive; @@ -186,19 +181,21 @@ class IldaeilUI : public UI, struct RunnerData { bool needsReinit; - uint pluginCount; - uint pluginIndex; + CarlaPluginDiscoveryHandle handle; RunnerData() : needsReinit(true), - pluginCount(0), - pluginIndex(0) {} + handle(nullptr) {} void init() { needsReinit = true; - pluginCount = 0; - pluginIndex = 0; + + if (handle != nullptr) + { + carla_plugin_discovery_stop(handle); + handle = nullptr; + } } } fRunnerData; @@ -212,7 +209,6 @@ public: fPluginHostWindow(getWindow(), this), fPluginType(PLUGIN_LV2), fNextPluginType(fPluginType), - fPluginCount(0), fPluginId(0), fPluginSelected(-1), fPluginScanningFinished(false), @@ -222,7 +218,7 @@ public: fPluginHasOutputParameters(false), fPluginRunning(false), fPluginWillRunInBridgeMode(false), - fPlugins(nullptr), + fCurrentPluginInfo(), fPluginSearchActive(false), fPluginSearchFirstShow(false), fRunnerData() @@ -305,8 +301,6 @@ public: stopRunner(); fPluginGenericUI = nullptr; - - delete[] fPlugins; } bool checkIfPluginIsLoaded() @@ -564,7 +558,7 @@ public: } } - void loadPlugin(const CarlaHostHandle handle, const char* const label) + bool loadPlugin(const CarlaHostHandle handle, const PluginInfoCache& info) { if (fPluginRunning || fPluginId != 0) { @@ -576,8 +570,17 @@ public: const MutexLocker cml(fPlugin->sPluginInfoLoadMutex); - if (carla_add_plugin(handle, BINARY_NATIVE, fPluginType, nullptr, nullptr, - label, 0, 0x0, PLUGIN_OPTIONS_NULL)) + const bool ok = carla_add_plugin(handle, + info.btype, + fPluginType, + info.filename.c_str(), + info.name.c_str(), + info.label.c_str(), + info.uniqueId, + nullptr, + PLUGIN_OPTIONS_NULL); + + if (ok) { fPluginRunning = true; fPluginGenericUI = nullptr; @@ -604,6 +607,7 @@ public: } repaint(); + return ok; } void loadFileAsPlugin(const CarlaHostHandle handle, const char* const filename) @@ -691,7 +695,7 @@ protected: if (fPluginFilename.isNotEmpty()) loadFileAsPlugin(handle, fPluginFilename.buffer()); else - loadPlugin(handle, carla_get_plugin_info(handle, fPluginId)->label); + loadPlugin(handle, fCurrentPluginInfo); break; case kIdleOpenFileUI: @@ -749,32 +753,16 @@ protected: { DISTRHO_SAFE_ASSERT_RETURN(fPluginSelected >= 0,); - const PluginInfoCache& info(fPlugins[fPluginSelected]); - - const char* label = nullptr; - - switch (fPluginType) + PluginInfoCache info; { - case PLUGIN_INTERNAL: - case PLUGIN_AU: - case PLUGIN_JSFX: - case PLUGIN_SFZ: - label = info.label; - break; - case PLUGIN_LV2: { - const char* const slash = std::strchr(info.label, DISTRHO_OS_SEP); - DISTRHO_SAFE_ASSERT_RETURN(slash != nullptr,); - label = slash+1; - break; - } - default: - break; + const MutexLocker cml(fPluginsMutex); + info = fPlugins[fPluginSelected]; } - DISTRHO_SAFE_ASSERT_RETURN(label != nullptr,); + d_stdout("Loading %s...", info.name.c_str()); - d_stdout("Loading %s...", info.name); - loadPlugin(handle, label); + if (loadPlugin(handle, info)) + fCurrentPluginInfo = info; } void uiFileBrowserSelected(const char* const filename) override @@ -802,30 +790,21 @@ protected: if (fRunnerData.needsReinit) { fRunnerData.needsReinit = false; + fPluginScanningFinished = false; - const char* path; - switch (fPluginType) { - case PLUGIN_LV2: - path = std::getenv("LV2_PATH"); - break; - case PLUGIN_JSFX: - path = fPlugin->getPathForJSFX(); - break; - default: - path = nullptr; - break; + const MutexLocker cml(fPluginsMutex); + fPlugins.clear(); } - fPluginCount = 0; - delete[] fPlugins; - { const MutexLocker cml(fPlugin->sPluginInfoLoadMutex); d_stdout("Will scan plugins now..."); - fRunnerData.pluginCount = carla_get_cached_plugin_count(fPluginType, path); - d_stdout("Scanning found %u plugins", fRunnerData.pluginCount); + fRunnerData.handle = carla_plugin_discovery_start(fPlugin->fDiscoveryTool, + fPluginType, + IldaeilBasePlugin::getPluginPath(fPluginType), + _binaryPluginSearchCallback, this); } if (fDrawingState == kDrawingLoading) @@ -834,99 +813,109 @@ protected: fPluginSearchFirstShow = true; } - if (fRunnerData.pluginCount != 0) + if (fRunnerData.handle == nullptr) { - fPlugins = new PluginInfoCache[fRunnerData.pluginCount]; - fPluginScanningFinished = false; - return true; - } - else - { - fPlugins = nullptr; + d_stdout("Nothing found!"); fPluginScanningFinished = true; return false; } } - const uint index = fRunnerData.pluginIndex++; - DISTRHO_SAFE_ASSERT_UINT2_RETURN(index < fRunnerData.pluginCount, - index, fRunnerData.pluginCount, false); + DISTRHO_SAFE_ASSERT_RETURN(!fPluginScanningFinished, false); + DISTRHO_SAFE_ASSERT_RETURN(fRunnerData.handle != nullptr, false); - do { + bool ok; + { const MutexLocker cml(fPlugin->sPluginInfoLoadMutex); + ok = carla_plugin_discovery_idle(fRunnerData.handle); + } - const CarlaCachedPluginInfo* const info = carla_get_cached_plugin_info(fPluginType, index); - DISTRHO_SAFE_ASSERT_RETURN(info != nullptr, true); + if (ok) + return true; - if (! info->valid) - break; - if (info->cvIns != 0 || info->cvOuts != 0) - break; + // stop here + { + const MutexLocker cml(fPlugin->sPluginInfoLoadMutex); + d_stdout("Found %lu plugins!", (ulong)fPlugins.size()); + carla_plugin_discovery_stop(fRunnerData.handle); + fRunnerData.handle = nullptr; + } - #if ILDAEIL_STANDALONE - if (info->midiIns != 0 && info->midiIns != 1) - break; - if (info->midiOuts != 0 && info->midiOuts != 1) - break; - if (info->audioIns > 2 || info->audioOuts > 2) - break; - if (fPluginType == PLUGIN_INTERNAL) - { - if (std::strcmp(info->label, "audiogain") == 0) - break; - if (std::strcmp(info->label, "midichanfilter") == 0) - break; - if (std::strcmp(info->label, "midichannelize") == 0) - break; - } - #elif DISTRHO_PLUGIN_IS_SYNTH - if (info->midiIns != 1 && info->audioIns != 0) - break; - if ((info->hints & PLUGIN_IS_SYNTH) == 0x0 && info->audioIns != 0) - break; - if (info->audioOuts != 1 && info->audioOuts != 2) - break; - #elif DISTRHO_PLUGIN_WANT_MIDI_OUTPUT - if ((info->midiIns != 1 && info->audioIns != 0 && info->audioOuts != 0) || info->midiOuts != 1) - break; - if (info->audioIns != 0 || info->audioOuts != 0) - break; - #else - if (info->audioIns != 1 && info->audioIns != 2) - break; - if (info->audioOuts != 1 && info->audioOuts != 2) - break; - #endif + fPluginScanningFinished = true; + return false; + } - if (fPluginType == PLUGIN_INTERNAL) - { - #if !ILDAEIL_STANDALONE - if (std::strcmp(info->label, "audiogain_s") == 0) - break; - #endif - if (std::strcmp(info->label, "lfo") == 0) - break; - if (std::strcmp(info->label, "midi2cv") == 0) - break; - if (std::strcmp(info->label, "midithrough") == 0) - break; - if (std::strcmp(info->label, "3bandsplitter") == 0) - break; - } + void binaryPluginSearchCallback(const CarlaPluginDiscoveryInfo* const info) + { + if (info->io.cvIns != 0 || info->io.cvOuts != 0) + return; + + #if ILDAEIL_STANDALONE + if (info->io.midiIns != 0 && info->io.midiIns != 1) + return; + if (info->io.midiOuts != 0 && info->io.midiOuts != 1) + return; + if (info->io.audioIns > 2 || info->io.audioOuts > 2) + return; + if (fPluginType == PLUGIN_INTERNAL) + { + if (std::strcmp(info->label, "audiogain") == 0) + return; + if (std::strcmp(info->label, "midichanfilter") == 0) + return; + if (std::strcmp(info->label, "midichannelize") == 0) + return; + } + #elif DISTRHO_PLUGIN_IS_SYNTH + if (info->io.midiIns != 1 && info->io.audioIns != 0) + return; + if ((info->metadata.hints & PLUGIN_IS_SYNTH) == 0x0 && info->io.audioIns != 0) + return; + if (info->io.audioOuts != 1 && info->io.audioOuts != 2) + return; + #elif DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + if ((info->io.midiIns != 1 && info->io.audioIns != 0 && info->io.audioOuts != 0) || info->io.midiOuts != 1) + return; + if (info->io.audioIns != 0 || info->io.audioOuts != 0) + return; + #else + if (info->io.audioIns != 1 && info->io.audioIns != 2) + return; + if (info->io.audioOuts != 1 && info->io.audioOuts != 2) + return; + #endif - const uint pindex = fPluginCount; - fPlugins[pindex].name = strdup(info->name); - fPlugins[pindex].label = strdup(info->label); - ++fPluginCount; - } while (false); + if (fPluginType == PLUGIN_INTERNAL) + { + #if !ILDAEIL_STANDALONE + if (std::strcmp(info->label, "audiogain_s") == 0) + return; + #endif + if (std::strcmp(info->label, "lfo") == 0) + return; + if (std::strcmp(info->label, "midi2cv") == 0) + return; + if (std::strcmp(info->label, "midithrough") == 0) + return; + if (std::strcmp(info->label, "3bandsplitter") == 0) + return; + } - // run again - if (fRunnerData.pluginIndex != fRunnerData.pluginCount) - return true; + const PluginInfoCache pinfo = { + info->btype, + info->uniqueId, + info->filename, + info->metadata.name, + info->label, + }; - // stop here - fPluginScanningFinished = true; - return false; + const MutexLocker cml(fPluginsMutex); + fPlugins.push_back(pinfo); + } + + static void _binaryPluginSearchCallback(void* ptr, const CarlaPluginDiscoveryInfo* info) + { + static_cast(ptr)->binaryPluginSearchCallback(info); } void onImGuiDisplay() override @@ -1258,7 +1247,12 @@ protected: { static const char* pluginTypes[] = { getPluginTypeAsString(PLUGIN_INTERNAL), + getPluginTypeAsString(PLUGIN_LADSPA), + getPluginTypeAsString(PLUGIN_DSSI), getPluginTypeAsString(PLUGIN_LV2), + getPluginTypeAsString(PLUGIN_VST2), + getPluginTypeAsString(PLUGIN_VST3), + getPluginTypeAsString(PLUGIN_CLAP), getPluginTypeAsString(PLUGIN_JSFX), "Load from file..." }; @@ -1309,15 +1303,14 @@ protected: int current; switch (fPluginType) { - case PLUGIN_JSFX: - current = 2; - break; - case PLUGIN_LV2: - current = 1; - break; - default: - current = 0; - break; + case PLUGIN_JSFX: current = 7; break; + case PLUGIN_CLAP: current = 6; break; + case PLUGIN_VST3: current = 5; break; + case PLUGIN_VST2: current = 4; break; + case PLUGIN_LV2: current = 3; break; + case PLUGIN_DSSI: current = 2; break; + case PLUGIN_LADSPA: current = 1; break; + default: current = 0; break; } if (ImGui::Combo("##plugintypes", ¤t, pluginTypes, ARRAY_SIZE(pluginTypes))) @@ -1325,18 +1318,15 @@ protected: fIdleState = kIdleChangePluginType; switch (current) { - case 0: - fNextPluginType = PLUGIN_INTERNAL; - break; - case 1: - fNextPluginType = PLUGIN_LV2; - break; - case 2: - fNextPluginType = PLUGIN_JSFX; - break; - case 3: - fNextPluginType = PLUGIN_TYPE_COUNT; - break; + case 0: fNextPluginType = PLUGIN_INTERNAL; break; + case 1: fNextPluginType = PLUGIN_LADSPA; break; + case 2: fNextPluginType = PLUGIN_DSSI; break; + case 3: fNextPluginType = PLUGIN_LV2; break; + case 4: fNextPluginType = PLUGIN_VST2; break; + case 5: fNextPluginType = PLUGIN_VST3; break; + case 6: fNextPluginType = PLUGIN_CLAP; break; + case 7: fNextPluginType = PLUGIN_JSFX; break; + case 8: fNextPluginType = PLUGIN_TYPE_COUNT; break; } } @@ -1372,8 +1362,6 @@ protected: { case PLUGIN_INTERNAL: case PLUGIN_AU: - case PLUGIN_SFZ: - case PLUGIN_JSFX: ImGui::TableSetupColumn("Name"); ImGui::TableSetupColumn("Label"); ImGui::TableHeadersRow(); @@ -1384,14 +1372,19 @@ protected: ImGui::TableHeadersRow(); break; default: + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Filename"); + ImGui::TableHeadersRow(); break; } - for (uint i=0; i= 0 && static_cast(fPluginSelected) == i; @@ -1400,25 +1393,25 @@ protected: { case PLUGIN_INTERNAL: case PLUGIN_AU: - case PLUGIN_JSFX: - case PLUGIN_SFZ: ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - ImGui::Selectable(info.name, &selected); + ImGui::Selectable(info.name.c_str(), &selected); ImGui::TableSetColumnIndex(1); - ImGui::Selectable(info.label, &selected); + ImGui::Selectable(info.label.c_str(), &selected); break; - case PLUGIN_LV2: { - const char* const slash = std::strchr(info.label, DISTRHO_OS_SEP); - DISTRHO_SAFE_ASSERT_CONTINUE(slash != nullptr); + case PLUGIN_LV2: ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - ImGui::Selectable(info.name, &selected); + ImGui::Selectable(info.name.c_str(), &selected); ImGui::TableSetColumnIndex(1); - ImGui::Selectable(slash+1, &selected); + ImGui::Selectable(info.label.c_str(), &selected); break; - } default: + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Selectable(info.name.c_str(), &selected); + ImGui::TableSetColumnIndex(1); + ImGui::Selectable(info.filename.c_str(), &selected); break; } diff --git a/plugins/Common/Makefile.mk b/plugins/Common/Makefile.mk index 42dffda..3762e8f 100644 --- a/plugins/Common/Makefile.mk +++ b/plugins/Common/Makefile.mk @@ -63,7 +63,6 @@ CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/audio_decoder CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/jackbridge.min.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/lilv.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/rtmempool.a -CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/sfzero.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/water.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/ysfx.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/zita-resampler.a @@ -138,6 +137,7 @@ ifneq ($(USE_SYSTEM_CARLA_BINS),true) CARLA_BINARIES = $(CURDIR)/../../carla/bin/carla-bridge-native$(APP_EXT) CARLA_BINARIES += $(CURDIR)/../../carla/bin/carla-bridge-lv2-gtk2$(APP_EXT) CARLA_BINARIES += $(CURDIR)/../../carla/bin/carla-bridge-lv2-gtk3$(APP_EXT) +CARLA_BINARIES = $(CURDIR)/../../carla/bin/carla-discovery-native$(APP_EXT) ifeq ($(CARLA_EXTRA_TARGETS),true)