Browse Source

Pass plugin path settings to auto-discovery

Signed-off-by: falkTX <falktx@falktx.com>
pull/1807/head
falkTX 1 year ago
parent
commit
1d24af0f28
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
10 changed files with 576 additions and 276 deletions
  1. +0
    -1
      source/backend/CarlaBackend.h
  2. +100
    -94
      source/backend/CarlaUtils.h
  3. +27
    -25
      source/backend/plugin/CarlaPluginBridge.cpp
  4. +125
    -12
      source/backend/utils/PluginDiscovery.cpp
  5. +25
    -7
      source/frontend/CarlaFrontend.h
  6. +33
    -10
      source/frontend/carla_frontend.py
  7. +180
    -86
      source/frontend/carla_host.py
  8. +4
    -0
      source/frontend/carla_shared.py
  9. +77
    -34
      source/frontend/pluginlist/pluginlistdialog.cpp
  10. +5
    -7
      source/frontend/pluginlist/pluginlistdialog.hpp

+ 0
- 1
source/backend/CarlaBackend.h View File

@@ -644,7 +644,6 @@ typedef enum {

/*!
* VST3 plugin.
* @note Windows and MacOS only
*/
PLUGIN_VST3 = 6,



+ 100
- 94
source/backend/CarlaUtils.h View File

@@ -22,6 +22,7 @@

#ifdef __cplusplus
using CARLA_BACKEND_NAMESPACE::BinaryType;
using CARLA_BACKEND_NAMESPACE::EngineOption;
using CARLA_BACKEND_NAMESPACE::PluginCategory;
using CARLA_BACKEND_NAMESPACE::PluginType;
#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 */

@@ -330,9 +237,108 @@ CARLA_PLUGIN_EXPORT void carla_plugin_discovery_skip(CarlaPluginDiscoveryHandle
*/
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 */

/*!
* 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.
* Internal and LV2 plugin formats are cached and need to be discovered via this function.


+ 27
- 25
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -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)
{
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);
}
#endif

// --------------------------------------------------------------------------------------------------------------------

@@ -128,15 +130,15 @@ public:
fBridgeBinary(),
fLabel(),
fShmIds(),
#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
fWinePrefix(),
#endif
#endif
fProcess() {}

void setData(
#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
const char* const winePrefix,
#endif
#endif
const char* const binaryArchName,
const char* const bridgeBinary,
const char* const label,
@@ -146,9 +148,9 @@ public:
CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',);
CARLA_SAFE_ASSERT(! isThreadRunning());

#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
fWinePrefix = winePrefix;
#endif
#endif
fBinaryArchName = binaryArchName;
fBridgeBinary = bridgeBinary;
fShmIds = shmIds;
@@ -190,7 +192,7 @@ protected:

StringArray arguments;

#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
// start with "wine" if needed
if (fBridgeBinary.endsWithIgnoreCase(".exe"))
{
@@ -212,7 +214,7 @@ protected:

arguments.add(wineCMD);
}
#endif
#endif

// setup binary arch
ChildProcess::Type childType;
@@ -245,10 +247,10 @@ protected:
{
const ScopedEngineEnvironmentLocker _seel(kEngine);

#ifdef CARLA_OS_LINUX
#ifdef CARLA_OS_LINUX
const CarlaScopedEnvVar sev1("LD_LIBRARY_PATH", nullptr);
const CarlaScopedEnvVar sev2("LD_PRELOAD", nullptr);
#endif
#endif

carla_setenv("ENGINE_OPTION_FORCE_STEREO", bool2str(options.forceStereo));
carla_setenv("ENGINE_OPTION_PREFER_PLUGIN_BRIDGES", bool2str(options.preferPluginBridges));
@@ -318,7 +320,7 @@ protected:

carla_setenv("ENGINE_BRIDGE_SHM_IDS", fShmIds.toRawUTF8());

#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
if (fWinePrefix.isNotEmpty())
{
carla_setenv("WINEDEBUG", "-all");
@@ -354,12 +356,12 @@ protected:
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,
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());

if (projFolder.isNotNull())
@@ -370,7 +372,7 @@ protected:
oldFolder.setAsCurrentWorkingDirectory();
}
else
#endif
#endif
{
started = fProcess->start(arguments, childType);
}
@@ -427,9 +429,9 @@ private:
String fBridgeBinary;
String fLabel;
String fShmIds;
#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
String fWinePrefix;
#endif
#endif

CarlaScopedPointer<ChildProcess> fProcess;

@@ -460,9 +462,9 @@ public:
fShmRtClientControl(),
fShmNonRtClientControl(),
fShmNonRtServerControl(),
#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
fWinePrefix(),
#endif
#endif
fReceivingParamText(),
fInfo(),
fUniqueId(0),
@@ -478,11 +480,11 @@ public:
{
carla_debug("CarlaPluginBridge::~CarlaPluginBridge()");

#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
// close UI
if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
pData->transientTryCounter = 0;
#endif
#endif

pData->singleMutex.lock();
pData->masterMutex.lock();
@@ -2754,7 +2756,7 @@ public:
return false;
}

#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
// ---------------------------------------------------------------
// set wine prefix

@@ -2767,7 +2769,7 @@ public:

if (fWinePrefix.isEmpty())
{
const char* const envWinePrefix(std::getenv("WINEPREFIX"));
const char* const envWinePrefix = std::getenv("WINEPREFIX");

if (envWinePrefix != nullptr && envWinePrefix[0] != '\0')
fWinePrefix = envWinePrefix;
@@ -2777,7 +2779,7 @@ public:
fWinePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine";
}
}
#endif
#endif

// ---------------------------------------------------------------
// init bridge thread
@@ -2914,9 +2916,9 @@ private:
BridgeNonRtClientControl fShmNonRtClientControl;
BridgeNonRtServerControl fShmNonRtServerControl;

#ifndef CARLA_OS_WIN
#ifndef CARLA_OS_WIN
String fWinePrefix;
#endif
#endif

class ReceivingParamText {
public:


+ 125
- 12
source/backend/utils/PluginDiscovery.cpp View File

@@ -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 = "";

_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
{
public:
@@ -367,36 +402,59 @@ private:

void start()
{
using water::File;
using water::String;

fLastMessageTime = carla_gettime_ms();
fPluginsFoundInBinary = false;
fNextSha1Sum.clear();

const char* helperTool;
#ifndef CARLA_OS_WIN
const CarlaPluginDiscoveryOptions& options(CarlaPluginDiscoveryOptions::getInstance());

String helperTool;

switch (fBinaryType)
{
#ifndef CARLA_OS_WIN
case CB::BINARY_WIN32:
helperTool = "wine";
if (options.wine.executable.isNotEmpty())
helperTool = options.wine.executable.buffer();
else
helperTool = "wine";
break;

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;
#endif
default:
helperTool = nullptr;
break;
}
#endif

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
{
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)
{
@@ -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());
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);
}

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

// --------------------------------------------------------------------------------------------------------------------

+ 25
- 7
source/frontend/CarlaFrontend.h View File

@@ -20,6 +20,7 @@
#include "CarlaBackend.h"

#ifdef __cplusplus
using CARLA_BACKEND_NAMESPACE::PluginType;
extern "C" {
#endif

@@ -31,6 +32,15 @@ typedef struct {
const char* labelSetup;
} JackAppDialogResults;

typedef struct _HostSettings {
bool showPluginBridges;
bool showWineBridges;
bool useSystemIcons;
bool wineAutoPrefix;
const char* wineExecutable;
const char* wineFallbackPrefix;
} HostSettings;

typedef struct {
uint build;
uint type;
@@ -55,20 +65,28 @@ struct PluginListDialog;

// --------------------------------------------------------------------------------------------------------------------

CARLA_API void
CARLA_PLUGIN_EXPORT void
carla_frontend_createAndExecAboutJuceDialog(void* parent);

CARLA_API const JackAppDialogResults*
CARLA_PLUGIN_EXPORT const JackAppDialogResults*
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_API const PluginListDialogResults*
carla_frontend_createAndExecPluginListDialog(void* parent/*, const HostSettings& hostSettings*/);
// CARLA_PLUGIN_EXPORT const PluginListDialogResults*
// carla_frontend_createAndExecPluginListDialog(void* parent, const HostSettings* hostSettings);

// --------------------------------------------------------------------------------------------------------------------



+ 33
- 10
source/frontend/carla_frontend.py View File

@@ -23,7 +23,7 @@
# Imports (ctypes)

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,
POINTER
)
@@ -53,6 +53,16 @@ class JackApplicationDialogResults(Structure):
("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):
_fields_ = [
("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.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_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.restype = POINTER(PluginListDialogResults)

self.lib.carla_frontend_createAndExecPluginListDialog.argtypes = (c_void_p,)
self.lib.carla_frontend_createAndExecPluginListDialog.restype = POINTER(PluginListDialogResults)

# --------------------------------------------------------------------------------------------------------

def createAndExecAboutJuceDialog(self, parent):
@@ -105,13 +118,23 @@ class CarlaFrontendLib():
return structToDictOrNull(self.lib.carla_frontend_createAndExecJackAppDialog(unwrapinstance(parent),
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):
return structToDictOrNull(self.lib.carla_frontend_execPluginListDialog(dialog))

def createAndExecPluginListDialog(self, parent, useSystemIcons):
return structToDictOrNull(self.lib.carla_frontend_createAndExecPluginListDialog(unwrapinstance(parent)))

# ------------------------------------------------------------------------------------------------------------

+ 180
- 86
source/frontend/carla_host.py View File

@@ -931,10 +931,11 @@ class HostWindow(QMainWindow):

@pyqtSlot()
def slot_engineStart(self):
audioDriver = setEngineSettings(self.host)
firstInit = self.fFirstEngineInit
audioDriver = setEngineSettings(self.host, self.fSavedSettings)

firstInit = self.fFirstEngineInit
self.fFirstEngineInit = False

self.ui.text_logs.appendPlainText("======= Starting engine =======")

if self.host.engine_init(audioDriver, self.fClientName):
@@ -953,9 +954,11 @@ class HostWindow(QMainWindow):
audioError = self.host.get_last_error()

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:
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()
def slot_engineStop(self, forced = False):
@@ -1209,10 +1212,27 @@ class HostWindow(QMainWindow):
def showAddPluginDialog(self):
# TODO self.fHasLoadedLv2Plugins
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)
print(ret)

# TODO
#if dialog.fFavoritePluginsChanged:
@@ -1940,6 +1960,10 @@ class HostWindow(QMainWindow):
def loadSettings(self, firstTime):
settings = QSafeSettings()

if self.fPluginListDialog is not None:
gCarla.felib.destroyPluginListDialog(self.fPluginListDialog)
self.fPluginListDialog = None

if firstTime:
geometry = settings.value("Geometry", QByteArray(), QByteArray)
if not geometry.isNull():
@@ -1990,6 +2014,13 @@ class HostWindow(QMainWindow):
# TODO - complete this
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 = {
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),
@@ -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_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"),

# 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:
@@ -2027,7 +2103,7 @@ class HostWindow(QMainWindow):

self.fMiniCanvasUpdateTimeout = 1000 if self.fSavedSettings[CARLA_KEY_CANVAS_FANCY_EYE_CANDY] else 0

setEngineSettings(self.host)
setEngineSettings(self.host, self.fSavedSettings)
self.restartTimersIfNeeded()

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):
host.set_engine_option(ENGINE_OPTION_CLIENT_NAME_PREFIX, 0, gCarla.cnprefix)

# ------------------------------------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------------------------------------------
# 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 :)
if False: host = CarlaHostNull()

# --------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------
# do nothing if control

if host.isControl:
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

setHostSettings(host)

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

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

if host.isPlugin:
return "Plugin"

# --------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------
# osc settings

if oscPort is not None and isinstance(oscPort, int):
@@ -3454,84 +3567,65 @@ def setEngineSettings(host, oscPort = None):
portNumTCP = portNumUDP = oscPort

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
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
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
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
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_PORT_TCP, portNumTCP, "")
host.set_engine_option(ENGINE_OPTION_OSC_PORT_UDP, portNumUDP, "")

# --------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------
# 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 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
if not host.is_engine_running():
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"):
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

if audioDriver != "JACK" and host.transportMode == ENGINE_TRANSPORT_MODE_JACK:
host.transportMode = ENGINE_TRANSPORT_MODE_INTERNAL
host.set_engine_option(ENGINE_OPTION_TRANSPORT_MODE, ENGINE_TRANSPORT_MODE_INTERNAL, host.transportExtra)

# --------------------------------------------------------------------------------------------------------
# -----------------------------------------------------------------------------------------------------------------
# return selected driver name

return audioDriver

# ------------------------------------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------------------------------------------
# Run Carla without showing UI

def runHostWithoutUI(host):
@@ -3564,7 +3658,7 @@ def runHostWithoutUI(host):
# --------------------------------------------------------------------------------------------------------
# Init engine

audioDriver = setEngineSettings(host, oscPort)
audioDriver = setEngineSettings(host, None, oscPort)
if not host.engine_init(audioDriver, "Carla"):
print("Engine failed to initialize, possible reasons:\n%s" % host.get_last_error())
sys.exit(1)


+ 4
- 0
source/frontend/carla_shared.py View File

@@ -204,6 +204,10 @@ CARLA_KEY_CANVAS_FULL_REPAINTS = "Canvas/FullRepaints" # bool

CARLA_KEY_ENGINE_DRIVER_PREFIX = "Engine/Driver-"
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_TRANSPORT_MODE = "Engine/TransportMode" # enum
CARLA_KEY_ENGINE_TRANSPORT_EXTRA = "Engine/TransportExtra" # str


+ 77
- 34
source/frontend/pluginlist/pluginlistdialog.cpp View File

@@ -33,7 +33,6 @@

#include "CarlaBackendUtils.hpp"
#include "CarlaJuceUtils.hpp"
#include "CarlaFrontend.h"
#include "CarlaUtils.h"

#include "CarlaString.hpp"
@@ -42,22 +41,6 @@

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

@@ -381,11 +364,11 @@ struct PluginPaths {
static inline
int fontMetricsHorizontalAdvance(const QFontMetrics& fontMetrics, const QString& string)
{
#if QT_VERSION >= 0x50b00
#if QT_VERSION >= 0x50b00
return fontMetrics.horizontalAdvance(string);
#else
#else
return fontMetrics.width(string);
#endif
#endif
}

// --------------------------------------------------------------------------------------------------------------------
@@ -692,6 +675,7 @@ struct PluginListDialog::PrivateData {
carla_plugin_discovery_stop(handle);
}

#ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS
bool nextTool()
{
if (handle != nullptr)
@@ -771,6 +755,7 @@ struct PluginListDialog::PrivateData {
tool += ".exe";
#endif
}
#endif // CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS
} discovery;

PluginPaths paths;
@@ -825,13 +810,20 @@ struct PluginListDialog::PrivateData {
// --------------------------------------------------------------------------------------------------------------------
// Plugin List Dialog

PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& hostSettings)
PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings* const hostSettings)
: QDialog(parent),
p(new PrivateData)
{
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
@@ -917,7 +909,7 @@ PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& ho
// ----------------------------------------------------------------------------------------------------------------
// Set-up Icons

if (hostSettings.useSystemIcons)
if (hostSettings->useSystemIcons)
{
#if 0
ui.b_add.setIcon(getIcon('list-add', 16, 'svgz'))
@@ -1090,6 +1082,44 @@ bool PluginListDialog::checkPluginCache(const char* const filename, const char*
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

@@ -1239,7 +1269,9 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
#endif
default:
// discovery complete
#ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS
if (! p->discovery.nextTool())
#endif
refreshPluginsStop();
}

@@ -1489,7 +1521,7 @@ void PluginListDialog::loadSettings()
#endif
}

// -----------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// private slots

void PluginListDialog::cellClicked(const int row, const int column)
@@ -1994,12 +2026,24 @@ void PluginListDialog::saveSettings()
// --------------------------------------------------------------------------------------------------------------------

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);
}

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*
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);
// }

