Browse Source

Implement automatic find of plugin wineprefix

Thanks to Jan Ypma for some base code
Closes #332
Closes #374
tags/1.9.8
falkTX 8 years ago
parent
commit
68bd68b6f1
3 changed files with 158 additions and 89 deletions
  1. +0
    -3
      resources/ui/carla_settings.ui
  2. +97
    -62
      source/backend/plugin/CarlaPluginBridge.cpp
  3. +61
    -24
      source/carla_database.py

+ 0
- 3
resources/ui/carla_settings.ui View File

@@ -1478,9 +1478,6 @@
<layout class="QGridLayout" name="gridLayout_6"> <layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0" colspan="2"> <item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="cb_wine_prefix_detect"> <widget class="QCheckBox" name="cb_wine_prefix_detect">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text"> <property name="text">
<string>Auto-detect Wine prefix based on plugin filename</string> <string>Auto-detect Wine prefix based on plugin filename</string>
</property> </property>


+ 97
- 62
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -30,7 +30,7 @@


#include <ctime> #include <ctime>


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


using juce::ChildProcess; using juce::ChildProcess;
using juce::File; using juce::File;
@@ -41,12 +41,27 @@ using juce::Time;


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


// -------------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------------
// Fallback data // Fallback data


static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 }; static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };


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

static String findWinePrefix(const String filename, const int recursionLimit = 10)
{
if (recursionLimit == 0 || filename.length() < 5 || ! filename.contains("/"))
return "";

const String path(filename.upToLastOccurrenceOf("/", false, false));

if (File(path + "/dosdevices").isDirectory())
return path;

return findWinePrefix(path, recursionLimit-1);
}

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


struct BridgeParamInfo { struct BridgeParamInfo {
float value; float value;
@@ -63,7 +78,7 @@ struct BridgeParamInfo {
CARLA_DECLARE_NON_COPY_STRUCT(BridgeParamInfo) CARLA_DECLARE_NON_COPY_STRUCT(BridgeParamInfo)
}; };


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


class CarlaPluginBridgeThread : public CarlaThread class CarlaPluginBridgeThread : public CarlaThread
{ {
@@ -77,12 +92,16 @@ public:
fShmIds(), fShmIds(),
fProcess() {} fProcess() {}


void setData(const char* const binary, const char* const label, const char* const shmIds) noexcept
void setData(const char* const winePrefix,
const char* const binary,
const char* const label,
const char* const shmIds) noexcept
{ {
CARLA_SAFE_ASSERT_RETURN(binary != nullptr && binary[0] != '\0',); CARLA_SAFE_ASSERT_RETURN(binary != nullptr && binary[0] != '\0',);
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());


fWinePrefix = winePrefix;
fBinary = binary; fBinary = binary;
fShmIds = shmIds; fShmIds = shmIds;


@@ -135,41 +154,6 @@ protected:
arguments.add(options.wine.executable); arguments.add(options.wine.executable);
else else
arguments.add("wine"); arguments.add("wine");

#if 0
if (options.wine.autoPrefix)
{
// TODO
}
else
#endif
if (std::getenv("WINEPREFIX") == nullptr &&
options.wine.fallbackPrefix != nullptr &&
options.wine.fallbackPrefix[0] != '\0')
{
carla_setenv("WINEPREFIX", options.wine.fallbackPrefix);
}

if (options.wine.rtPrio)
{
carla_setenv("STAGING_SHARED_MEMORY", "1");

std::snprintf(strBuf, STR_MAX, "%i", options.wine.baseRtPrio);
carla_setenv("STAGING_RT_PRIORITY_BASE", strBuf);
carla_setenv("WINE_RT", strBuf);

std::snprintf(strBuf, STR_MAX, "%i", options.wine.serverRtPrio);
carla_setenv("STAGING_RT_PRIORITY_SERVER", strBuf);
carla_setenv("WINE_SVR_RT", strBuf);
}
else
{
carla_unsetenv("STAGING_SHARED_MEMORY");
carla_unsetenv("STAGING_RT_PRIORITY_BASE");
carla_unsetenv("STAGING_RT_PRIORITY_SERVER");
carla_unsetenv("WINE_RT");
carla_unsetenv("WINE_SVR_RT");
}
} }
#endif #endif


@@ -265,7 +249,37 @@ protected:
carla_setenv("ENGINE_OPTION_FRONTEND_WIN_ID", strBuf); carla_setenv("ENGINE_OPTION_FRONTEND_WIN_ID", strBuf);


carla_setenv("ENGINE_BRIDGE_SHM_IDS", fShmIds.toRawUTF8()); carla_setenv("ENGINE_BRIDGE_SHM_IDS", fShmIds.toRawUTF8());
carla_setenv("WINEDEBUG", "-all");

#ifndef CARLA_OS_WIN
if (fWinePrefix.isNotEmpty())
{
carla_setenv("WINEDEBUG", "-all");
carla_setenv("WINEPREFIX", fWinePrefix.toRawUTF8());

if (options.wine.rtPrio)
{
carla_setenv("STAGING_SHARED_MEMORY", "1");

std::snprintf(strBuf, STR_MAX, "%i", options.wine.baseRtPrio);
carla_setenv("STAGING_RT_PRIORITY_BASE", strBuf);
carla_setenv("WINE_RT", strBuf);

std::snprintf(strBuf, STR_MAX, "%i", options.wine.serverRtPrio);
carla_setenv("STAGING_RT_PRIORITY_SERVER", strBuf);
carla_setenv("WINE_SVR_RT", strBuf);
}
else
{
carla_unsetenv("STAGING_SHARED_MEMORY");
carla_unsetenv("STAGING_RT_PRIORITY_BASE");
carla_unsetenv("STAGING_RT_PRIORITY_SERVER");
carla_unsetenv("WINE_RT");
carla_unsetenv("WINE_SVR_RT");
}

carla_stdout("Using WINEPREFIX '%s'", fWinePrefix.toRawUTF8());
}
#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,
fBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId()); fBinary.toRawUTF8(), getPluginTypeAsString(kPlugin->getType()), filename.toRawUTF8(), fLabel.toRawUTF8(), kPlugin->getUniqueId());
@@ -319,6 +333,7 @@ private:
CarlaEngine* const kEngine; CarlaEngine* const kEngine;
CarlaPlugin* const kPlugin; CarlaPlugin* const kPlugin;


