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 | ||||