Signed-off-by: falkTX <falktx@falktx.com>pull/1807/head
| @@ -644,7 +644,6 @@ typedef enum { | |||||
| /*! | /*! | ||||
| * VST3 plugin. | * VST3 plugin. | ||||
| * @note Windows and MacOS only | |||||
| */ | */ | ||||
| PLUGIN_VST3 = 6, | PLUGIN_VST3 = 6, | ||||
| @@ -22,6 +22,7 @@ | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| using CARLA_BACKEND_NAMESPACE::BinaryType; | using CARLA_BACKEND_NAMESPACE::BinaryType; | ||||
| using CARLA_BACKEND_NAMESPACE::EngineOption; | |||||
| using CARLA_BACKEND_NAMESPACE::PluginCategory; | using CARLA_BACKEND_NAMESPACE::PluginCategory; | ||||
| using CARLA_BACKEND_NAMESPACE::PluginType; | using CARLA_BACKEND_NAMESPACE::PluginType; | ||||
| #endif | #endif | ||||
| @@ -35,100 +36,6 @@ using CARLA_BACKEND_NAMESPACE::PluginType; | |||||
| * @{ | * @{ | ||||
| */ | */ | ||||
| /*! | |||||
| * Information about a cached plugin. | |||||
| * @see carla_get_cached_plugin_info() | |||||
| */ | |||||
| typedef struct _CarlaCachedPluginInfo { | |||||
| /*! | |||||
| * Wherever the data in this struct is valid. | |||||
| * For performance reasons, plugins are only checked on request, | |||||
| * and as such, the count vs number of really valid plugins might not match. | |||||
| * Use this field to skip on plugins which cannot be loaded in Carla. | |||||
| */ | |||||
| bool valid; | |||||
| /*! | |||||
| * Plugin category. | |||||
| */ | |||||
| PluginCategory category; | |||||
| /*! | |||||
| * Plugin hints. | |||||
| * @see PluginHints | |||||
| */ | |||||
| uint hints; | |||||
| /*! | |||||
| * Number of audio inputs. | |||||
| */ | |||||
| uint32_t audioIns; | |||||
| /*! | |||||
| * Number of audio outputs. | |||||
| */ | |||||
| uint32_t audioOuts; | |||||
| /*! | |||||
| * Number of CV inputs. | |||||
| */ | |||||
| uint32_t cvIns; | |||||
| /*! | |||||
| * Number of CV outputs. | |||||
| */ | |||||
| uint32_t cvOuts; | |||||
| /*! | |||||
| * Number of MIDI inputs. | |||||
| */ | |||||
| uint32_t midiIns; | |||||
| /*! | |||||
| * Number of MIDI outputs. | |||||
| */ | |||||
| uint32_t midiOuts; | |||||
| /*! | |||||
| * Number of input parameters. | |||||
| */ | |||||
| uint32_t parameterIns; | |||||
| /*! | |||||
| * Number of output parameters. | |||||
| */ | |||||
| uint32_t parameterOuts; | |||||
| /*! | |||||
| * Plugin name. | |||||
| */ | |||||
| const char* name; | |||||
| /*! | |||||
| * Plugin label. | |||||
| */ | |||||
| const char* label; | |||||
| /*! | |||||
| * Plugin author/maker. | |||||
| */ | |||||
| const char* maker; | |||||
| /*! | |||||
| * Plugin copyright/license. | |||||
| */ | |||||
| const char* copyright; | |||||
| #ifdef __cplusplus | |||||
| /*! | |||||
| * C++ constructor. | |||||
| */ | |||||
| CARLA_API _CarlaCachedPluginInfo() noexcept; | |||||
| CARLA_DECLARE_NON_COPYABLE(_CarlaCachedPluginInfo) | |||||
| #endif | |||||
| } CarlaCachedPluginInfo; | |||||
| /* -------------------------------------------------------------------------------------------------------------------- | /* -------------------------------------------------------------------------------------------------------------------- | ||||
| * plugin discovery */ | * plugin discovery */ | ||||
| @@ -330,9 +237,108 @@ CARLA_PLUGIN_EXPORT void carla_plugin_discovery_skip(CarlaPluginDiscoveryHandle | |||||
| */ | */ | ||||
| CARLA_PLUGIN_EXPORT void carla_plugin_discovery_stop(CarlaPluginDiscoveryHandle handle); | CARLA_PLUGIN_EXPORT void carla_plugin_discovery_stop(CarlaPluginDiscoveryHandle handle); | ||||
| /*! | |||||
| * Set a plugin discovery setting, to be applied globally. | |||||
| */ | |||||
| CARLA_PLUGIN_EXPORT void carla_plugin_discovery_set_option(EngineOption option, int value, const char* valueStr); | |||||
| /* -------------------------------------------------------------------------------------------------------------------- | /* -------------------------------------------------------------------------------------------------------------------- | ||||
| * cached plugins */ | * cached plugins */ | ||||
| /*! | |||||
| * Information about a cached plugin. | |||||
| * @see carla_get_cached_plugin_info() | |||||
| */ | |||||
| typedef struct _CarlaCachedPluginInfo { | |||||
| /*! | |||||
| * Wherever the data in this struct is valid. | |||||
| * For performance reasons, plugins are only checked on request, | |||||
| * and as such, the count vs number of really valid plugins might not match. | |||||
| * Use this field to skip on plugins which cannot be loaded in Carla. | |||||
| */ | |||||
| bool valid; | |||||
| /*! | |||||
| * Plugin category. | |||||
| */ | |||||
| PluginCategory category; | |||||
| /*! | |||||
| * Plugin hints. | |||||
| * @see PluginHints | |||||
| */ | |||||
| uint hints; | |||||
| /*! | |||||
| * Number of audio inputs. | |||||
| */ | |||||
| uint32_t audioIns; | |||||
| /*! | |||||
| * Number of audio outputs. | |||||
| */ | |||||
| uint32_t audioOuts; | |||||
| /*! | |||||
| * Number of CV inputs. | |||||
| */ | |||||
| uint32_t cvIns; | |||||
| /*! | |||||
| * Number of CV outputs. | |||||
| */ | |||||
| uint32_t cvOuts; | |||||
| /*! | |||||
| * Number of MIDI inputs. | |||||
| */ | |||||
| uint32_t midiIns; | |||||
| /*! | |||||
| * Number of MIDI outputs. | |||||
| */ | |||||
| uint32_t midiOuts; | |||||
| /*! | |||||
| * Number of input parameters. | |||||
| */ | |||||
| uint32_t parameterIns; | |||||
| /*! | |||||
| * Number of output parameters. | |||||
| */ | |||||
| uint32_t parameterOuts; | |||||
| /*! | |||||
| * Plugin name. | |||||
| */ | |||||
| const char* name; | |||||
| /*! | |||||
| * Plugin label. | |||||
| */ | |||||
| const char* label; | |||||
| /*! | |||||
| * Plugin author/maker. | |||||
| */ | |||||
| const char* maker; | |||||
| /*! | |||||
| * Plugin copyright/license. | |||||
| */ | |||||
| const char* copyright; | |||||
| #ifdef __cplusplus | |||||
| /*! | |||||
| * C++ constructor. | |||||
| */ | |||||
| CARLA_API _CarlaCachedPluginInfo() noexcept; | |||||
| CARLA_DECLARE_NON_COPYABLE(_CarlaCachedPluginInfo) | |||||
| #endif | |||||
| } CarlaCachedPluginInfo; | |||||
| /*! | /*! | ||||
| * Get how many cached plugins are available. | * Get how many cached plugins are available. | ||||
| * Internal and LV2 plugin formats are cached and need to be discovered via this function. | * Internal and LV2 plugin formats are cached and need to be discovered via this function. | ||||
| @@ -52,6 +52,7 @@ static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 }; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| #ifndef CARLA_OS_WIN | |||||
| static String findWinePrefix(const String filename, const int recursionLimit = 10) | static String findWinePrefix(const String filename, const int recursionLimit = 10) | ||||
| { | { | ||||
| if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/")) | if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/")) | ||||
| @@ -64,6 +65,7 @@ static String findWinePrefix(const String filename, const int recursionLimit = 1 | |||||
| return findWinePrefix(path, recursionLimit-1); | return findWinePrefix(path, recursionLimit-1); | ||||
| } | } | ||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -128,15 +130,15 @@ public: | |||||
| fBridgeBinary(), | fBridgeBinary(), | ||||
| fLabel(), | fLabel(), | ||||
| fShmIds(), | fShmIds(), | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| fWinePrefix(), | fWinePrefix(), | ||||
| #endif | |||||
| #endif | |||||
| fProcess() {} | fProcess() {} | ||||
| void setData( | void setData( | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| const char* const winePrefix, | const char* const winePrefix, | ||||
| #endif | |||||
| #endif | |||||
| const char* const binaryArchName, | const char* const binaryArchName, | ||||
| const char* const bridgeBinary, | const char* const bridgeBinary, | ||||
| const char* const label, | const char* const label, | ||||
| @@ -146,9 +148,9 @@ public: | |||||
| CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); | CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); | ||||
| CARLA_SAFE_ASSERT(! isThreadRunning()); | CARLA_SAFE_ASSERT(! isThreadRunning()); | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| fWinePrefix = winePrefix; | fWinePrefix = winePrefix; | ||||
| #endif | |||||
| #endif | |||||
| fBinaryArchName = binaryArchName; | fBinaryArchName = binaryArchName; | ||||
| fBridgeBinary = bridgeBinary; | fBridgeBinary = bridgeBinary; | ||||
| fShmIds = shmIds; | fShmIds = shmIds; | ||||
| @@ -190,7 +192,7 @@ protected: | |||||
| StringArray arguments; | StringArray arguments; | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| // start with "wine" if needed | // start with "wine" if needed | ||||
| if (fBridgeBinary.endsWithIgnoreCase(".exe")) | if (fBridgeBinary.endsWithIgnoreCase(".exe")) | ||||
| { | { | ||||
| @@ -212,7 +214,7 @@ protected: | |||||
| arguments.add(wineCMD); | arguments.add(wineCMD); | ||||
| } | } | ||||
| #endif | |||||
| #endif | |||||
| // setup binary arch | // setup binary arch | ||||
| ChildProcess::Type childType; | ChildProcess::Type childType; | ||||
| @@ -245,10 +247,10 @@ protected: | |||||
| { | { | ||||
| const ScopedEngineEnvironmentLocker _seel(kEngine); | const ScopedEngineEnvironmentLocker _seel(kEngine); | ||||
| #ifdef CARLA_OS_LINUX | |||||
| #ifdef CARLA_OS_LINUX | |||||
| const CarlaScopedEnvVar sev1("LD_LIBRARY_PATH", nullptr); | const CarlaScopedEnvVar sev1("LD_LIBRARY_PATH", nullptr); | ||||
| const CarlaScopedEnvVar sev2("LD_PRELOAD", nullptr); | const CarlaScopedEnvVar sev2("LD_PRELOAD", nullptr); | ||||
| #endif | |||||
| #endif | |||||
| carla_setenv("ENGINE_OPTION_FORCE_STEREO", bool2str(options.forceStereo)); | carla_setenv("ENGINE_OPTION_FORCE_STEREO", bool2str(options.forceStereo)); | ||||
| carla_setenv("ENGINE_OPTION_PREFER_PLUGIN_BRIDGES", bool2str(options.preferPluginBridges)); | carla_setenv("ENGINE_OPTION_PREFER_PLUGIN_BRIDGES", bool2str(options.preferPluginBridges)); | ||||
| @@ -318,7 +320,7 @@ protected: | |||||
| carla_setenv("ENGINE_BRIDGE_SHM_IDS", fShmIds.toRawUTF8()); | carla_setenv("ENGINE_BRIDGE_SHM_IDS", fShmIds.toRawUTF8()); | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| if (fWinePrefix.isNotEmpty()) | if (fWinePrefix.isNotEmpty()) | ||||
| { | { | ||||
| carla_setenv("WINEDEBUG", "-all"); | carla_setenv("WINEDEBUG", "-all"); | ||||
| @@ -354,12 +356,12 @@ protected: | |||||
| carla_stdout("Using WINEPREFIX '%s', without RT priorities", fWinePrefix.toRawUTF8()); | carla_stdout("Using WINEPREFIX '%s', without RT priorities", fWinePrefix.toRawUTF8()); | ||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| #endif | |||||
| carla_stdout("Starting plugin bridge, command is:\n%s \"%s\" \"%s\" \"%s\" " P_INT64, | carla_stdout("Starting plugin bridge, command is:\n%s \"%s\" \"%s\" \"%s\" " P_INT64, | ||||
| fBridgeBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId()); | fBridgeBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId()); | ||||
| #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
| #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
| const File projFolder(kEngine->getCurrentProjectFolder()); | const File projFolder(kEngine->getCurrentProjectFolder()); | ||||
| if (projFolder.isNotNull()) | if (projFolder.isNotNull()) | ||||
| @@ -370,7 +372,7 @@ protected: | |||||
| oldFolder.setAsCurrentWorkingDirectory(); | oldFolder.setAsCurrentWorkingDirectory(); | ||||
| } | } | ||||
| else | else | ||||
| #endif | |||||
| #endif | |||||
| { | { | ||||
| started = fProcess->start(arguments, childType); | started = fProcess->start(arguments, childType); | ||||
| } | } | ||||
| @@ -427,9 +429,9 @@ private: | |||||
| String fBridgeBinary; | String fBridgeBinary; | ||||
| String fLabel; | String fLabel; | ||||
| String fShmIds; | String fShmIds; | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| String fWinePrefix; | String fWinePrefix; | ||||
| #endif | |||||
| #endif | |||||
| CarlaScopedPointer<ChildProcess> fProcess; | CarlaScopedPointer<ChildProcess> fProcess; | ||||
| @@ -460,9 +462,9 @@ public: | |||||
| fShmRtClientControl(), | fShmRtClientControl(), | ||||
| fShmNonRtClientControl(), | fShmNonRtClientControl(), | ||||
| fShmNonRtServerControl(), | fShmNonRtServerControl(), | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| fWinePrefix(), | fWinePrefix(), | ||||
| #endif | |||||
| #endif | |||||
| fReceivingParamText(), | fReceivingParamText(), | ||||
| fInfo(), | fInfo(), | ||||
| fUniqueId(0), | fUniqueId(0), | ||||
| @@ -478,11 +480,11 @@ public: | |||||
| { | { | ||||
| carla_debug("CarlaPluginBridge::~CarlaPluginBridge()"); | carla_debug("CarlaPluginBridge::~CarlaPluginBridge()"); | ||||
| #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
| #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
| // close UI | // close UI | ||||
| if (pData->hints & PLUGIN_HAS_CUSTOM_UI) | if (pData->hints & PLUGIN_HAS_CUSTOM_UI) | ||||
| pData->transientTryCounter = 0; | pData->transientTryCounter = 0; | ||||
| #endif | |||||
| #endif | |||||
| pData->singleMutex.lock(); | pData->singleMutex.lock(); | ||||
| pData->masterMutex.lock(); | pData->masterMutex.lock(); | ||||
| @@ -2754,7 +2756,7 @@ public: | |||||
| return false; | return false; | ||||
| } | } | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| // --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
| // set wine prefix | // set wine prefix | ||||
| @@ -2767,7 +2769,7 @@ public: | |||||
| if (fWinePrefix.isEmpty()) | if (fWinePrefix.isEmpty()) | ||||
| { | { | ||||
| const char* const envWinePrefix(std::getenv("WINEPREFIX")); | |||||
| const char* const envWinePrefix = std::getenv("WINEPREFIX"); | |||||
| if (envWinePrefix != nullptr && envWinePrefix[0] != '\0') | if (envWinePrefix != nullptr && envWinePrefix[0] != '\0') | ||||
| fWinePrefix = envWinePrefix; | fWinePrefix = envWinePrefix; | ||||
| @@ -2777,7 +2779,7 @@ public: | |||||
| fWinePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine"; | fWinePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine"; | ||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| #endif | |||||
| // --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
| // init bridge thread | // init bridge thread | ||||
| @@ -2914,9 +2916,9 @@ private: | |||||
| BridgeNonRtClientControl fShmNonRtClientControl; | BridgeNonRtClientControl fShmNonRtClientControl; | ||||
| BridgeNonRtServerControl fShmNonRtServerControl; | BridgeNonRtServerControl fShmNonRtServerControl; | ||||
| #ifndef CARLA_OS_WIN | |||||
| #ifndef CARLA_OS_WIN | |||||
| String fWinePrefix; | String fWinePrefix; | ||||
| #endif | |||||
| #endif | |||||
| class ReceivingParamText { | class ReceivingParamText { | ||||
| public: | public: | ||||
| @@ -33,6 +33,23 @@ namespace CB = CARLA_BACKEND_NAMESPACE; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| #ifndef CARLA_OS_WIN | |||||
| static water::String findWinePrefix(const water::String filename, const int recursionLimit = 10) | |||||
| { | |||||
| if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/")) | |||||
| return ""; | |||||
| const water::String path(filename.upToLastOccurrenceOf("/", false, false)); | |||||
| if (water::File(path + "/dosdevices").isDirectory()) | |||||
| return path; | |||||
| return findWinePrefix(path, recursionLimit-1); | |||||
| } | |||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| static const char* const gPluginsDiscoveryNullCharPtr = ""; | static const char* const gPluginsDiscoveryNullCharPtr = ""; | ||||
| _CarlaPluginDiscoveryMetadata::_CarlaPluginDiscoveryMetadata() noexcept | _CarlaPluginDiscoveryMetadata::_CarlaPluginDiscoveryMetadata() noexcept | ||||
| @@ -61,6 +78,24 @@ _CarlaPluginDiscoveryInfo::_CarlaPluginDiscoveryInfo() noexcept | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| struct CarlaPluginDiscoveryOptions { | |||||
| #if !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) && !defined(CARLA_OS_WIN) | |||||
| struct { | |||||
| bool autoPrefix; | |||||
| CarlaString executable; | |||||
| CarlaString fallbackPrefix; | |||||
| } wine; | |||||
| #endif | |||||
| static CarlaPluginDiscoveryOptions& getInstance() noexcept | |||||
| { | |||||
| static CarlaPluginDiscoveryOptions instance; | |||||
| return instance; | |||||
| } | |||||
| }; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| class CarlaPluginDiscovery : private CarlaPipeServer | class CarlaPluginDiscovery : private CarlaPipeServer | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -367,36 +402,59 @@ private: | |||||
| void start() | void start() | ||||
| { | { | ||||
| using water::File; | |||||
| using water::String; | |||||
| fLastMessageTime = carla_gettime_ms(); | fLastMessageTime = carla_gettime_ms(); | ||||
| fPluginsFoundInBinary = false; | fPluginsFoundInBinary = false; | ||||
| fNextSha1Sum.clear(); | fNextSha1Sum.clear(); | ||||
| const char* helperTool; | |||||
| #ifndef CARLA_OS_WIN | |||||
| const CarlaPluginDiscoveryOptions& options(CarlaPluginDiscoveryOptions::getInstance()); | |||||
| String helperTool; | |||||
| switch (fBinaryType) | switch (fBinaryType) | ||||
| { | { | ||||
| #ifndef CARLA_OS_WIN | |||||
| case CB::BINARY_WIN32: | case CB::BINARY_WIN32: | ||||
| helperTool = "wine"; | |||||
| if (options.wine.executable.isNotEmpty()) | |||||
| helperTool = options.wine.executable.buffer(); | |||||
| else | |||||
| helperTool = "wine"; | |||||
| break; | break; | ||||
| case CB::BINARY_WIN64: | case CB::BINARY_WIN64: | ||||
| helperTool = "wine64"; | |||||
| if (options.wine.executable.isNotEmpty()) | |||||
| { | |||||
| helperTool = options.wine.executable.buffer(); | |||||
| if (helperTool[0] == CARLA_OS_SEP && File(helperTool + "64").existsAsFile()) | |||||
| helperTool += "64"; | |||||
| } | |||||
| else | |||||
| { | |||||
| helperTool = "wine"; | |||||
| } | |||||
| break; | break; | ||||
| #endif | |||||
| default: | default: | ||||
| helperTool = nullptr; | |||||
| break; | break; | ||||
| } | } | ||||
| #endif | |||||
| if (fBinaries.empty()) | if (fBinaries.empty()) | ||||
| { | { | ||||
| startPipeServer(helperTool, fDiscoveryTool, | |||||
| getPluginTypeAsString(fPluginType), | |||||
| ":all"); | |||||
| #ifndef CARLA_OS_WIN | |||||
| if (helperTool.isNotEmpty()) | |||||
| startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all"); | |||||
| else | |||||
| #endif | |||||
| startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), ":all"); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const water::File file(fBinaries[fBinaryIndex]); | |||||
| const water::String filename(file.getFullPathName()); | |||||
| const File file(fBinaries[fBinaryIndex]); | |||||
| const String filename(file.getFullPathName()); | |||||
| if (fCheckCacheCallback != nullptr) | if (fCheckCacheCallback != nullptr) | ||||
| { | { | ||||
| @@ -410,8 +468,36 @@ private: | |||||
| } | } | ||||
| } | } | ||||
| #ifndef CARLA_OS_WIN | |||||
| String winePrefix; | |||||
| if (options.wine.autoPrefix) | |||||
| winePrefix = findWinePrefix(filename); | |||||
| if (winePrefix.isEmpty()) | |||||
| { | |||||
| const char* const envWinePrefix = std::getenv("WINEPREFIX"); | |||||
| if (envWinePrefix != nullptr && envWinePrefix[0] != '\0') | |||||
| winePrefix = envWinePrefix; | |||||
| else if (options.wine.fallbackPrefix != nullptr && options.wine.fallbackPrefix[0] != '\0') | |||||
| winePrefix = options.wine.fallbackPrefix.buffer(); | |||||
| else | |||||
| winePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine"; | |||||
| } | |||||
| const CarlaScopedEnvVar sev1("WINEDEBUG", "-all"); | |||||
| const CarlaScopedEnvVar sev2("WINEPREFIX", winePrefix.toRawUTF8()); | |||||
| #endif | |||||
| carla_stdout("Scanning \"%s\"...", filename.toRawUTF8()); | carla_stdout("Scanning \"%s\"...", filename.toRawUTF8()); | ||||
| startPipeServer(helperTool, fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8()); | |||||
| #ifndef CARLA_OS_WIN | |||||
| if (helperTool.isNotEmpty()) | |||||
| startPipeServer(helperTool.toRawUTF8(), fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8()); | |||||
| else | |||||
| #endif | |||||
| startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -696,4 +782,31 @@ void carla_plugin_discovery_stop(const CarlaPluginDiscoveryHandle handle) | |||||
| delete static_cast<CarlaPluginDiscovery*>(handle); | delete static_cast<CarlaPluginDiscovery*>(handle); | ||||
| } | } | ||||
| void carla_plugin_discovery_set_option(const EngineOption option, const int value, const char* const valueStr) | |||||
| { | |||||
| switch (option) | |||||
| { | |||||
| #if !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) && !defined(CARLA_OS_WIN) | |||||
| case CB::ENGINE_OPTION_WINE_EXECUTABLE: | |||||
| if (valueStr != nullptr && valueStr[0] != '\0') | |||||
| CarlaPluginDiscoveryOptions::getInstance().wine.executable = valueStr; | |||||
| else | |||||
| CarlaPluginDiscoveryOptions::getInstance().wine.executable.clear(); | |||||
| break; | |||||
| case CB::ENGINE_OPTION_WINE_AUTO_PREFIX: | |||||
| CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,); | |||||
| CarlaPluginDiscoveryOptions::getInstance().wine.autoPrefix = value != 0; | |||||
| break; | |||||
| case CB::ENGINE_OPTION_WINE_FALLBACK_PREFIX: | |||||
| if (valueStr != nullptr && valueStr[0] != '\0') | |||||
| CarlaPluginDiscoveryOptions::getInstance().wine.fallbackPrefix = valueStr; | |||||
| else | |||||
| CarlaPluginDiscoveryOptions::getInstance().wine.fallbackPrefix.clear(); | |||||
| break; | |||||
| #endif | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -20,6 +20,7 @@ | |||||
| #include "CarlaBackend.h" | #include "CarlaBackend.h" | ||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| using CARLA_BACKEND_NAMESPACE::PluginType; | |||||
| extern "C" { | extern "C" { | ||||
| #endif | #endif | ||||
| @@ -31,6 +32,15 @@ typedef struct { | |||||
| const char* labelSetup; | const char* labelSetup; | ||||
| } JackAppDialogResults; | } JackAppDialogResults; | ||||
| typedef struct _HostSettings { | |||||
| bool showPluginBridges; | |||||
| bool showWineBridges; | |||||
| bool useSystemIcons; | |||||
| bool wineAutoPrefix; | |||||
| const char* wineExecutable; | |||||
| const char* wineFallbackPrefix; | |||||
| } HostSettings; | |||||
| typedef struct { | typedef struct { | ||||
| uint build; | uint build; | ||||
| uint type; | uint type; | ||||
| @@ -55,20 +65,28 @@ struct PluginListDialog; | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| CARLA_API void | |||||
| CARLA_PLUGIN_EXPORT void | |||||
| carla_frontend_createAndExecAboutJuceDialog(void* parent); | carla_frontend_createAndExecAboutJuceDialog(void* parent); | ||||
| CARLA_API const JackAppDialogResults* | |||||
| CARLA_PLUGIN_EXPORT const JackAppDialogResults* | |||||
| carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilename); | carla_frontend_createAndExecJackAppDialog(void* parent, const char* projectFilename); | ||||
| CARLA_API PluginListDialog* | |||||
| carla_frontend_createPluginListDialog(void* parent); | |||||
| CARLA_PLUGIN_EXPORT PluginListDialog* | |||||
| carla_frontend_createPluginListDialog(void* parent, const HostSettings* hostSettings); | |||||
| CARLA_PLUGIN_EXPORT void | |||||
| carla_frontend_destroyPluginListDialog(PluginListDialog* dialog); | |||||
| // TODO get favorites | |||||
| CARLA_PLUGIN_EXPORT void | |||||
| carla_frontend_setPluginListDialogPath(PluginListDialog* dialog, int ptype, const char* path); | |||||
| CARLA_API const PluginListDialogResults* | |||||
| CARLA_PLUGIN_EXPORT const PluginListDialogResults* | |||||
| carla_frontend_execPluginListDialog(PluginListDialog* dialog); | carla_frontend_execPluginListDialog(PluginListDialog* dialog); | ||||
| CARLA_API const PluginListDialogResults* | |||||
| carla_frontend_createAndExecPluginListDialog(void* parent/*, const HostSettings& hostSettings*/); | |||||
| // CARLA_PLUGIN_EXPORT const PluginListDialogResults* | |||||
| // carla_frontend_createAndExecPluginListDialog(void* parent, const HostSettings* hostSettings); | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -23,7 +23,7 @@ | |||||
| # Imports (ctypes) | # Imports (ctypes) | ||||
| from ctypes import ( | from ctypes import ( | ||||
| c_bool, c_char, c_char_p, c_uint, c_uint64, c_void_p, cast, | |||||
| c_bool, c_char, c_char_p, c_int, c_uint, c_uint64, c_void_p, cast, | |||||
| cdll, Structure, | cdll, Structure, | ||||
| POINTER | POINTER | ||||
| ) | ) | ||||
| @@ -53,6 +53,16 @@ class JackApplicationDialogResults(Structure): | |||||
| ("labelSetup", c_char_p) | ("labelSetup", c_char_p) | ||||
| ] | ] | ||||
| class HostSettings(Structure): | |||||
| _fields_ = [ | |||||
| ("showPluginBridges", c_bool), | |||||
| ("showWineBridges", c_bool), | |||||
| ("useSystemIcons", c_bool), | |||||
| ("wineAutoPrefix", c_bool), | |||||
| ("wineExecutable", c_char_p), | |||||
| ("wineFallbackPrefix", c_char_p), | |||||
| ] | |||||
| class PluginListDialogResults(Structure): | class PluginListDialogResults(Structure): | ||||
| _fields_ = [ | _fields_ = [ | ||||
| ("build", c_uint), | ("build", c_uint), | ||||
| @@ -87,15 +97,18 @@ class CarlaFrontendLib(): | |||||
| self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p) | self.lib.carla_frontend_createAndExecJackAppDialog.argtypes = (c_void_p, c_char_p) | ||||
| self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults) | self.lib.carla_frontend_createAndExecJackAppDialog.restype = POINTER(JackApplicationDialogResults) | ||||
| self.lib.carla_frontend_createPluginListDialog.argtypes = (c_void_p,) | |||||
| self.lib.carla_frontend_createPluginListDialog.argtypes = (c_void_p, POINTER(HostSettings)) | |||||
| self.lib.carla_frontend_createPluginListDialog.restype = c_void_p | self.lib.carla_frontend_createPluginListDialog.restype = c_void_p | ||||
| self.lib.carla_frontend_destroyPluginListDialog.argtypes = (c_void_p,) | |||||
| self.lib.carla_frontend_destroyPluginListDialog.restype = None | |||||
| self.lib.carla_frontend_setPluginListDialogPath.argtypes = (c_void_p, c_int, c_char_p) | |||||
| self.lib.carla_frontend_setPluginListDialogPath.restype = None | |||||
| self.lib.carla_frontend_execPluginListDialog.argtypes = (c_void_p,) | self.lib.carla_frontend_execPluginListDialog.argtypes = (c_void_p,) | ||||
| self.lib.carla_frontend_execPluginListDialog.restype = POINTER(PluginListDialogResults) | self.lib.carla_frontend_execPluginListDialog.restype = POINTER(PluginListDialogResults) | ||||
| self.lib.carla_frontend_createAndExecPluginListDialog.argtypes = (c_void_p,) | |||||
| self.lib.carla_frontend_createAndExecPluginListDialog.restype = POINTER(PluginListDialogResults) | |||||
| # -------------------------------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------------------------------- | ||||
| def createAndExecAboutJuceDialog(self, parent): | def createAndExecAboutJuceDialog(self, parent): | ||||
| @@ -105,13 +118,23 @@ class CarlaFrontendLib(): | |||||
| return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), | return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent), | ||||
| projectFilename.encode("utf-8"))) | projectFilename.encode("utf-8"))) | ||||
| def createPluginListDialog(self, parent, useSystemIcons): | |||||
| return self.lib.carla_frontend_createPluginListDialog(unwrapinstance(parent)) | |||||
| def createPluginListDialog(self, parent, hostSettings): | |||||
| hostSettingsC = HostSettings() | |||||
| hostSettingsC.showPluginBridges = hostSettings['showPluginBridges'] | |||||
| hostSettingsC.showWineBridges = hostSettings['showWineBridges'] | |||||
| hostSettingsC.useSystemIcons = hostSettings['useSystemIcons'] | |||||
| hostSettingsC.wineAutoPrefix = hostSettings['wineAutoPrefix'] | |||||
| hostSettingsC.wineExecutable = hostSettings['wineExecutable'].encode("utf-8") | |||||
| hostSettingsC.wineFallbackPrefix = hostSettings['wineFallbackPrefix'].encode("utf-8") | |||||
| return self.lib.carla_frontend_createPluginListDialog(unwrapinstance(parent), hostSettingsC) | |||||
| def destroyPluginListDialog(self, dialog): | |||||
| self.lib.carla_frontend_destroyPluginListDialog(dialog) | |||||
| def setPluginListDialogPath(self, dialog, ptype, path): | |||||
| self.lib.carla_frontend_setPluginListDialogPath(dialog, ptype, path.encode("utf-8")) | |||||
| def execPluginListDialog(self, dialog): | def execPluginListDialog(self, dialog): | ||||
| return structToDictOrNull(self.lib.carla_frontend_execPluginListDialog(dialog)) | return structToDictOrNull(self.lib.carla_frontend_execPluginListDialog(dialog)) | ||||
| def createAndExecPluginListDialog(self, parent, useSystemIcons): | |||||
| return structToDictOrNull(self.lib.carla_frontend_createAndExecPluginListDialog(unwrapinstance(parent))) | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| @@ -931,10 +931,11 @@ class HostWindow(QMainWindow): | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_engineStart(self): | def slot_engineStart(self): | ||||
| audioDriver = setEngineSettings(self.host) | |||||
| firstInit = self.fFirstEngineInit | |||||
| audioDriver = setEngineSettings(self.host, self.fSavedSettings) | |||||
| firstInit = self.fFirstEngineInit | |||||
| self.fFirstEngineInit = False | self.fFirstEngineInit = False | ||||
| self.ui.text_logs.appendPlainText("======= Starting engine =======") | self.ui.text_logs.appendPlainText("======= Starting engine =======") | ||||
| if self.host.engine_init(audioDriver, self.fClientName): | if self.host.engine_init(audioDriver, self.fClientName): | ||||
| @@ -953,9 +954,11 @@ class HostWindow(QMainWindow): | |||||
| audioError = self.host.get_last_error() | audioError = self.host.get_last_error() | ||||
| if audioError: | if audioError: | ||||
| QMessageBox.critical(self, self.tr("Error"), self.tr("Could not connect to Audio backend '%s', possible reasons:\n%s" % (audioDriver, audioError))) | |||||
| QMessageBox.critical(self, self.tr("Error"), | |||||
| self.tr("Could not connect to Audio backend '%s', possible reasons:\n%s" % (audioDriver, audioError))) | |||||
| else: | else: | ||||
| QMessageBox.critical(self, self.tr("Error"), self.tr("Could not connect to Audio backend '%s'" % audioDriver)) | |||||
| QMessageBox.critical(self, self.tr("Error"), | |||||
| self.tr("Could not connect to Audio backend '%s'" % audioDriver)) | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_engineStop(self, forced = False): | def slot_engineStop(self, forced = False): | ||||
| @@ -1209,10 +1212,27 @@ class HostWindow(QMainWindow): | |||||
| def showAddPluginDialog(self): | def showAddPluginDialog(self): | ||||
| # TODO self.fHasLoadedLv2Plugins | # TODO self.fHasLoadedLv2Plugins | ||||
| if self.fPluginListDialog is None: | if self.fPluginListDialog is None: | ||||
| self.fPluginListDialog = gCarla.felib.createPluginListDialog(self.fParentOrSelf, | |||||
| self.fSavedSettings[CARLA_KEY_MAIN_SYSTEM_ICONS]) | |||||
| hostSettings = { | |||||
| 'showPluginBridges': self.fSavedSettings[CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES], | |||||
| 'showWineBridges': self.fSavedSettings[CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES], | |||||
| 'useSystemIcons': self.fSavedSettings[CARLA_KEY_MAIN_SYSTEM_ICONS], | |||||
| 'wineAutoPrefix': self.fSavedSettings[CARLA_KEY_WINE_AUTO_PREFIX], | |||||
| 'wineExecutable': self.fSavedSettings[CARLA_KEY_WINE_EXECUTABLE], | |||||
| 'wineFallbackPrefix': self.fSavedSettings[CARLA_KEY_WINE_FALLBACK_PREFIX], | |||||
| } | |||||
| self.fPluginListDialog = d = gCarla.felib.createPluginListDialog(self.fParentOrSelf, hostSettings) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_LADSPA, self.fSavedSettings[CARLA_KEY_PATHS_LADSPA]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_DSSI, self.fSavedSettings[CARLA_KEY_PATHS_DSSI]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_LV2, self.fSavedSettings[CARLA_KEY_PATHS_LV2]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_VST2, self.fSavedSettings[CARLA_KEY_PATHS_VST2]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_VST3, self.fSavedSettings[CARLA_KEY_PATHS_VST3]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_SF2, self.fSavedSettings[CARLA_KEY_PATHS_SF2]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_SFZ, self.fSavedSettings[CARLA_KEY_PATHS_SFZ]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_JSFX, self.fSavedSettings[CARLA_KEY_PATHS_JSFX]) | |||||
| gCarla.felib.setPluginListDialogPath(d, PLUGIN_CLAP, self.fSavedSettings[CARLA_KEY_PATHS_CLAP]) | |||||
| ret = gCarla.felib.execPluginListDialog(self.fPluginListDialog) | ret = gCarla.felib.execPluginListDialog(self.fPluginListDialog) | ||||
| print(ret) | |||||
| # TODO | # TODO | ||||
| #if dialog.fFavoritePluginsChanged: | #if dialog.fFavoritePluginsChanged: | ||||
| @@ -1940,6 +1960,10 @@ class HostWindow(QMainWindow): | |||||
| def loadSettings(self, firstTime): | def loadSettings(self, firstTime): | ||||
| settings = QSafeSettings() | settings = QSafeSettings() | ||||
| if self.fPluginListDialog is not None: | |||||
| gCarla.felib.destroyPluginListDialog(self.fPluginListDialog) | |||||
| self.fPluginListDialog = None | |||||
| if firstTime: | if firstTime: | ||||
| geometry = settings.value("Geometry", QByteArray(), QByteArray) | geometry = settings.value("Geometry", QByteArray(), QByteArray) | ||||
| if not geometry.isNull(): | if not geometry.isNull(): | ||||
| @@ -1990,6 +2014,13 @@ class HostWindow(QMainWindow): | |||||
| # TODO - complete this | # TODO - complete this | ||||
| oldSettings = self.fSavedSettings | oldSettings = self.fSavedSettings | ||||
| if self.host.audioDriverForced is not None: | |||||
| audioDriver = self.host.audioDriverForced | |||||
| else: | |||||
| audioDriver = settings.value(CARLA_KEY_ENGINE_AUDIO_DRIVER, CARLA_DEFAULT_AUDIO_DRIVER, str) | |||||
| audioDriverPrefix = CARLA_KEY_ENGINE_DRIVER_PREFIX + audioDriver | |||||
| self.fSavedSettings = { | self.fSavedSettings = { | ||||
| CARLA_KEY_MAIN_PROJECT_FOLDER: settings.value(CARLA_KEY_MAIN_PROJECT_FOLDER, CARLA_DEFAULT_MAIN_PROJECT_FOLDER, str), | CARLA_KEY_MAIN_PROJECT_FOLDER: settings.value(CARLA_KEY_MAIN_PROJECT_FOLDER, CARLA_DEFAULT_MAIN_PROJECT_FOLDER, str), | ||||
| CARLA_KEY_MAIN_CONFIRM_EXIT: settings.value(CARLA_KEY_MAIN_CONFIRM_EXIT, CARLA_DEFAULT_MAIN_CONFIRM_EXIT, bool), | CARLA_KEY_MAIN_CONFIRM_EXIT: settings.value(CARLA_KEY_MAIN_CONFIRM_EXIT, CARLA_DEFAULT_MAIN_CONFIRM_EXIT, bool), | ||||
| @@ -2010,6 +2041,51 @@ class HostWindow(QMainWindow): | |||||
| CARLA_KEY_CANVAS_FULL_REPAINTS: settings.value(CARLA_KEY_CANVAS_FULL_REPAINTS, CARLA_DEFAULT_CANVAS_FULL_REPAINTS, bool), | CARLA_KEY_CANVAS_FULL_REPAINTS: settings.value(CARLA_KEY_CANVAS_FULL_REPAINTS, CARLA_DEFAULT_CANVAS_FULL_REPAINTS, bool), | ||||
| CARLA_KEY_CUSTOM_PAINTING: (settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, True, bool) and | CARLA_KEY_CUSTOM_PAINTING: (settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, True, bool) and | ||||
| settings.value(CARLA_KEY_MAIN_PRO_THEME_COLOR, "Black", str).lower() == "black"), | settings.value(CARLA_KEY_MAIN_PRO_THEME_COLOR, "Black", str).lower() == "black"), | ||||
| # engine | |||||
| CARLA_KEY_ENGINE_AUDIO_DRIVER: audioDriver, | |||||
| CARLA_KEY_ENGINE_AUDIO_DEVICE: settings.value(audioDriverPrefix+"/Device", "", str), | |||||
| CARLA_KEY_ENGINE_BUFFER_SIZE: settings.value(audioDriverPrefix+"/BufferSize", CARLA_DEFAULT_AUDIO_BUFFER_SIZE, int), | |||||
| CARLA_KEY_ENGINE_SAMPLE_RATE: settings.value(audioDriverPrefix+"/SampleRate", CARLA_DEFAULT_AUDIO_SAMPLE_RATE, int), | |||||
| CARLA_KEY_ENGINE_TRIPLE_BUFFER: settings.value(audioDriverPrefix+"/TripleBuffer", CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER, bool), | |||||
| # file paths | |||||
| CARLA_KEY_PATHS_AUDIO: splitter.join(settings.value(CARLA_KEY_PATHS_AUDIO, CARLA_DEFAULT_FILE_PATH_AUDIO, list)), | |||||
| CARLA_KEY_PATHS_MIDI: splitter.join(settings.value(CARLA_KEY_PATHS_MIDI, CARLA_DEFAULT_FILE_PATH_MIDI, list)), | |||||
| # plugin paths | |||||
| CARLA_KEY_PATHS_LADSPA: splitter.join(settings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH, list)), | |||||
| CARLA_KEY_PATHS_DSSI: splitter.join(settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH, list)), | |||||
| CARLA_KEY_PATHS_LV2: splitter.join(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list)), | |||||
| CARLA_KEY_PATHS_VST2: splitter.join(settings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH, list)), | |||||
| CARLA_KEY_PATHS_VST3: splitter.join(settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list)), | |||||
| CARLA_KEY_PATHS_SF2: splitter.join(settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list)), | |||||
| CARLA_KEY_PATHS_SFZ: splitter.join(settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list)), | |||||
| CARLA_KEY_PATHS_JSFX: splitter.join(settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list)), | |||||
| CARLA_KEY_PATHS_CLAP: splitter.join(settings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list)), | |||||
| # osc | |||||
| CARLA_KEY_OSC_ENABLED: settings.value(CARLA_KEY_OSC_ENABLED, CARLA_DEFAULT_OSC_ENABLED, bool), | |||||
| CARLA_KEY_OSC_TCP_PORT_ENABLED: settings.value(CARLA_KEY_OSC_TCP_PORT_ENABLED, CARLA_DEFAULT_OSC_TCP_PORT_ENABLED, bool), | |||||
| CARLA_KEY_OSC_TCP_PORT_RANDOM: settings.value(CARLA_KEY_OSC_TCP_PORT_RANDOM, CARLA_DEFAULT_OSC_TCP_PORT_RANDOM, bool), | |||||
| CARLA_KEY_OSC_TCP_PORT_NUMBER: settings.value(CARLA_KEY_OSC_TCP_PORT_NUMBER, CARLA_DEFAULT_OSC_TCP_PORT_NUMBER, int), | |||||
| CARLA_KEY_OSC_UDP_PORT_ENABLED: settings.value(CARLA_KEY_OSC_UDP_PORT_ENABLED, CARLA_DEFAULT_OSC_UDP_PORT_ENABLED, bool), | |||||
| CARLA_KEY_OSC_UDP_PORT_RANDOM: settings.value(CARLA_KEY_OSC_UDP_PORT_RANDOM, CARLA_DEFAULT_OSC_UDP_PORT_RANDOM, bool), | |||||
| CARLA_KEY_OSC_UDP_PORT_NUMBER: settings.value(CARLA_KEY_OSC_UDP_PORT_NUMBER, CARLA_DEFAULT_OSC_UDP_PORT_NUMBER, int), | |||||
| # wine | |||||
| CARLA_KEY_WINE_EXECUTABLE: settings.value(CARLA_KEY_WINE_EXECUTABLE, CARLA_DEFAULT_WINE_EXECUTABLE, str), | |||||
| CARLA_KEY_WINE_AUTO_PREFIX: settings.value(CARLA_KEY_WINE_AUTO_PREFIX, CARLA_DEFAULT_WINE_AUTO_PREFIX, bool), | |||||
| CARLA_KEY_WINE_FALLBACK_PREFIX: settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, CARLA_DEFAULT_WINE_FALLBACK_PREFIX, str), | |||||
| CARLA_KEY_WINE_RT_PRIO_ENABLED: settings.value(CARLA_KEY_WINE_RT_PRIO_ENABLED, CARLA_DEFAULT_WINE_RT_PRIO_ENABLED, bool), | |||||
| CARLA_KEY_WINE_BASE_RT_PRIO: settings.value(CARLA_KEY_WINE_BASE_RT_PRIO, CARLA_DEFAULT_WINE_BASE_RT_PRIO, int), | |||||
| CARLA_KEY_WINE_SERVER_RT_PRIO: settings.value(CARLA_KEY_WINE_SERVER_RT_PRIO, CARLA_DEFAULT_WINE_SERVER_RT_PRIO, int), | |||||
| # experimental switches | |||||
| CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES: | |||||
| settings.value(CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES, CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES, bool), | |||||
| CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES: | |||||
| settings.value(CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES, CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES, bool), | |||||
| } | } | ||||
| if not self.host.isControl: | if not self.host.isControl: | ||||
| @@ -2027,7 +2103,7 @@ class HostWindow(QMainWindow): | |||||
| self.fMiniCanvasUpdateTimeout = 1000 if self.fSavedSettings[CARLA_KEY_CANVAS_FANCY_EYE_CANDY] else 0 | self.fMiniCanvasUpdateTimeout = 1000 if self.fSavedSettings[CARLA_KEY_CANVAS_FANCY_EYE_CANDY] else 0 | ||||
| setEngineSettings(self.host) | |||||
| setEngineSettings(self.host, self.fSavedSettings) | |||||
| self.restartTimersIfNeeded() | self.restartTimersIfNeeded() | ||||
| if oldSettings.get(CARLA_KEY_MAIN_CLASSIC_SKIN, None) not in (self.fSavedSettings[CARLA_KEY_MAIN_CLASSIC_SKIN], None): | if oldSettings.get(CARLA_KEY_MAIN_CLASSIC_SKIN, None) not in (self.fSavedSettings[CARLA_KEY_MAIN_CLASSIC_SKIN], None): | ||||
| @@ -3386,67 +3462,104 @@ def setHostSettings(host): | |||||
| if not (NSM_URL and host.nsmOK): | if not (NSM_URL and host.nsmOK): | ||||
| host.set_engine_option(ENGINE_OPTION_CLIENT_NAME_PREFIX, 0, gCarla.cnprefix) | host.set_engine_option(ENGINE_OPTION_CLIENT_NAME_PREFIX, 0, gCarla.cnprefix) | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Set Engine settings according to carla preferences. Returns selected audio driver. | # Set Engine settings according to carla preferences. Returns selected audio driver. | ||||
| def setEngineSettings(host, oscPort = None): | |||||
| def setEngineSettings(host, settings, oscPort = None): | |||||
| # kdevelop likes this :) | # kdevelop likes this :) | ||||
| if False: host = CarlaHostNull() | if False: host = CarlaHostNull() | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # do nothing if control | # do nothing if control | ||||
| if host.isControl: | if host.isControl: | ||||
| return "Control" | return "Control" | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # fetch settings as needed | |||||
| settings = QSafeSettings("falkTX", "Carla2") | |||||
| if settings is None: | |||||
| qsettings = QSafeSettings("falkTX", "Carla2") | |||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| if host.audioDriverForced is not None: | |||||
| audioDriver = host.audioDriverForced | |||||
| else: | |||||
| audioDriver = qsettings.value(CARLA_KEY_ENGINE_AUDIO_DRIVER, CARLA_DEFAULT_AUDIO_DRIVER, str) | |||||
| audioDriverPrefix = CARLA_KEY_ENGINE_DRIVER_PREFIX + audioDriver | |||||
| settings = { | |||||
| # engine | |||||
| CARLA_KEY_ENGINE_AUDIO_DRIVER: audioDriver, | |||||
| CARLA_KEY_ENGINE_AUDIO_DEVICE: qsettings.value(audioDriverPrefix+"/Device", "", str), | |||||
| CARLA_KEY_ENGINE_BUFFER_SIZE: qsettings.value(audioDriverPrefix+"/BufferSize", CARLA_DEFAULT_AUDIO_BUFFER_SIZE, int), | |||||
| CARLA_KEY_ENGINE_SAMPLE_RATE: qsettings.value(audioDriverPrefix+"/SampleRate", CARLA_DEFAULT_AUDIO_SAMPLE_RATE, int), | |||||
| CARLA_KEY_ENGINE_TRIPLE_BUFFER: qsettings.value(audioDriverPrefix+"/TripleBuffer", CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER, bool), | |||||
| # file paths | |||||
| CARLA_KEY_PATHS_AUDIO: splitter.join(qsettings.value(CARLA_KEY_PATHS_AUDIO, CARLA_DEFAULT_FILE_PATH_AUDIO, list)), | |||||
| CARLA_KEY_PATHS_MIDI: splitter.join(qsettings.value(CARLA_KEY_PATHS_MIDI, CARLA_DEFAULT_FILE_PATH_MIDI, list)), | |||||
| # plugin paths | |||||
| CARLA_KEY_PATHS_LADSPA: splitter.join(qsettings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH, list)), | |||||
| CARLA_KEY_PATHS_DSSI: splitter.join(qsettings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH, list)), | |||||
| CARLA_KEY_PATHS_LV2: splitter.join(qsettings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list)), | |||||
| CARLA_KEY_PATHS_VST2: splitter.join(qsettings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH, list)), | |||||
| CARLA_KEY_PATHS_VST3: splitter.join(qsettings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list)), | |||||
| CARLA_KEY_PATHS_SF2: splitter.join(qsettings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list)), | |||||
| CARLA_KEY_PATHS_SFZ: splitter.join(qsettings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list)), | |||||
| CARLA_KEY_PATHS_JSFX: splitter.join(qsettings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list)), | |||||
| CARLA_KEY_PATHS_CLAP: splitter.join(qsettings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list)), | |||||
| # osc | |||||
| CARLA_KEY_OSC_ENABLED: qsettings.value(CARLA_KEY_OSC_ENABLED, CARLA_DEFAULT_OSC_ENABLED, bool), | |||||
| CARLA_KEY_OSC_TCP_PORT_ENABLED: qsettings.value(CARLA_KEY_OSC_TCP_PORT_ENABLED, CARLA_DEFAULT_OSC_TCP_PORT_ENABLED, bool), | |||||
| CARLA_KEY_OSC_TCP_PORT_RANDOM: qsettings.value(CARLA_KEY_OSC_TCP_PORT_RANDOM, CARLA_DEFAULT_OSC_TCP_PORT_RANDOM, bool), | |||||
| CARLA_KEY_OSC_TCP_PORT_NUMBER: qsettings.value(CARLA_KEY_OSC_TCP_PORT_NUMBER, CARLA_DEFAULT_OSC_TCP_PORT_NUMBER, int), | |||||
| CARLA_KEY_OSC_UDP_PORT_ENABLED: qsettings.value(CARLA_KEY_OSC_UDP_PORT_ENABLED, CARLA_DEFAULT_OSC_UDP_PORT_ENABLED, bool), | |||||
| CARLA_KEY_OSC_UDP_PORT_RANDOM: qsettings.value(CARLA_KEY_OSC_UDP_PORT_RANDOM, CARLA_DEFAULT_OSC_UDP_PORT_RANDOM, bool), | |||||
| CARLA_KEY_OSC_UDP_PORT_NUMBER: qsettings.value(CARLA_KEY_OSC_UDP_PORT_NUMBER, CARLA_DEFAULT_OSC_UDP_PORT_NUMBER, int), | |||||
| # wine | |||||
| CARLA_KEY_WINE_EXECUTABLE: qsettings.value(CARLA_KEY_WINE_EXECUTABLE, CARLA_DEFAULT_WINE_EXECUTABLE, str), | |||||
| CARLA_KEY_WINE_AUTO_PREFIX: qsettings.value(CARLA_KEY_WINE_AUTO_PREFIX, CARLA_DEFAULT_WINE_AUTO_PREFIX, bool), | |||||
| CARLA_KEY_WINE_FALLBACK_PREFIX: qsettings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, CARLA_DEFAULT_WINE_FALLBACK_PREFIX, str), | |||||
| CARLA_KEY_WINE_RT_PRIO_ENABLED: qsettings.value(CARLA_KEY_WINE_RT_PRIO_ENABLED, CARLA_DEFAULT_WINE_RT_PRIO_ENABLED, bool), | |||||
| CARLA_KEY_WINE_BASE_RT_PRIO: qsettings.value(CARLA_KEY_WINE_BASE_RT_PRIO, CARLA_DEFAULT_WINE_BASE_RT_PRIO, int), | |||||
| CARLA_KEY_WINE_SERVER_RT_PRIO: qsettings.value(CARLA_KEY_WINE_SERVER_RT_PRIO, CARLA_DEFAULT_WINE_SERVER_RT_PRIO, int), | |||||
| } | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # main settings | # main settings | ||||
| setHostSettings(host) | setHostSettings(host) | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # file paths | # file paths | ||||
| FILE_PATH_AUDIO = settings.value(CARLA_KEY_PATHS_AUDIO, CARLA_DEFAULT_FILE_PATH_AUDIO, list) | |||||
| FILE_PATH_MIDI = settings.value(CARLA_KEY_PATHS_MIDI, CARLA_DEFAULT_FILE_PATH_MIDI, list) | |||||
| host.set_engine_option(ENGINE_OPTION_FILE_PATH, FILE_AUDIO, settings[CARLA_KEY_PATHS_AUDIO]) | |||||
| host.set_engine_option(ENGINE_OPTION_FILE_PATH, FILE_MIDI, settings[CARLA_KEY_PATHS_MIDI]) | |||||
| host.set_engine_option(ENGINE_OPTION_FILE_PATH, FILE_AUDIO, splitter.join(FILE_PATH_AUDIO)) | |||||
| host.set_engine_option(ENGINE_OPTION_FILE_PATH, FILE_MIDI, splitter.join(FILE_PATH_MIDI)) | |||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # plugin paths | # plugin paths | ||||
| LADSPA_PATH = settings.value(CARLA_KEY_PATHS_LADSPA, CARLA_DEFAULT_LADSPA_PATH, list) | |||||
| DSSI_PATH = settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH, list) | |||||
| LV2_PATH = settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH, list) | |||||
| VST2_PATH = settings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH, list) | |||||
| VST3_PATH = settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list) | |||||
| SF2_PATH = settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list) | |||||
| SFZ_PATH = settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list) | |||||
| JSFX_PATH = settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list) | |||||
| CLAP_PATH = settings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LADSPA, splitter.join(LADSPA_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, splitter.join(DSSI_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LV2, splitter.join(LV2_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST2, splitter.join(VST2_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, splitter.join(VST3_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SF2, splitter.join(SF2_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SFZ, splitter.join(SFZ_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, splitter.join(JSFX_PATH)) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_CLAP, splitter.join(CLAP_PATH)) | |||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LADSPA, settings[CARLA_KEY_PATHS_LADSPA]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, settings[CARLA_KEY_PATHS_DSSI]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LV2, settings[CARLA_KEY_PATHS_LV2]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST2, settings[CARLA_KEY_PATHS_VST2]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, settings[CARLA_KEY_PATHS_VST3]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SF2, settings[CARLA_KEY_PATHS_SF2]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SFZ, settings[CARLA_KEY_PATHS_SFZ]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, settings[CARLA_KEY_PATHS_JSFX]) | |||||
| host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_CLAP, settings[CARLA_KEY_PATHS_CLAP]) | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # don't continue if plugin | # don't continue if plugin | ||||
| if host.isPlugin: | if host.isPlugin: | ||||
| return "Plugin" | return "Plugin" | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # osc settings | # osc settings | ||||
| if oscPort is not None and isinstance(oscPort, int): | if oscPort is not None and isinstance(oscPort, int): | ||||
| @@ -3454,84 +3567,65 @@ def setEngineSettings(host, oscPort = None): | |||||
| portNumTCP = portNumUDP = oscPort | portNumTCP = portNumUDP = oscPort | ||||
| else: | else: | ||||
| oscEnabled = settings.value(CARLA_KEY_OSC_ENABLED, CARLA_DEFAULT_OSC_ENABLED, bool) | |||||
| oscEnabled = settings[CARLA_KEY_OSC_ENABLED] | |||||
| if not settings.value(CARLA_KEY_OSC_TCP_PORT_ENABLED, CARLA_DEFAULT_OSC_TCP_PORT_ENABLED, bool): | |||||
| if not settings[CARLA_KEY_OSC_TCP_PORT_ENABLED]: | |||||
| portNumTCP = -1 | portNumTCP = -1 | ||||
| elif settings.value(CARLA_KEY_OSC_TCP_PORT_RANDOM, CARLA_DEFAULT_OSC_TCP_PORT_RANDOM, bool): | |||||
| elif settings[CARLA_KEY_OSC_TCP_PORT_RANDOM]: | |||||
| portNumTCP = 0 | portNumTCP = 0 | ||||
| else: | else: | ||||
| portNumTCP = settings.value(CARLA_KEY_OSC_TCP_PORT_NUMBER, CARLA_DEFAULT_OSC_TCP_PORT_NUMBER, int) | |||||
| portNumTCP = settings[CARLA_KEY_OSC_TCP_PORT_NUMBER] | |||||
| if not settings.value(CARLA_KEY_OSC_UDP_PORT_ENABLED, CARLA_DEFAULT_OSC_UDP_PORT_ENABLED, bool): | |||||
| if not settings[CARLA_KEY_OSC_UDP_PORT_ENABLED]: | |||||
| portNumUDP = -1 | portNumUDP = -1 | ||||
| elif settings.value(CARLA_KEY_OSC_UDP_PORT_RANDOM, CARLA_DEFAULT_OSC_UDP_PORT_RANDOM, bool): | |||||
| elif settings[CARLA_KEY_OSC_UDP_PORT_RANDOM]: | |||||
| portNumUDP = 0 | portNumUDP = 0 | ||||
| else: | else: | ||||
| portNumUDP = settings.value(CARLA_KEY_OSC_UDP_PORT_NUMBER, CARLA_DEFAULT_OSC_UDP_PORT_NUMBER, int) | |||||
| portNumUDP = settings[CARLA_KEY_OSC_UDP_PORT_NUMBER] | |||||
| host.set_engine_option(ENGINE_OPTION_OSC_ENABLED, 1 if oscEnabled else 0, "") | host.set_engine_option(ENGINE_OPTION_OSC_ENABLED, 1 if oscEnabled else 0, "") | ||||
| host.set_engine_option(ENGINE_OPTION_OSC_PORT_TCP, portNumTCP, "") | host.set_engine_option(ENGINE_OPTION_OSC_PORT_TCP, portNumTCP, "") | ||||
| host.set_engine_option(ENGINE_OPTION_OSC_PORT_UDP, portNumUDP, "") | host.set_engine_option(ENGINE_OPTION_OSC_PORT_UDP, portNumUDP, "") | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # wine settings | # wine settings | ||||
| optWineExecutable = settings.value(CARLA_KEY_WINE_EXECUTABLE, CARLA_DEFAULT_WINE_EXECUTABLE, str) | |||||
| optWineAutoPrefix = settings.value(CARLA_KEY_WINE_AUTO_PREFIX, CARLA_DEFAULT_WINE_AUTO_PREFIX, bool) | |||||
| optWineFallbackPrefix = settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, CARLA_DEFAULT_WINE_FALLBACK_PREFIX, str) | |||||
| optWineRtPrioEnabled = settings.value(CARLA_KEY_WINE_RT_PRIO_ENABLED, CARLA_DEFAULT_WINE_RT_PRIO_ENABLED, bool) | |||||
| optWineBaseRtPrio = settings.value(CARLA_KEY_WINE_BASE_RT_PRIO, CARLA_DEFAULT_WINE_BASE_RT_PRIO, int) | |||||
| optWineServerRtPrio = settings.value(CARLA_KEY_WINE_SERVER_RT_PRIO, CARLA_DEFAULT_WINE_SERVER_RT_PRIO, int) | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_EXECUTABLE, 0, settings[CARLA_KEY_WINE_EXECUTABLE]) | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_AUTO_PREFIX, 1 if settings[CARLA_KEY_WINE_AUTO_PREFIX] else 0, "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_FALLBACK_PREFIX, 0, os.path.expanduser(settings[CARLA_KEY_WINE_FALLBACK_PREFIX])) | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_RT_PRIO_ENABLED, 1 if settings[CARLA_KEY_WINE_RT_PRIO_ENABLED] else 0, "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_BASE_RT_PRIO, settings[CARLA_KEY_WINE_BASE_RT_PRIO], "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_SERVER_RT_PRIO, settings[CARLA_KEY_WINE_SERVER_RT_PRIO], "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_EXECUTABLE, 0, optWineExecutable) | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_AUTO_PREFIX, 1 if optWineAutoPrefix else 0, "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_FALLBACK_PREFIX, 0, os.path.expanduser(optWineFallbackPrefix)) | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_RT_PRIO_ENABLED, 1 if optWineRtPrioEnabled else 0, "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_BASE_RT_PRIO, optWineBaseRtPrio, "") | |||||
| host.set_engine_option(ENGINE_OPTION_WINE_SERVER_RT_PRIO, optWineServerRtPrio, "") | |||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # driver and device settings | # driver and device settings | ||||
| # driver name | # driver name | ||||
| if host.audioDriverForced is not None: | |||||
| audioDriver = host.audioDriverForced | |||||
| else: | |||||
| try: | |||||
| audioDriver = settings.value(CARLA_KEY_ENGINE_AUDIO_DRIVER, CARLA_DEFAULT_AUDIO_DRIVER, str) | |||||
| except: | |||||
| audioDriver = CARLA_DEFAULT_AUDIO_DRIVER | |||||
| # driver options | |||||
| audioDevice = settings.value("%s%s/Device" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, audioDriver), "", str) | |||||
| audioBufferSize = settings.value("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, audioDriver), CARLA_DEFAULT_AUDIO_BUFFER_SIZE, int) | |||||
| audioSampleRate = settings.value("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, audioDriver), CARLA_DEFAULT_AUDIO_SAMPLE_RATE, int) | |||||
| audioTripleBuffer = settings.value("%s%s/TripleBuffer" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, audioDriver), CARLA_DEFAULT_AUDIO_TRIPLE_BUFFER, bool) | |||||
| audioDriver = settings[CARLA_KEY_ENGINE_AUDIO_DRIVER] | |||||
| # Only setup audio things if engine is not running | # Only setup audio things if engine is not running | ||||
| if not host.is_engine_running(): | if not host.is_engine_running(): | ||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_DRIVER, 0, audioDriver) | host.set_engine_option(ENGINE_OPTION_AUDIO_DRIVER, 0, audioDriver) | ||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_DEVICE, 0, audioDevice) | |||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_DEVICE, 0, settings[CARLA_KEY_ENGINE_AUDIO_DEVICE]) | |||||
| if not audioDriver.startswith("JACK"): | if not audioDriver.startswith("JACK"): | ||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_BUFFER_SIZE, audioBufferSize, "") | |||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_SAMPLE_RATE, audioSampleRate, "") | |||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_TRIPLE_BUFFER, 1 if audioTripleBuffer else 0, "") | |||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_BUFFER_SIZE, settings[CARLA_KEY_ENGINE_BUFFER_SIZE], "") | |||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_SAMPLE_RATE, settings[CARLA_KEY_ENGINE_SAMPLE_RATE], "") | |||||
| host.set_engine_option(ENGINE_OPTION_AUDIO_TRIPLE_BUFFER, 1 if settings[CARLA_KEY_ENGINE_TRIPLE_BUFFER] else 0, "") | |||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # fix things if needed | # fix things if needed | ||||
| if audioDriver != "JACK" and host.transportMode == ENGINE_TRANSPORT_MODE_JACK: | if audioDriver != "JACK" and host.transportMode == ENGINE_TRANSPORT_MODE_JACK: | ||||
| host.transportMode = ENGINE_TRANSPORT_MODE_INTERNAL | host.transportMode = ENGINE_TRANSPORT_MODE_INTERNAL | ||||
| host.set_engine_option(ENGINE_OPTION_TRANSPORT_MODE, ENGINE_TRANSPORT_MODE_INTERNAL, host.transportExtra) | host.set_engine_option(ENGINE_OPTION_TRANSPORT_MODE, ENGINE_TRANSPORT_MODE_INTERNAL, host.transportExtra) | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # ----------------------------------------------------------------------------------------------------------------- | |||||
| # return selected driver name | # return selected driver name | ||||
| return audioDriver | return audioDriver | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # Run Carla without showing UI | # Run Carla without showing UI | ||||
| def runHostWithoutUI(host): | def runHostWithoutUI(host): | ||||
| @@ -3564,7 +3658,7 @@ def runHostWithoutUI(host): | |||||
| # -------------------------------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------------------------------- | ||||
| # Init engine | # Init engine | ||||
| audioDriver = setEngineSettings(host, oscPort) | |||||
| audioDriver = setEngineSettings(host, None, oscPort) | |||||
| if not host.engine_init(audioDriver, "Carla"): | if not host.engine_init(audioDriver, "Carla"): | ||||
| print("Engine failed to initialize, possible reasons:\n%s" % host.get_last_error()) | print("Engine failed to initialize, possible reasons:\n%s" % host.get_last_error()) | ||||
| sys.exit(1) | sys.exit(1) | ||||
| @@ -204,6 +204,10 @@ CARLA_KEY_CANVAS_FULL_REPAINTS = "Canvas/FullRepaints" # bool | |||||
| CARLA_KEY_ENGINE_DRIVER_PREFIX = "Engine/Driver-" | CARLA_KEY_ENGINE_DRIVER_PREFIX = "Engine/Driver-" | ||||
| CARLA_KEY_ENGINE_AUDIO_DRIVER = "Engine/AudioDriver" # str | CARLA_KEY_ENGINE_AUDIO_DRIVER = "Engine/AudioDriver" # str | ||||
| CARLA_KEY_ENGINE_AUDIO_DEVICE = "Engine/AudioDevice" # str | |||||
| CARLA_KEY_ENGINE_BUFFER_SIZE = "Engine/BufferSize" # int | |||||
| CARLA_KEY_ENGINE_SAMPLE_RATE = "Engine/SampleRate" # int | |||||
| CARLA_KEY_ENGINE_TRIPLE_BUFFER = "Engine/TripleBuffer" # bool | |||||
| CARLA_KEY_ENGINE_PROCESS_MODE = "Engine/ProcessMode" # enum | CARLA_KEY_ENGINE_PROCESS_MODE = "Engine/ProcessMode" # enum | ||||
| CARLA_KEY_ENGINE_TRANSPORT_MODE = "Engine/TransportMode" # enum | CARLA_KEY_ENGINE_TRANSPORT_MODE = "Engine/TransportMode" # enum | ||||
| CARLA_KEY_ENGINE_TRANSPORT_EXTRA = "Engine/TransportExtra" # str | CARLA_KEY_ENGINE_TRANSPORT_EXTRA = "Engine/TransportExtra" # str | ||||
| @@ -33,7 +33,6 @@ | |||||
| #include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
| #include "CarlaJuceUtils.hpp" | #include "CarlaJuceUtils.hpp" | ||||
| #include "CarlaFrontend.h" | |||||
| #include "CarlaUtils.h" | #include "CarlaUtils.h" | ||||
| #include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
| @@ -42,22 +41,6 @@ | |||||
| CARLA_BACKEND_USE_NAMESPACE | CARLA_BACKEND_USE_NAMESPACE | ||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Carla Settings keys | |||||
| #define CARLA_KEY_PATHS_LADSPA "Paths/LADSPA" | |||||
| #define CARLA_KEY_PATHS_DSSI "Paths/DSSI" | |||||
| #define CARLA_KEY_PATHS_LV2 "Paths/LV2" | |||||
| #define CARLA_KEY_PATHS_VST2 "Paths/VST2" | |||||
| #define CARLA_KEY_PATHS_VST3 "Paths/VST3" | |||||
| #define CARLA_KEY_PATHS_CLAP "Paths/CLAP" | |||||
| #define CARLA_KEY_PATHS_SF2 "Paths/SF2" | |||||
| #define CARLA_KEY_PATHS_SFZ "Paths/SFZ" | |||||
| #define CARLA_KEY_PATHS_JSFX "Paths/JSFX" | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // Carla Settings defaults | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // getenv with a fallback value if unset | // getenv with a fallback value if unset | ||||
| @@ -381,11 +364,11 @@ struct PluginPaths { | |||||
| static inline | static inline | ||||
| int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& string) | int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& string) | ||||
| { | { | ||||
| #if QT_VERSION >= 0x50b00 | |||||
| #if QT_VERSION >= 0x50b00 | |||||
| return fontMetrics.horizontalAdvance(string); | return fontMetrics.horizontalAdvance(string); | ||||
| #else | |||||
| #else | |||||
| return fontMetrics.width(string); | return fontMetrics.width(string); | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -692,6 +675,7 @@ struct PluginListDialog::PrivateData { | |||||
| carla_plugin_discovery_stop(handle); | carla_plugin_discovery_stop(handle); | ||||
| } | } | ||||
| #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | |||||
| bool nextTool() | bool nextTool() | ||||
| { | { | ||||
| if (handle != nullptr) | if (handle != nullptr) | ||||
| @@ -771,6 +755,7 @@ struct PluginListDialog::PrivateData { | |||||
| tool += ".exe"; | tool += ".exe"; | ||||
| #endif | #endif | ||||
| } | } | ||||
| #endif // CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | |||||
| } discovery; | } discovery; | ||||
| PluginPaths paths; | PluginPaths paths; | ||||
| @@ -825,13 +810,20 @@ struct PluginListDialog::PrivateData { | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // Plugin List Dialog | // Plugin List Dialog | ||||
| PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& hostSettings) | |||||
| PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings* const hostSettings) | |||||
| : QDialog(parent), | : QDialog(parent), | ||||
| p(new PrivateData) | p(new PrivateData) | ||||
| { | { | ||||
| ui.setupUi(this); | ui.setupUi(this); | ||||
| // p->hostSettings = hostSettings; | |||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| // Set-up global discovery options | |||||
| #ifndef CARLA_OS_WIN | |||||
| carla_plugin_discovery_set_option(ENGINE_OPTION_WINE_AUTO_PREFIX, hostSettings->wineAutoPrefix, nullptr); | |||||
| carla_plugin_discovery_set_option(ENGINE_OPTION_WINE_EXECUTABLE, 0, hostSettings->wineExecutable); | |||||
| carla_plugin_discovery_set_option(ENGINE_OPTION_WINE_FALLBACK_PREFIX, 0, hostSettings->wineFallbackPrefix); | |||||
| #endif | |||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| // Set-up GUI | // Set-up GUI | ||||
| @@ -917,7 +909,7 @@ PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& ho | |||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| // Set-up Icons | // Set-up Icons | ||||
| if (hostSettings.useSystemIcons) | |||||
| if (hostSettings->useSystemIcons) | |||||
| { | { | ||||
| #if 0 | #if 0 | ||||
| ui.b_add.setIcon(getIcon('list-add', 16, 'svgz')) | ui.b_add.setIcon(getIcon('list-add', 16, 'svgz')) | ||||
| @@ -1090,6 +1082,44 @@ bool PluginListDialog::checkPluginCache(const char* const filename, const char* | |||||
| return true; | return true; | ||||
| } | } | ||||
| void PluginListDialog::setPluginPath(const PluginType ptype, const char* const path) | |||||
| { | |||||
| switch (ptype) | |||||
| { | |||||
| case PLUGIN_LV2: | |||||
| p->paths.lv2 = path; | |||||
| break; | |||||
| case PLUGIN_VST2: | |||||
| p->paths.vst2 = path; | |||||
| break; | |||||
| case PLUGIN_VST3: | |||||
| p->paths.vst3 = path; | |||||
| break; | |||||
| case PLUGIN_CLAP: | |||||
| p->paths.clap = path; | |||||
| break; | |||||
| #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | |||||
| case PLUGIN_LADSPA: | |||||
| p->paths.ladspa = path; | |||||
| break; | |||||
| case PLUGIN_DSSI: | |||||
| p->paths.dssi = path; | |||||
| break; | |||||
| case PLUGIN_SF2: | |||||
| p->paths.sf2 = path; | |||||
| break; | |||||
| case PLUGIN_SFZ: | |||||
| p->paths.sfz = path; | |||||
| break; | |||||
| case PLUGIN_JSFX: | |||||
| p->paths.jsfx = path; | |||||
| break; | |||||
| #endif | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // protected methods | // protected methods | ||||
| @@ -1239,7 +1269,9 @@ void PluginListDialog::timerEvent(QTimerEvent* const event) | |||||
| #endif | #endif | ||||
| default: | default: | ||||
| // discovery complete | // discovery complete | ||||
| #ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS | |||||
| if (! p->discovery.nextTool()) | if (! p->discovery.nextTool()) | ||||
| #endif | |||||
| refreshPluginsStop(); | refreshPluginsStop(); | ||||
| } | } | ||||
| @@ -1489,7 +1521,7 @@ void PluginListDialog::loadSettings() | |||||
| #endif | #endif | ||||
| } | } | ||||
| // ----------------------------------------------------------------------------------------------------------------- | |||||
| // -------------------------------------------------------------------------------------------------------------------- | |||||
| // private slots | // private slots | ||||
| void PluginListDialog::cellClicked(const int row, const int column) | void PluginListDialog::cellClicked(const int row, const int column) | ||||
| @@ -1994,12 +2026,24 @@ void PluginListDialog::saveSettings() | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| PluginListDialog* | PluginListDialog* | ||||
| carla_frontend_createPluginListDialog(void* const parent) | |||||
| carla_frontend_createPluginListDialog(void* const parent, const HostSettings* const hostSettings) | |||||
| { | { | ||||
| const HostSettings hostSettings = {}; | |||||
| return new PluginListDialog(reinterpret_cast<QWidget*>(parent), hostSettings); | return new PluginListDialog(reinterpret_cast<QWidget*>(parent), hostSettings); | ||||
| } | } | ||||
| void | |||||
| carla_frontend_destroyPluginListDialog(PluginListDialog* const dialog) | |||||
| { | |||||
| dialog->close(); | |||||
| delete dialog; | |||||
| } | |||||
| void | |||||
| carla_frontend_setPluginListDialogPath(PluginListDialog* const dialog, const int ptype, const char* const path) | |||||
| { | |||||
| dialog->setPluginPath(static_cast<PluginType>(ptype), path); | |||||
| } | |||||
| const PluginListDialogResults* | const PluginListDialogResults* | ||||
| carla_frontend_execPluginListDialog(PluginListDialog* const dialog) | carla_frontend_execPluginListDialog(PluginListDialog* const dialog) | ||||
| { | { | ||||
| @@ -2046,13 +2090,12 @@ carla_frontend_execPluginListDialog(PluginListDialog* const dialog) | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| const PluginListDialogResults* | |||||
| carla_frontend_createAndExecPluginListDialog(void* const parent/*, const HostSettings& hostSettings*/) | |||||
| { | |||||
| const HostSettings hostSettings = {}; | |||||
| PluginListDialog gui(reinterpret_cast<QWidget*>(parent), hostSettings); | |||||
| return carla_frontend_execPluginListDialog(&gui); | |||||
| } | |||||
| // const PluginListDialogResults* | |||||
| // carla_frontend_createAndExecPluginListDialog(void* const parent, const HostSettings* const hostSettings) | |||||
| // { | |||||
| // PluginListDialog gui(reinterpret_cast<QWidget*>(parent), hostSettings); | |||||
| // | |||||
| // return carla_frontend_execPluginListDialog(&gui); | |||||
| // } | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -6,6 +6,8 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "CarlaFrontend.h" | |||||
| #ifdef __clang__ | #ifdef __clang__ | ||||
| # pragma clang diagnostic push | # pragma clang diagnostic push | ||||
| # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | # pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" | ||||
| @@ -26,14 +28,9 @@ | |||||
| #include "ui_pluginlistdialog.h" | #include "ui_pluginlistdialog.h" | ||||
| struct HostSettings { | |||||
| bool showPluginBridges; | |||||
| bool showWineBridges; | |||||
| bool useSystemIcons; | |||||
| }; | |||||
| class QSafeSettings; | class QSafeSettings; | ||||
| typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; | typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo; | ||||
| typedef struct _HostSettings HostSettings; | |||||
| struct PluginInfo; | struct PluginInfo; | ||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -63,12 +60,13 @@ class PluginListDialog : public QDialog | |||||
| // public methods | // public methods | ||||
| public: | public: | ||||
| explicit PluginListDialog(QWidget* parent, const HostSettings& hostSettings); | |||||
| explicit PluginListDialog(QWidget* parent, const HostSettings* hostSettings); | |||||
| ~PluginListDialog() override; | ~PluginListDialog() override; | ||||
| const PluginInfo& getSelectedPluginInfo() const; | const PluginInfo& getSelectedPluginInfo() const; | ||||
| void addPluginInfo(const CarlaPluginDiscoveryInfo* info, const char* sha1sum); | void addPluginInfo(const CarlaPluginDiscoveryInfo* info, const char* sha1sum); | ||||
| bool checkPluginCache(const char* filename, const char* sha1sum); | bool checkPluginCache(const char* filename, const char* sha1sum); | ||||
| void setPluginPath(PluginType ptype, const char* path); | |||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| // protected methods | // protected methods | ||||