String fWinePrefix;
String fBinary; String fBinary;
String fLabel; String fLabel;
String fShmIds; String fShmIds;
@@ -328,7 +343,7 @@ private:
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridgeThread) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridgeThread)
}; };


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


class CarlaPluginBridge : public CarlaPlugin class CarlaPluginBridge : public CarlaPlugin
{ {
@@ -2027,25 +2042,17 @@ public:
fShmNonRtServerControl.readCustomData(chunkFilePath, chunkFilePathSize); fShmNonRtServerControl.readCustomData(chunkFilePath, chunkFilePathSize);


String realChunkFilePath(chunkFilePath); String realChunkFilePath(chunkFilePath);
carla_stdout("chunk save path BEFORE => %s", realChunkFilePath.toRawUTF8());


#ifndef CARLA_OS_WIN #ifndef CARLA_OS_WIN
// Using Wine, fix temp dir // Using Wine, fix temp dir
if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64) if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64)
{ {
// Get WINEPREFIX
String wineDir;
if (const char* const WINEPREFIX = getenv("WINEPREFIX"))
wineDir = String(WINEPREFIX);
else
wineDir = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine";

const StringArray driveLetterSplit(StringArray::fromTokens(realChunkFilePath, ":/", "")); const StringArray driveLetterSplit(StringArray::fromTokens(realChunkFilePath, ":/", ""));
carla_stdout("chunk save path BEFORE => %s", realChunkFilePath.toRawUTF8());


realChunkFilePath = wineDir;
realChunkFilePath = fWinePrefix;
realChunkFilePath += "/drive_"; realChunkFilePath += "/drive_";
realChunkFilePath += driveLetterSplit[0].toLowerCase(); realChunkFilePath += driveLetterSplit[0].toLowerCase();
realChunkFilePath += "/";
realChunkFilePath += driveLetterSplit[1]; realChunkFilePath += driveLetterSplit[1];


realChunkFilePath = realChunkFilePath.replace("\\", "/"); realChunkFilePath = realChunkFilePath.replace("\\", "/");
@@ -2054,12 +2061,10 @@ public:
#endif #endif


File chunkFile(realChunkFilePath); File chunkFile(realChunkFilePath);
CARLA_SAFE_ASSERT_BREAK(chunkFile.existsAsFile());


if (chunkFile.existsAsFile())
{
fInfo.chunk = carla_getChunkFromBase64String(chunkFile.loadFileAsString().toRawUTF8());
chunkFile.deleteFile();
}
fInfo.chunk = carla_getChunkFromBase64String(chunkFile.loadFileAsString().toRawUTF8());
chunkFile.deleteFile();
} break; } break;