// --------------------------------------------------------------------------------------------------------------------

+ 5
- 7
source/frontend/pluginlist/pluginlistdialog.hpp View File

@@ -6,6 +6,8 @@

#pragma once

#include "CarlaFrontend.h"

#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy"
@@ -26,14 +28,9 @@

#include "ui_pluginlistdialog.h"

struct HostSettings {
bool showPluginBridges;
bool showWineBridges;
bool useSystemIcons;
};

class QSafeSettings;
typedef struct _CarlaPluginDiscoveryInfo CarlaPluginDiscoveryInfo;
typedef struct _HostSettings HostSettings;
struct PluginInfo;

// --------------------------------------------------------------------------------------------------------------------
@@ -63,12 +60,13 @@ class PluginListDialog : public QDialog
// public methods

public:
explicit PluginListDialog(QWidget* parent, const HostSettings& hostSettings);
explicit PluginListDialog(QWidget* parent, const HostSettings* hostSettings);
~PluginListDialog() override;

const PluginInfo& getSelectedPluginInfo() const;
void addPluginInfo(const CarlaPluginDiscoveryInfo* info, const char* sha1sum);
bool checkPluginCache(const char* filename, const char* sha1sum);
void setPluginPath(PluginType ptype, const char* path);

// ----------------------------------------------------------------------------------------------------------------
// protected methods


Loading…
Cancel
Save