From 356e952575073a8a1e2aadd0c1df1e2216cbca67 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 24 Jan 2016 15:39:56 +0100 Subject: [PATCH] Find plugin binary when saved filename doesn't exist --- source/backend/engine/CarlaEngine.cpp | 132 +++++++++++++++++++++++--- source/includes/CarlaDefines.h | 12 ++- 2 files changed, 128 insertions(+), 16 deletions(-) diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 44fa6a6a5..7c5b7def6 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -19,7 +19,6 @@ * - complete processRack(): carefully add to input, sorted events * - implement processPatchbay() * - implement oscSend_control_switch_plugins() - * - proper find&load plugins * - something about the peaks? */ @@ -37,11 +36,13 @@ #include "jackbridge/JackBridge.hpp" #include "juce_core/juce_core.h" +using juce::Array; using juce::CharPointer_UTF8; using juce::File; using juce::MemoryOutputStream; using juce::ScopedPointer; using juce::String; +using juce::StringArray; using juce::XmlDocument; using juce::XmlElement; @@ -1844,6 +1845,70 @@ void CarlaEngine::saveProjectInternal(juce::MemoryOutputStream& outStream) const outStream << "\n"; } +static String findBinaryInCustomPath(const char* const searchPath, const char* const binary) +{ + const StringArray searchPaths(StringArray::fromTokens(searchPath, CARLA_OS_SPLIT_STR, "")); + + // try direct filename first + String jbinary(binary); + + // adjust for current platform +#ifdef CARLA_OS_WIN + if (jbinary[0] == '/') + jbinary = "C:" + jbinary.replaceCharacter('/', '\\'); +#else + if (jbinary[1] == ':' && jbinary[2] == '\\') + jbinary = jbinary.substring(2).replaceCharacter('\\', '/'); +#endif + + String filename = File(jbinary).getFileName(); + + int searchFlags = File::findFiles|File::ignoreHiddenFiles; +#ifdef CARLA_OS_MAC + if (filename.endsWith(".vst") || filename.endsWith(".vst3")) + searchFlags |= File::findDirectories; +#endif + + Array results; + for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) + { + const File path(*it); + + results.clear(); + path.findChildFiles(results, searchFlags, true, filename); + + if (results.size() > 0) + return results.getFirst().getFullPathName(); + } + + // try changing extension +#if defined(CARLA_OS_MAC) + if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".so")) + filename = File(jbinary).getFileNameWithoutExtension() + ".dylib"; +#elif defined(CARLA_OS_WIN) + if (filename.endsWithIgnoreCase(".dylib") || filename.endsWithIgnoreCase(".so")) + filename = File(jbinary).getFileNameWithoutExtension() + ".dll"; +#else + if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".dylib")) + filename = File(jbinary).getFileNameWithoutExtension() + ".so"; +#endif + else + return String(); + + for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) + { + const File path(*it); + + results.clear(); + path.findChildFiles(results, searchFlags, true, filename); + + if (results.size() > 0) + return results.getFirst().getFullPathName(); + } + + return String(); +} + bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) { ScopedPointer xmlElement(xmlDoc.getDocumentElement(true)); @@ -2001,23 +2066,66 @@ bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) CARLA_SAFE_ASSERT_CONTINUE(stateSave.type != nullptr); - const void* extraStuff = nullptr; - - // check if using GIG or SF2 16outs - static const char kTrue[] = "true"; - static const char kUse16OutsSuffix[] = " (16 outs)"; + const void* extraStuff = nullptr; + static const char kTrue[] = "true"; - const BinaryType btype(getBinaryTypeFromFile(stateSave.binary)); const PluginType ptype(getPluginTypeFromString(stateSave.type)); - if ((ptype == PLUGIN_GIG || ptype == PLUGIN_SF2) && CarlaString(stateSave.label).endsWith(kUse16OutsSuffix)) + switch (ptype) { - extraStuff = kTrue; + case PLUGIN_GIG: + case PLUGIN_SF2: + if (CarlaString(stateSave.label).endsWith(" (16 outs)")) + extraStuff = kTrue; + // nobreak + case PLUGIN_LADSPA: + case PLUGIN_DSSI: + case PLUGIN_VST2: + case PLUGIN_VST3: + case PLUGIN_SFZ: + if (stateSave.binary != nullptr && stateSave.binary[0] != '\0' && + ! (File::isAbsolutePath(stateSave.binary) && File(stateSave.binary).exists())) + { + const char* searchPath; + + switch (ptype) + { + case PLUGIN_LADSPA: searchPath = pData->options.pathLADSPA; break; + case PLUGIN_DSSI: searchPath = pData->options.pathDSSI; break; + case PLUGIN_VST2: searchPath = pData->options.pathVST2; break; + case PLUGIN_VST3: searchPath = pData->options.pathVST3; break; + case PLUGIN_GIG: searchPath = pData->options.pathGIG; break; + case PLUGIN_SF2: searchPath = pData->options.pathSF2; break; + case PLUGIN_SFZ: searchPath = pData->options.pathSFZ; break; + default: searchPath = nullptr; break; + } + + if (searchPath != nullptr && searchPath[0] != '\0') + { + carla_stderr("Plugin binary '%s' doesn't exist on this filesystem, let's look for it...", + stateSave.binary); + + const String result(findBinaryInCustomPath(searchPath, stateSave.binary)); + + if (result.isNotEmpty()) + { + delete [] stateSave.binary; + stateSave.binary = carla_strdup(result.toRawUTF8()); + carla_stderr("Found it! :)"); + } + else + { + carla_stderr("Damn, we failed... :("); + } + } + } + break; + default: + break; } - // TODO - proper find&load plugins - - if (addPlugin(btype, ptype, stateSave.binary, stateSave.name, stateSave.label, stateSave.uniqueId, extraStuff, stateSave.options)) + if (addPlugin(getBinaryTypeFromFile(stateSave.binary), ptype, stateSave.binary, + stateSave.name, stateSave.label, stateSave.uniqueId, extraStuff, stateSave.options)) { if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) { diff --git a/source/includes/CarlaDefines.h b/source/includes/CarlaDefines.h index a8d355a1a..ec368038e 100644 --- a/source/includes/CarlaDefines.h +++ b/source/includes/CarlaDefines.h @@ -255,11 +255,15 @@ private: \ /* Define CARLA_OS_SEP */ #ifdef CARLA_OS_WIN -# define CARLA_OS_SEP '\\' -# define CARLA_OS_SEP_STR "\\" +# define CARLA_OS_SEP '\\' +# define CARLA_OS_SEP_STR "\\" +# define CARLA_OS_SPLIT ';' +# define CARLA_OS_SPLIT_STR ";" #else -# define CARLA_OS_SEP '/' -# define CARLA_OS_SEP_STR "/" +# define CARLA_OS_SEP '/' +# define CARLA_OS_SEP_STR "/" +# define CARLA_OS_SPLIT ':' +# define CARLA_OS_SPLIT_STR ":" #endif /* Useful typedefs */