case kPluginBridgeNonRtServerSetLatency: case kPluginBridgeNonRtServerSetLatency:
@@ -2193,8 +2198,8 @@ public:
} }


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

// initial values // initial values

fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientNull); fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientNull);
fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeRtClientData))); fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeRtClientData)));
fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeNonRtClientData))); fShmNonRtClientControl.writeUInt(static_cast<uint32_t>(sizeof(BridgeNonRtClientData)));
@@ -2210,7 +2215,32 @@ public:
fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull); fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull);
fShmRtClientControl.commitWrite(); fShmRtClientControl.commitWrite();


// ---------------------------------------------------------------
// set wine prefix

if (fBridgeBinary.contains(".exe", true))
{
const EngineOptions& options(pData->engine->getOptions());

if (options.wine.autoPrefix)
fWinePrefix = findWinePrefix(pData->filename);

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

if (envWinePrefix != nullptr && envWinePrefix[0] != '\0')
fWinePrefix = envWinePrefix;
else if (options.wine.fallbackPrefix != nullptr && options.wine.fallbackPrefix[0] != '\0')
fWinePrefix = options.wine.fallbackPrefix;
else
fWinePrefix = File::getSpecialLocation(File::userHomeDirectory).getFullPathName() + "/.wine";
}
}

// ---------------------------------------------------------------
// init bridge thread // init bridge thread

{ {
char shmIdsStr[6*4+1]; char shmIdsStr[6*4+1];
carla_zeroChars(shmIdsStr, 6*4+1); carla_zeroChars(shmIdsStr, 6*4+1);
@@ -2220,10 +2250,13 @@ public:
std::strncpy(shmIdsStr+6*2, &fShmNonRtClientControl.filename[fShmNonRtClientControl.filename.length()-6], 6); std::strncpy(shmIdsStr+6*2, &fShmNonRtClientControl.filename[fShmNonRtClientControl.filename.length()-6], 6);
std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6); std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6);


fBridgeThread.setData(bridgeBinary, label, shmIdsStr);
fBridgeThread.setData(fWinePrefix.toRawUTF8(), bridgeBinary, label, shmIdsStr);
fBridgeThread.startThread(); fBridgeThread.startThread();
} }


// ---------------------------------------------------------------
// wait for bridge to start

fInitiated = false; fInitiated = false;
fLastPongTime = Time::currentTimeMillis(); fLastPongTime = Time::currentTimeMillis();
CARLA_SAFE_ASSERT(fLastPongTime > 0); CARLA_SAFE_ASSERT(fLastPongTime > 0);
@@ -2314,6 +2347,8 @@ private:
BridgeNonRtClientControl fShmNonRtClientControl; BridgeNonRtClientControl fShmNonRtClientControl;
BridgeNonRtServerControl fShmNonRtServerControl; BridgeNonRtServerControl fShmNonRtServerControl;


String fWinePrefix;

struct Info { struct Info {
uint32_t aIns, aOuts; uint32_t aIns, aOuts;
uint32_t cvIns, cvOuts; uint32_t cvIns, cvOuts;
@@ -2381,7 +2416,7 @@ private:


CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


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


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


@@ -2414,10 +2449,10 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P


CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


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


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
# include "CarlaBridgeUtils.cpp" # include "CarlaBridgeUtils.cpp"
#endif #endif


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

+ 61
- 24
source/carla_database.py View File

@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-


# Carla plugin database code # Carla plugin database code
# Copyright (C) 2011-2016 Filipe Coelho <falktx@falktx.com>
# Copyright (C) 2011-2017 Filipe Coelho <falktx@falktx.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as # modify it under the terms of the GNU General Public License as
@@ -162,7 +162,18 @@ PyPluginInfo = {
global gDiscoveryProcess global gDiscoveryProcess
gDiscoveryProcess = None gDiscoveryProcess = None


def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
def findWinePrefix(filename, recursionLimit = 10):
if recursionLimit == 0 or len(filename) < 5 or "/" not in filename:
return ""

path = filename[:filename.rfind("/")]

if os.path.isdir(path + "/dosdevices"):
return path

return findWinePrefix(path, recursionLimit-1)

def runCarlaDiscovery(itype, stype, filename, tool, wineSettings=None):
if not os.path.exists(tool): if not os.path.exists(tool):
qWarning("runCarlaDiscovery() - tool '%s' does not exist" % tool) qWarning("runCarlaDiscovery() - tool '%s' does not exist" % tool)
return return
@@ -173,9 +184,26 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
command.append("env") command.append("env")
command.append("LANG=C") command.append("LANG=C")
command.append("LD_PRELOAD=") command.append("LD_PRELOAD=")
if isWine:
if wineSettings is not None:
command.append("WINEDEBUG=-all") command.append("WINEDEBUG=-all")
command.append("wine")

if wineSettings['autoPrefix']:
winePrefix = findWinePrefix(filename)
else:
winePrefix = ""

if not winePrefix:
envWinePrefix = os.getenv("WINEPREFIX")

if envWinePrefix:
winePrefix = envWinePrefix
elif wineSettings['fallbackPrefix']:
winePrefix = os.path.expanduser(wineSettings['fallbackPrefix'])
else:
winePrefix = os.path.expanduser("~/.wine")

command.append("WINEPREFIX=" + winePrefix)
command.append(wineSettings['executable'] if wineSettings['executable'] else "wine")


command.append(tool) command.append(tool)
command.append(stype) command.append(stype)
@@ -314,32 +342,32 @@ def checkPluginCached(desc, ptype):


return plugins return plugins


def checkPluginLADSPA(filename, tool, isWine=False):
return runCarlaDiscovery(PLUGIN_LADSPA, "LADSPA", filename, tool, isWine)
def checkPluginLADSPA(filename, tool, wineSettings=None):
return runCarlaDiscovery(PLUGIN_LADSPA, "LADSPA", filename, tool, wineSettings)


def checkPluginDSSI(filename, tool, isWine=False):
return runCarlaDiscovery(PLUGIN_DSSI, "DSSI", filename, tool, isWine)
def checkPluginDSSI(filename, tool, wineSettings=None):
return runCarlaDiscovery(PLUGIN_DSSI, "DSSI", filename, tool, wineSettings)


def checkPluginLV2(filename, tool, isWine=False):
return runCarlaDiscovery(PLUGIN_LV2, "LV2", filename, tool, isWine)
def checkPluginLV2(filename, tool, wineSettings=None):
return runCarlaDiscovery(PLUGIN_LV2, "LV2", filename, tool, wineSettings)


def checkPluginVST2(filename, tool, isWine=False):
return runCarlaDiscovery(PLUGIN_VST2, "VST2", filename, tool, isWine)
def checkPluginVST2(filename, tool, wineSettings=None):
return runCarlaDiscovery(PLUGIN_VST2, "VST2", filename, tool, wineSettings)


def checkPluginVST3(filename, tool, isWine=False):
return runCarlaDiscovery(PLUGIN_VST3, "VST3", filename, tool, isWine)
def checkPluginVST3(filename, tool, wineSettings=None):
return runCarlaDiscovery(PLUGIN_VST3, "VST3", filename, tool, wineSettings)


def checkPluginAU(tool): def checkPluginAU(tool):
return runCarlaDiscovery(PLUGIN_AU, "AU", ":all", tool)
return runCarlaDiscovery(None, PLUGIN_AU, "AU", ":all", tool)


def checkFileGIG(filename, tool): def checkFileGIG(filename, tool):
return runCarlaDiscovery(PLUGIN_GIG, "GIG", filename, tool)
return runCarlaDiscovery(None, PLUGIN_GIG, "GIG", filename, tool)


def checkFileSF2(filename, tool): def checkFileSF2(filename, tool):
return runCarlaDiscovery(PLUGIN_SF2, "SF2", filename, tool)
return runCarlaDiscovery(None, PLUGIN_SF2, "SF2", filename, tool)


def checkFileSFZ(filename, tool): def checkFileSFZ(filename, tool):
return runCarlaDiscovery(PLUGIN_SFZ, "SFZ", filename, tool)
return runCarlaDiscovery(None, PLUGIN_SFZ, "SFZ", filename, tool)


# ---------------------------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------------------------
# Separate Thread for Plugin Search # Separate Thread for Plugin Search
@@ -371,9 +399,19 @@ class SearchPluginsThread(QThread):


if WINDOWS: if WINDOWS:
toolNative = "carla-discovery-win64.exe" if kIs64bit else "carla-discovery-win32.exe" toolNative = "carla-discovery-win64.exe" if kIs64bit else "carla-discovery-win32.exe"
self.fWineSettings = None

else: else:
toolNative = "carla-discovery-native" toolNative = "carla-discovery-native"


settings = QSettings("falkTX", "Carla2")
self.fWineSettings = {
'executable' : settings.value(CARLA_KEY_WINE_EXECUTABLE, CARLA_DEFAULT_WINE_EXECUTABLE, type=str),
'autoPrefix' : settings.value(CARLA_KEY_WINE_AUTO_PREFIX, CARLA_DEFAULT_WINE_AUTO_PREFIX, type=bool),
'fallbackPrefix': settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, CARLA_DEFAULT_WINE_FALLBACK_PREFIX, type=str)
}
del settings

self.fToolNative = os.path.join(pathBinaries, toolNative) self.fToolNative = os.path.join(pathBinaries, toolNative)


if not os.path.exists(self.fToolNative): if not os.path.exists(self.fToolNative):
@@ -713,7 +751,7 @@ class SearchPluginsThread(QThread):
percent = ( float(i) / len(ladspaBinaries) ) * self.fCurPercentValue percent = ( float(i) / len(ladspaBinaries) ) * self.fCurPercentValue
self._pluginLook((self.fLastCheckValue + percent) * 0.9, ladspa) self._pluginLook((self.fLastCheckValue + percent) * 0.9, ladspa)


plugins = checkPluginLADSPA(ladspa, tool, isWine)
plugins = checkPluginLADSPA(ladspa, tool, self.fWineSettings if isWine else None)
if plugins: if plugins:
self.fLadspaPlugins.append(plugins) self.fLadspaPlugins.append(plugins)


@@ -746,7 +784,7 @@ class SearchPluginsThread(QThread):
percent = ( float(i) / len(dssiBinaries) ) * self.fCurPercentValue percent = ( float(i) / len(dssiBinaries) ) * self.fCurPercentValue
self._pluginLook(self.fLastCheckValue + percent, dssi) self._pluginLook(self.fLastCheckValue + percent, dssi)


plugins = checkPluginDSSI(dssi, tool, isWine)
plugins = checkPluginDSSI(dssi, tool, self.fWineSettings if isWine else None)
if plugins: if plugins:
self.fDssiPlugins.append(plugins) self.fDssiPlugins.append(plugins)


@@ -785,7 +823,7 @@ class SearchPluginsThread(QThread):
percent = ( float(i) / len(vst2Binaries) ) * self.fCurPercentValue percent = ( float(i) / len(vst2Binaries) ) * self.fCurPercentValue
self._pluginLook(self.fLastCheckValue + percent, vst2) self._pluginLook(self.fLastCheckValue + percent, vst2)


plugins = checkPluginVST2(vst2, tool, isWine)
plugins = checkPluginVST2(vst2, tool, self.fWineSettings if isWine else None)
if plugins: if plugins:
self.fVstPlugins.append(plugins) self.fVstPlugins.append(plugins)


@@ -824,7 +862,7 @@ class SearchPluginsThread(QThread):
percent = ( float(i) / len(vst3Binaries) ) * self.fCurPercentValue percent = ( float(i) / len(vst3Binaries) ) * self.fCurPercentValue
self._pluginLook(self.fLastCheckValue + percent, vst3) self._pluginLook(self.fLastCheckValue + percent, vst3)


plugins = checkPluginVST3(vst3, tool, isWine)
plugins = checkPluginVST3(vst3, tool, self.fWineSettings if isWine else None)
if plugins: if plugins:
self.fVst3Plugins.append(plugins) self.fVst3Plugins.append(plugins)


@@ -928,8 +966,7 @@ class PluginRefreshW(QDialog):


if False: if False:
# kdevelop likes this :) # kdevelop likes this :)
host = CarlaHostNull()
self.host = host
self.host = host = CarlaHostNull()


# -------------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------------
# Internal stuff # Internal stuff


Loading…
Cancel
Save