Browse Source

Implement auto-discovery for wine bridges

Signed-off-by: falkTX <falktx@falktx.com>
pull/1807/head
falkTX 1 year ago
parent
commit
cec462a44d
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
17 changed files with 452 additions and 126 deletions
  1. +1
    -1
      Makefile
  2. +1
    -0
      source/backend/CarlaUtils.h
  3. +1
    -0
      source/backend/utils/Makefile
  4. +1
    -1
      source/backend/utils/PipeClient.cpp
  5. +89
    -27
      source/backend/utils/PluginDiscovery.cpp
  6. +10
    -5
      source/discovery/Makefile
  7. +45
    -2
      source/discovery/carla-discovery.cpp
  8. +142
    -50
      source/frontend/pluginlist/pluginlistdialog.cpp
  9. +4
    -0
      source/jackbridge/JackBridge.hpp
  10. +70
    -5
      source/jackbridge/JackBridge2.cpp
  11. +7
    -4
      source/jackbridge/JackBridge3.cpp
  12. +32
    -10
      source/jackbridge/JackBridgeExport.cpp
  13. +9
    -1
      source/jackbridge/JackBridgeExport.hpp
  14. +7
    -1
      source/jackbridge/Makefile
  15. +1
    -1
      source/utils/CarlaBinaryUtils.hpp
  16. +23
    -16
      source/utils/CarlaPipeUtils.cpp
  17. +9
    -2
      source/utils/CarlaPipeUtils.hpp

+ 1
- 1
Makefile View File

@@ -124,7 +124,7 @@ $(MODULEDIR)/carla_plugin.a: .FORCE
$(MODULEDIR)/jackbridge.a: .FORCE
@$(MAKE) -C source/jackbridge

$(MODULEDIR)/jackbridge.%.a: $(MODULEDIR)/jackbridge.a
$(MODULEDIR)/jackbridge.%.a: .FORCE
@$(MAKE) -C source/jackbridge $*

$(MODULEDIR)/native-plugins.a: .FORCE


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

@@ -304,6 +304,7 @@ typedef bool (*CarlaPluginCheckCacheCallback)(void* ptr, const char* filename, c
* @a carla_plugin_discovery_idle must be called at regular intervals afterwards.
*/
CARLA_PLUGIN_EXPORT CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* discoveryTool,
BinaryType btype,
PluginType ptype,
const char* pluginPath,
CarlaPluginDiscoveryCallback discoveryCb,


+ 1
- 0
source/backend/utils/Makefile View File

@@ -10,6 +10,7 @@ include ../Makefile.mk
# ---------------------------------------------------------------------------------------------------------------------

BUILD_CXX_FLAGS += $(FLUIDSYNTH_FLAGS)
BUILD_CXX_FLAGS += $(MAGIC_LIBS)
BUILD_CXX_FLAGS += $(YSFX_FLAGS)

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


+ 1
- 1
source/backend/utils/PipeClient.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as


+ 89
- 27
source/backend/utils/PluginDiscovery.cpp View File

@@ -18,6 +18,7 @@
#include "CarlaUtils.h"

#include "CarlaBackendUtils.hpp"
#include "CarlaBinaryUtils.hpp"
#include "CarlaJuceUtils.hpp"
#include "CarlaPipeUtils.hpp"
#include "CarlaSha1Utils.hpp"
@@ -64,12 +65,14 @@ class CarlaPluginDiscovery : private CarlaPipeServer
{
public:
CarlaPluginDiscovery(const char* const discoveryTool,
const BinaryType btype,
const PluginType ptype,
const std::vector<water::File>&& binaries,
const CarlaPluginDiscoveryCallback discoveryCb,
const CarlaPluginCheckCacheCallback checkCacheCb,
void* const callbackPtr)
: fPluginType(ptype),
: fBinaryType(btype),
fPluginType(ptype),
fDiscoveryCallback(discoveryCb),
fCheckCacheCallback(checkCacheCb),
fCallbackPtr(callbackPtr),
@@ -87,11 +90,13 @@ public:
}

CarlaPluginDiscovery(const char* const discoveryTool,
const BinaryType btype,
const PluginType ptype,
const CarlaPluginDiscoveryCallback discoveryCb,
const CarlaPluginCheckCacheCallback checkCacheCb,
void* const callbackPtr)
: fPluginType(ptype),
: fBinaryType(btype),
fPluginType(ptype),
fDiscoveryCallback(discoveryCb),
fCheckCacheCallback(checkCacheCb),
fCallbackPtr(callbackPtr),
@@ -340,6 +345,7 @@ protected:
}

private:
const BinaryType fBinaryType;
const PluginType fPluginType;
const CarlaPluginDiscoveryCallback fDiscoveryCallback;
const CarlaPluginCheckCacheCallback fCheckCacheCallback;
@@ -365,9 +371,25 @@ private:
fPluginsFoundInBinary = false;
fNextSha1Sum.clear();

const char* helperTool;
switch (fBinaryType)
{
#ifndef CARLA_OS_WIN
case CB::BINARY_WIN32:
helperTool = "wine";
break;
case CB::BINARY_WIN64:
helperTool = "wine64";
break;
#endif
default:
helperTool = nullptr;
break;
}

if (fBinaries.empty())
{
startPipeServer(fDiscoveryTool,
startPipeServer(helperTool, fDiscoveryTool,
getPluginTypeAsString(fPluginType),
":all");
}
@@ -389,7 +411,7 @@ private:
}

carla_stdout("Scanning \"%s\"...", filename.toRawUTF8());
startPipeServer(fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8());
startPipeServer(helperTool, fDiscoveryTool, getPluginTypeAsString(fPluginType), filename.toRawUTF8());
}
}

@@ -455,7 +477,8 @@ static bool findDirectories(std::vector<water::File>& files, const char* const p
return files.empty();
}

static bool findFiles(std::vector<water::File>& files, const char* const pluginPath, const char* const wildcard)
static bool findFiles(std::vector<water::File>& files,
const BinaryType btype, const char* const pluginPath, const char* const wildcard)
{
CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true);

@@ -479,14 +502,22 @@ static bool findFiles(std::vector<water::File>& files, const char* const pluginP
if (dir.findChildFiles(results, File::findFiles|File::ignoreHiddenFiles, true, wildcard) > 0)
{
files.reserve(files.size() + results.size());
files.insert(files.end(), results.begin(), results.end());

for (std::vector<File>::const_iterator cit = results.begin(); cit != results.end(); ++cit)
{
const File file(*cit);

if (CB::getBinaryTypeFromFile(file.getFullPathName().toRawUTF8()) == btype)
files.push_back(file);
}
}
}

return files.empty();
}

static bool findVST3s(std::vector<water::File>& files, const char* const pluginPath)
static bool findVST3s(std::vector<water::File>& files,
const BinaryType btype, const char* const pluginPath)
{
CARLA_SAFE_ASSERT_RETURN(pluginPath != nullptr, true);

@@ -502,11 +533,9 @@ static bool findVST3s(std::vector<water::File>& files, const char* const pluginP
if (splitPaths.size() == 0)
return true;

#if defined(CARLA_OS_WIN)
static constexpr const uint flags = File::findDirectories|File::findFiles;
#else
static constexpr const uint flags = File::findDirectories;
#endif
const uint flags = btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64
? File::findDirectories|File::findFiles
: File::findDirectories;

for (String *it = splitPaths.begin(), *end = splitPaths.end(); it != end; ++it)
{
@@ -516,7 +545,14 @@ static bool findVST3s(std::vector<water::File>& files, const char* const pluginP
if (dir.findChildFiles(results, flags|File::ignoreHiddenFiles, true, "*.vst3") > 0)
{
files.reserve(files.size() + results.size());
files.insert(files.end(), results.begin(), results.end());

for (std::vector<File>::const_iterator cit = results.begin(); cit != results.end(); ++cit)
{
const File file(*cit);

if (CB::getBinaryTypeFromFile(file.getFullPathName().toRawUTF8()) == btype)
files.push_back(file);
}
}
}

@@ -524,12 +560,15 @@ static bool findVST3s(std::vector<water::File>& files, const char* const pluginP
}

CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discoveryTool,
const BinaryType btype,
const PluginType ptype,
const char* const pluginPath,
const CarlaPluginDiscoveryCallback discoveryCb,
const CarlaPluginCheckCacheCallback checkCacheCb,
void* const callbackPtr)
{
CARLA_SAFE_ASSERT_RETURN(btype != CB::BINARY_NONE, nullptr);
CARLA_SAFE_ASSERT_RETURN(ptype != CB::PLUGIN_NONE, nullptr);
CARLA_SAFE_ASSERT_RETURN(discoveryTool != nullptr && discoveryTool[0] != '\0', nullptr);
CARLA_SAFE_ASSERT_RETURN(discoveryCb != nullptr, nullptr);

@@ -547,44 +586,66 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov
case CB::PLUGIN_JSFX:
{
const CarlaScopedEnvVar csev("CARLA_DISCOVERY_PATH", pluginPath);
return new CarlaPluginDiscovery(discoveryTool, ptype, discoveryCb, checkCacheCb, callbackPtr);
return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr);
}

case CB::PLUGIN_INTERNAL:
case CB::PLUGIN_LV2:
case CB::PLUGIN_AU:
return new CarlaPluginDiscovery(discoveryTool, ptype, discoveryCb, checkCacheCb, callbackPtr);
return new CarlaPluginDiscovery(discoveryTool, btype, ptype, discoveryCb, checkCacheCb, callbackPtr);

case CB::PLUGIN_LADSPA:
case CB::PLUGIN_DSSI:
#if defined(CARLA_OS_MAC)
wildcard = "*.dylib";
#elif defined(CARLA_OS_WIN)
#ifdef CARLA_OS_WIN
wildcard = "*.dll";
#else
wildcard = "*.so";
if (btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64)
{
wildcard = "*.dll";
}
else
{
#ifdef CARLA_OS_MAC
wildcard = "*.dylib";
#else
wildcard = "*.so";
#endif
}
#endif
break;

case CB::PLUGIN_VST2:
#if defined(CARLA_OS_MAC)
directories = true;
wildcard = "*.vst";
#elif defined(CARLA_OS_WIN)
#ifdef CARLA_OS_WIN
wildcard = "*.dll";
#else
wildcard = "*.so";
if (btype == CB::BINARY_WIN32 || btype == CB::BINARY_WIN64)
{
wildcard = "*.dll";
}
else
{
#ifdef CARLA_OS_MAC
directories = true;
wildcard = "*.vst";
#else
wildcard = "*.so";
#endif
}
#endif
break;

case CB::PLUGIN_VST3:
directories = true;
wildcard = "*.vst3";
break;

case CB::PLUGIN_CLAP:
wildcard = "*.clap";
#ifdef CARLA_OS_MAC
directories = true;
#endif
break;

case CB::PLUGIN_DLS:
wildcard = "*.dls";
break;
@@ -602,7 +663,7 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov

if (ptype == CB::PLUGIN_VST3)
{
if (findVST3s(files, pluginPath))
if (findVST3s(files, btype, pluginPath))
return nullptr;
}
else if (directories)
@@ -612,11 +673,12 @@ CarlaPluginDiscoveryHandle carla_plugin_discovery_start(const char* const discov
}
else
{
if (findFiles(files, pluginPath, wildcard))
if (findFiles(files, btype, pluginPath, wildcard))
return nullptr;
}

return new CarlaPluginDiscovery(discoveryTool, ptype, std::move(files), discoveryCb, checkCacheCb, callbackPtr);
return new CarlaPluginDiscovery(discoveryTool, btype, ptype, std::move(files),
discoveryCb, checkCacheCb, callbackPtr);
}

bool carla_plugin_discovery_idle(const CarlaPluginDiscoveryHandle handle)


+ 10
- 5
source/discovery/Makefile View File

@@ -79,11 +79,11 @@ LIBS_win64 = $(MODULEDIR)/lilv.win64.a
LINK_FLAGS += $(LILV_LIBS)

LIBS_native += $(MODULEDIR)/water.files.a
LIBS_arm32 = $(MODULEDIR)/water.files.arm32.a
LIBS_posix32 = $(MODULEDIR)/water.posix32.a
LIBS_posix64 = $(MODULEDIR)/water.posix64.a
LIBS_win32 = $(MODULEDIR)/water.win32.a
LIBS_win64 = $(MODULEDIR)/water.win64.a
LIBS_arm32 += $(MODULEDIR)/water.files.arm32.a
LIBS_posix32 += $(MODULEDIR)/water.posix32.a
LIBS_posix64 += $(MODULEDIR)/water.posix64.a
LIBS_win32 += $(MODULEDIR)/water.win32.a
LIBS_win64 += $(MODULEDIR)/water.win64.a
LINK_FLAGS += $(WATER_LIBS)
LINK_FLAGS += $(LIBDL_LIBS)

@@ -92,6 +92,11 @@ LIBS_native += $(MODULEDIR)/ysfx.a
LINK_FLAGS += $(YSFX_GRAPHICS_LIBS)
endif

ifeq ($(BUILDING_FOR_WINE),true)
LIBS_win32 += $(MODULEDIR)/jackbridge.win32e.a
LIBS_win64 += $(MODULEDIR)/jackbridge.win64e.a
endif

ifeq ($(USING_JUCE),true)
LIBS_native += $(MODULEDIR)/carla_juce.a
LIBS_native += $(MODULEDIR)/juce_audio_basics.a


+ 45
- 2
source/discovery/carla-discovery.cpp View File

@@ -18,7 +18,6 @@
#include "CarlaBackendUtils.hpp"
#include "CarlaLibUtils.hpp"
#include "CarlaMathUtils.hpp"
#include "CarlaPipeUtils.cpp"
#include "CarlaScopeUtils.hpp"

#include "CarlaMIDI.h"
@@ -31,6 +30,10 @@
#include "CarlaVst3Utils.hpp"
#include "CarlaClapUtils.hpp"

#ifndef BUILDING_CARLA_FOR_WINE
# include "CarlaPipeUtils.cpp"
#endif

#ifdef CARLA_OS_MAC
# include "CarlaMacUtils.cpp"
# ifdef __aarch64__
@@ -80,6 +83,11 @@
# pragma GCC diagnostic pop
#endif

// must be last
#ifdef BUILDING_CARLA_FOR_WINE
# include "../jackbridge/JackBridge.hpp"
#endif

#define MAX_DISCOVERY_AUDIO_IO 64
#define MAX_DISCOVERY_CV_IO 32

@@ -102,6 +110,7 @@ static constexpr const float kSampleRatef = 44100.0f;
// --------------------------------------------------------------------------------------------------------------------
// Dynamic discovery

#ifndef BUILDING_CARLA_FOR_WINE
class DiscoveryPipe : public CarlaPipeClient
{
public:
@@ -124,7 +133,7 @@ public:
if (! writeAndFixMessage(value))
return false;

flushMessages();
syncMessages();
return true;
}

@@ -135,6 +144,37 @@ protected:
return true;
}
};
#else
class DiscoveryPipe
{
void* pipe;

public:
DiscoveryPipe() noexcept : pipe(nullptr) {}

~DiscoveryPipe()
{
jackbridge_discovery_pipe_destroy(pipe);
}

bool initPipeClient(const char* argv[])
{
if (jackbridge_is_ok())
pipe = jackbridge_discovery_pipe_create(argv);

return pipe != nullptr;
}

bool writeDiscoveryMessage(const char* const key, const char* const value) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false);
CARLA_SAFE_ASSERT_RETURN(value != nullptr, false);

jackbridge_discovery_pipe_message(pipe, key, value);
return true;
}
};
#endif

CarlaScopedPointer<DiscoveryPipe> gPipe;

@@ -2667,6 +2707,7 @@ int main(int argc, const char* argv[])
if (handle == nullptr)
{
print_lib_error(filename);
gPipe = nullptr;
return 1;
}
}
@@ -2685,6 +2726,7 @@ int main(int argc, const char* argv[])
if (! lib_close(handle))
{
print_lib_error(filename);
gPipe = nullptr;
return 1;
}

@@ -2693,6 +2735,7 @@ int main(int argc, const char* argv[])
if (handle == nullptr)
{
print_lib_error(filename);
gPipe = nullptr;
return 1;
}
}


+ 142
- 50
source/frontend/pluginlist/pluginlistdialog.cpp View File

@@ -356,16 +356,16 @@ struct PluginPaths {

if (QDir(winePrefix).exists())
{
vst2 += ":" + winePrefix + "/drive_c/Program Files/VSTPlugins";
vst2 += ":" + winePrefix + "/drive_c/Program Files/Steinberg/VSTPlugins";
vst2 += ":" + winePrefix + "/drive_c/Program Files/VstPlugins";
vst2 += ":" + winePrefix + "/drive_c/Program Files/Steinberg/VstPlugins";
vst3 += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3";
clap += ":" + winePrefix + "/drive_c/Program Files/Common Files/CLAP";

#ifdef CARLA_OS_64BIT
if (QDir(winePrefix + "/drive_c/Program Files (x86)").exists())
{
vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/VSTPlugins";
vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VSTPlugins";
vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins";
vst2 += ":" + winePrefix + "/drive_c/Program Files (x86)/Steinberg/VstPlugins";
vst3 += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3";
clap += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/CLAP";
}
@@ -606,7 +606,7 @@ static PluginFavorite asPluginFavorite(const QByteArray& qdata)
CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(qdata.size()) >= sizeof(PluginFavoriteHeader) + sizeof(char) * 3, {});

// read POD data first
const PluginFavoriteHeader* const data
const PluginFavoriteHeader* const data
= static_cast<const PluginFavoriteHeader*>(static_cast<const void*>(qdata.constData()));
PluginFavorite fav = { data->type, data->uniqueId, {}, {} };

@@ -673,6 +673,7 @@ struct PluginListDialog::PrivateData {
bool hasLoadedLv2Plugins = false;

struct Discovery {
BinaryType btype = BINARY_NATIVE;
PluginType ptype = PLUGIN_NONE;
bool firstInit = true;
bool ignoreCache = false;
@@ -682,11 +683,7 @@ struct PluginListDialog::PrivateData {
CarlaScopedPointer<PluginRefreshDialog> dialog;
Discovery()
{
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-native";
#ifdef CARLA_OS_WIN
tool += ".exe";
#endif
restart();
}

~Discovery()
@@ -694,6 +691,86 @@ struct PluginListDialog::PrivateData {
if (handle != nullptr)
carla_plugin_discovery_stop(handle);
}

bool nextTool()
{
if (handle != nullptr)
{
carla_plugin_discovery_stop(handle);
handle = nullptr;
}

#ifdef CARLA_OS_WIN
#ifdef CARLA_OS_WIN64
// look for win32 plugins on win64
if (btype == BINARY_NATIVE)
{
btype = BINARY_WIN32;
ptype = PLUGIN_INTERNAL;
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-win32.exe";

if (QFile(tool).exists())
return true;
}
#endif

// no other types to try
return false;
#else // CARLA_OS_WIN

#ifndef CARLA_OS_MAC
// try 32bit plugins on 64bit systems, skipping macOS where 32bit is no longer supported
if (btype == BINARY_NATIVE)
{
btype = BINARY_POSIX32;
ptype = PLUGIN_INTERNAL;
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-posix32";

if (QFile(tool).exists())
return true;
}
#endif

// try wine bridges
#ifdef CARLA_OS_64BIT
if (btype == BINARY_NATIVE || btype == BINARY_POSIX32)
{
btype = BINARY_WIN64;
ptype = PLUGIN_INTERNAL;
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-win64.exe";

if (QFile(tool).exists())
return true;
}
#endif

{
btype = BINARY_WIN32;
ptype = PLUGIN_INTERNAL;
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-win32.exe";

if (QFile(tool).exists())
return true;
}

return false;
#endif // CARLA_OS_WIN
}

void restart()
{
btype = BINARY_NATIVE;
ptype = PLUGIN_NONE;
tool = carla_get_library_folder();
tool += CARLA_OS_SEP_STR "carla-discovery-native";
#ifdef CARLA_OS_WIN
tool += ".exe";
#endif
}
} discovery;

PluginPaths paths;
@@ -788,10 +865,11 @@ PluginListDialog::PluginListDialog(QWidget* const parent, const HostSettings& ho
// custom action that listens for Ctrl+F shortcut
addAction(ui.act_focus_search);

#if BINARY_NATIVE == BINARY_POSIX32 || BINARY_NATIVE == BINARY_WIN32
ui.ch_bridged->setText(tr("Bridged (64bit)"));
#else
#ifdef CARLA_OS_64BIT
ui.ch_bridged->setText(tr("Bridged (32bit)"));
#else
ui.ch_bridged->setChecked(false);
ui.ch_bridged->setEnabled(false);
#endif

#if !(defined(CARLA_OS_LINUX) || defined(CARLA_OS_MAC))
@@ -1081,9 +1159,13 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
{
case PLUGIN_NONE:
#ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS
ui.label->setText(tr("Discovering internal plugins..."));
p->discovery.ptype = PLUGIN_INTERNAL;
break;
if (p->discovery.btype == BINARY_NATIVE)
{
ui.label->setText(tr("Discovering internal plugins..."));
p->discovery.ptype = PLUGIN_INTERNAL;
break;
}
[[fallthrough]];
case PLUGIN_INTERNAL:
ui.label->setText(tr("Discovering LADSPA plugins..."));
path = p->paths.ladspa;
@@ -1118,12 +1200,16 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
case PLUGIN_CLAP:
#ifndef CARLA_FRONTEND_ONLY_EMBEDDABLE_PLUGINS
#ifdef CARLA_OS_MAC
ui.label->setText(tr("Discovering AU plugins..."));
p->discovery.ptype = PLUGIN_AU;
break;
if (p->discovery.btype == BINARY_POSIX32 || p->discovery.btype == BINARY_POSIX64)
{
ui.label->setText(tr("Discovering AU plugins..."));
p->discovery.ptype = PLUGIN_AU;
break;
}
[[fallthrough]];
case PLUGIN_AU:
#endif
if (p->paths.jsfx.isNotEmpty())
if (p->discovery.btype == BINARY_NATIVE && p->paths.jsfx.isNotEmpty())
{
ui.label->setText(tr("Discovering JSFX plugins..."));
path = p->paths.jsfx;
@@ -1132,20 +1218,29 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
}
[[fallthrough]];
case PLUGIN_JSFX:
ui.label->setText(tr("Discovering SF2 kits..."));
path = p->paths.sf2;
p->discovery.ptype = PLUGIN_SF2;
break;
if (p->discovery.btype == BINARY_NATIVE && p->paths.sf2.isNotEmpty())
{
ui.label->setText(tr("Discovering SF2 kits..."));
path = p->paths.sf2;
p->discovery.ptype = PLUGIN_SF2;
break;
}
[[fallthrough]];
case PLUGIN_SF2:
ui.label->setText(tr("Discovering SFZ kits..."));
path = p->paths.sfz;
p->discovery.ptype = PLUGIN_SFZ;
break;
if (p->discovery.btype == BINARY_NATIVE && p->paths.sfz.isNotEmpty())
{
ui.label->setText(tr("Discovering SFZ kits..."));
path = p->paths.sfz;
p->discovery.ptype = PLUGIN_SFZ;
break;
}
[[fallthrough]];
case PLUGIN_SFZ:
#endif
default:
// discovery complete
refreshPluginsStop();
if (! p->discovery.nextTool())
refreshPluginsStop();
}

if (p->timerId == 0)
@@ -1155,6 +1250,7 @@ void PluginListDialog::timerEvent(QTimerEvent* const event)
p->discovery.dialog->progressBar->setFormat(ui.label->text());

p->discovery.handle = carla_plugin_discovery_start(p->discovery.tool.toUtf8().constData(),
p->discovery.btype,
p->discovery.ptype,
path.toUtf8().constData(),
discoveryCallback, checkCacheCallback, this);
@@ -1462,17 +1558,19 @@ void PluginListDialog::checkFilters()
const bool hideNonIDisp = ui.ch_inline_display->isChecked();
const bool hideNonStereo = ui.ch_stereo->isChecked();

#if 0
if HAIKU or LINUX or MACOS:
nativeBins = [BINARY_POSIX32, BINARY_POSIX64]
wineBins = [BINARY_WIN32, BINARY_WIN64]
elif WINDOWS:
nativeBins = [BINARY_WIN32, BINARY_WIN64]
wineBins = []
else:
nativeBins = []
wineBins = []
#endif
#if defined(CARLA_OS_WIN64)
static constexpr const BinaryType nativeBins[2] = { BINARY_WIN32, BINARY_WIN64 };
static constexpr const BinaryType wineBins[2] = { BINARY_NONE, BINARY_NONE };
#elif defined(CARLA_OS_WIN32)
static constexpr const BinaryType nativeBins[2] = { BINARY_WIN32, BINARY_NONE };
static constexpr const BinaryType wineBins[2] = { BINARY_NONE, BINARY_NONE };
#elif defined(CARLA_OS_MAC)
static constexpr const BinaryType nativeBins[2] = { BINARY_POSIX64, BINARY_NONE };
static constexpr const BinaryType wineBins[2] = { BINARY_WIN32, BINARY_WIN64 };
#else
static constexpr const BinaryType nativeBins[2] = { BINARY_POSIX32, BINARY_POSIX64 };
static constexpr const BinaryType wineBins[2] = { BINARY_WIN32, BINARY_WIN64 };
#endif

for (int i=0, c=ui.tableWidget->rowCount(); i<c; ++i)
{
@@ -1499,14 +1597,8 @@ void PluginListDialog::checkFilters()
const bool hasCV = cvIns + cvOuts > 0;
const bool hasGui = phints & PLUGIN_HAS_CUSTOM_UI;
const bool hasIDisp = phints & PLUGIN_HAS_INLINE_DISPLAY;

#if 0
const bool isBridged = bool(not isNative and info.build in nativeBins);
const bool isBridgedWine = bool(not isNative and info.build in wineBins);
#else
const bool isBridged = false;
const bool isBridgedWine = false;
#endif
const bool isBridged = !isNative && (nativeBins[0] == info.build || nativeBins[1] == info.build);
const bool isBridgedWine = !isNative && (wineBins[0] == info.build || wineBins[1] == info.build);

const auto hasText = [text, ptext]() {
const QStringList textSplit = text.strip().split(' ');
@@ -1798,7 +1890,7 @@ void PluginListDialog::refreshPluginsStart()
p->plugins.cache.clear();

// start discovery again
p->discovery.ptype = PLUGIN_NONE;
p->discovery.restart();

if (p->timerId == 0)
p->timerId = startTimer(0);
@@ -1806,7 +1898,7 @@ void PluginListDialog::refreshPluginsStart()

void PluginListDialog::refreshPluginsStop()
{
// stop previous discovery if still running
// stop previous discovery if still running
if (p->discovery.handle != nullptr)
{
carla_plugin_discovery_stop(p->discovery.handle);


+ 4
- 0
source/jackbridge/JackBridge.hpp View File

@@ -428,6 +428,10 @@ JACKBRIDGE_API void jackbridge_shm_close(void* shm) noexcept;
JACKBRIDGE_API void* jackbridge_shm_map(void* shm, uint64_t size) noexcept;
JACKBRIDGE_API void jackbridge_shm_unmap(void* shm, void* ptr) noexcept;

JACKBRIDGE_API void* jackbridge_discovery_pipe_create(const char* argv[]);
JACKBRIDGE_API void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value);
JACKBRIDGE_API void jackbridge_discovery_pipe_destroy(void* pipe);

JACKBRIDGE_API void jackbridge_parent_deathsig(bool kill) noexcept;

#endif // JACKBRIDGE_HPP_INCLUDED

+ 70
- 5
source/jackbridge/JackBridge2.cpp View File

@@ -1,6 +1,6 @@
/*
* JackBridge (Part 2, Semaphore + Shared memory and other misc functions)
* Copyright (C) 2013-2019 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -22,9 +22,13 @@
# include "CarlaProcessUtils.hpp"
# include "CarlaSemUtils.hpp"
# include "CarlaShmUtils.hpp"
# include "CarlaTimeUtils.hpp"
# ifdef __WINE__
# include "utils/PipeClient.cpp"
# endif
#endif // ! JACKBRIDGE_DUMMY

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

bool jackbridge_sem_init(void* sem) noexcept
{
@@ -77,7 +81,7 @@ bool jackbridge_sem_timedwait(void* sem, uint msecs, bool server) noexcept
}
#endif

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

bool jackbridge_shm_is_valid(const void* shm) noexcept
{
@@ -137,7 +141,68 @@ void jackbridge_shm_unmap(void* shm, void* ptr) noexcept
#endif
}

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

#if !defined(JACKBRIDGE_DUMMY) && defined(__WINE__)
static void discovery_pipe_callback(void*, const char* const msg) noexcept
{
carla_stdout("discovery msgReceived %s", msg);
}
#endif

void* jackbridge_discovery_pipe_create(const char* argv[])
{
#if defined(JACKBRIDGE_DUMMY) || !defined(__WINE__)
return nullptr;
// unused
(void)argv;
#else
return carla_pipe_client_new(argv, discovery_pipe_callback, nullptr);
#endif
}

void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value)
{
#if defined(JACKBRIDGE_DUMMY) || !defined(__WINE__)
// unused
(void)pipe;
(void)key;
(void)value;
#else
carla_pipe_client_lock(pipe);
carla_pipe_client_write_and_fix_msg(pipe, key);
carla_pipe_client_write_and_fix_msg(pipe, value);
carla_pipe_client_flush_and_unlock(pipe);
#endif
}

void jackbridge_discovery_pipe_destroy(void* pipe)
{
#if defined(JACKBRIDGE_DUMMY) || !defined(__WINE__)
// unused
(void)pipe;
#else
carla_pipe_client_lock(pipe);
carla_pipe_client_write_msg(pipe, "exiting\n");
carla_pipe_client_flush_and_unlock(pipe);

// NOTE: no more messages are handled after this point
// pData->clientClosingDown = true;

for (int i=0; i < 100 && carla_pipe_client_is_running(pipe); ++i)
{
carla_msleep(50);
carla_pipe_client_idle(pipe);
}

if (carla_pipe_client_is_running(pipe))
carla_stderr2("jackbridge_discovery_pipe_destroy: pipe is still running!");

carla_pipe_client_destroy(pipe);
#endif
}

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

void jackbridge_parent_deathsig(bool kill) noexcept
{
@@ -146,4 +211,4 @@ void jackbridge_parent_deathsig(bool kill) noexcept
#endif
}

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

+ 7
- 4
source/jackbridge/JackBridge3.cpp View File

@@ -1,6 +1,6 @@
/*
* JackBridge (Part 3, Export)
* Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -18,7 +18,7 @@

#include "CarlaUtils.hpp"

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

#if defined(CARLA_OS_WIN) && ! defined(__WINE__)
# define JACKBRIDGE_EXPORT extern "C" __declspec (dllexport)
@@ -26,7 +26,7 @@
# define JACKBRIDGE_EXPORT extern "C" __attribute__ ((visibility("default")))
#endif

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

JACKBRIDGE_EXPORT
const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functions();
@@ -140,6 +140,9 @@ const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functi
funcs.shm_close_ptr = jackbridge_shm_close;
funcs.shm_map_ptr = jackbridge_shm_map;
funcs.shm_unmap_ptr = jackbridge_shm_unmap;
funcs.discovery_pipe_create_ptr = jackbridge_discovery_pipe_create;
funcs.discovery_pipe_message_ptr = jackbridge_discovery_pipe_message;
funcs.discovery_pipe_destroy_ptr = jackbridge_discovery_pipe_destroy;
funcs.parent_deathsig_ptr = jackbridge_parent_deathsig;

funcs.unique1 = funcs.unique2 = funcs.unique3 = 0xdeadf00d;
@@ -147,4 +150,4 @@ const JackBridgeExportedFunctions* JACKBRIDGE_API jackbridge_get_exported_functi
return &funcs;
}

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

+ 32
- 10
source/jackbridge/JackBridgeExport.cpp View File

@@ -1,6 +1,6 @@
/*
* JackBridge (Part 3, Export)
* Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -17,8 +17,11 @@
#include "JackBridgeExport.hpp"

#include "CarlaLibUtils.hpp"
#include "CarlaUtils.h"

// -----------------------------------------------------------------------------
// #include <cstdio>

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

class JackBridgeExported
{
@@ -27,11 +30,11 @@ public:
: lib(nullptr),
func(nullptr)
{
#ifdef CARLA_OS_WIN64
#ifdef CARLA_OS_WIN64
lib = lib_open("jackbridge-wine64.dll");
#else
#else
lib = lib_open("jackbridge-wine32.dll");
#endif
#endif
CARLA_SAFE_ASSERT_RETURN(lib != nullptr,);

func = lib_symbol<jackbridge_exported_function_type>(lib, "jackbridge_get_exported_functions");
@@ -59,12 +62,12 @@ public:
static const JackBridgeExported bridge;
CARLA_SAFE_ASSERT_RETURN(bridge.func != nullptr, fallback);

const JackBridgeExportedFunctions* const funcs(bridge.func());
const JackBridgeExportedFunctions* const funcs = bridge.func();
CARLA_SAFE_ASSERT_RETURN(funcs != nullptr, fallback);
CARLA_SAFE_ASSERT_RETURN(funcs->unique1 != 0, fallback);
CARLA_SAFE_ASSERT_RETURN(funcs->unique1 == funcs->unique2, fallback);
CARLA_SAFE_ASSERT_RETURN(funcs->unique2 == funcs->unique3, fallback);
CARLA_SAFE_ASSERT_RETURN(funcs->shm_map_ptr != nullptr, fallback);
CARLA_SAFE_ASSERT_RETURN(funcs->discovery_pipe_destroy_ptr != nullptr, fallback);

return *funcs;
}
@@ -77,7 +80,7 @@ private:
CARLA_DECLARE_NON_COPYABLE(JackBridgeExported);
};

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

static const JackBridgeExportedFunctions& getBridgeInstance() noexcept
{
@@ -85,7 +88,7 @@ static const JackBridgeExportedFunctions& getBridgeInstance() noexcept
return funcs;
}

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

bool jackbridge_is_ok() noexcept
{
@@ -598,9 +601,28 @@ void jackbridge_shm_unmap(void* shm, void* ptr) noexcept
return getBridgeInstance().shm_unmap_ptr(shm, ptr);
}

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

void* jackbridge_discovery_pipe_create(const char* argv[])
{
return getBridgeInstance().discovery_pipe_create_ptr(argv);
}

void jackbridge_discovery_pipe_message(void* pipe, const char* key, const char* value)
{
return getBridgeInstance().discovery_pipe_message_ptr(pipe, key, value);
}

void jackbridge_discovery_pipe_destroy(void* pipe)
{
return getBridgeInstance().discovery_pipe_destroy_ptr(pipe);
}

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

void jackbridge_parent_deathsig(bool kill) noexcept
{
return getBridgeInstance().parent_deathsig_ptr(kill);
}

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

+ 9
- 1
source/jackbridge/JackBridgeExport.hpp View File

@@ -1,6 +1,6 @@
/*
* JackBridge (Part 3, Export)
* Copyright (C) 2013-2015 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -14,6 +14,8 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#pragma once

#include "JackBridge.hpp"

extern "C" {
@@ -123,6 +125,9 @@ typedef void (JACKBRIDGE_API *jackbridgesym_shm_attach)(void*, const char*);
typedef void (JACKBRIDGE_API *jackbridgesym_shm_close)(void*);
typedef void* (JACKBRIDGE_API *jackbridgesym_shm_map)(void*, uint64_t);
typedef void (JACKBRIDGE_API *jackbridgesym_shm_unmap)(void*, void*);
typedef void* (JACKBRIDGE_API *jackbridgesym_discovery_pipe_create)(const char**);
typedef void (JACKBRIDGE_API *jackbridgesym_discovery_pipe_message)(void*, const char*, const char*);
typedef void (JACKBRIDGE_API *jackbridgesym_discovery_pipe_destroy)(void*);
typedef void (JACKBRIDGE_API *jackbridgesym_parent_deathsig)(bool);

// -----------------------------------------------------------------------------
@@ -233,6 +238,9 @@ struct _JackBridgeExportedFunctions {
jackbridgesym_shm_close shm_close_ptr;
jackbridgesym_shm_map shm_map_ptr;
jackbridgesym_shm_unmap shm_unmap_ptr;
jackbridgesym_discovery_pipe_create discovery_pipe_create_ptr;
jackbridgesym_discovery_pipe_message discovery_pipe_message_ptr;
jackbridgesym_discovery_pipe_destroy discovery_pipe_destroy_ptr;
jackbridgesym_parent_deathsig parent_deathsig_ptr;
ulong unique3;
};


+ 7
- 1
source/jackbridge/Makefile View File

@@ -10,7 +10,7 @@ include ../modules/Makefile.mk

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

BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS)
BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS) -I../backend
LINK_FLAGS += $(JACKBRIDGE_LIBS)

ifeq ($(JACKBRIDGE_DIRECT),true)
@@ -18,6 +18,12 @@ BUILD_CXX_FLAGS += $(JACK_FLAGS) -DJACKBRIDGE_DIRECT
LINK_FLAGS += $(JACK_LIBS)
endif

ifneq ($(BUILDING_FOR_WINE),true)
ifeq ($(WINDOWS),true)
BUILD_CXX_FLAGS += -I../modules
endif
endif

WINE_32BIT_FLAGS = $(32BIT_FLAGS) -fpermissive
WINE_64BIT_FLAGS = $(64BIT_FLAGS) -fpermissive
WINE_BUILD_FLAGS = $(filter-out -flto,$(BUILD_CXX_FLAGS))


+ 1
- 1
source/utils/CarlaBinaryUtils.hpp View File

@@ -88,7 +88,7 @@ BinaryType getBinaryTypeFromFile(const char* const filename)
#if defined(HAVE_LIBMAGIC) && ! defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
static const CarlaMagic magic;

const char* const output(magic.getFileDescription(filename));
const char* const output = magic.getFileDescription(filename);

if (output != nullptr && output[0] != '\0')
{


+ 23
- 16
source/utils/CarlaPipeUtils.cpp View File

@@ -35,9 +35,8 @@

#include <fcntl.h>

#include "water/text/String.h"

#ifdef CARLA_OS_WIN
# include "water/text/String.h"
# include <ctime>
#else
# include <cerrno>
@@ -1494,7 +1493,8 @@ uintptr_t CarlaPipeServer::getPID() const noexcept

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

bool CarlaPipeServer::startPipeServer(const char* const filename,
bool CarlaPipeServer::startPipeServer(const char* const helperTool,
const char* const filename,
const char* const arg1,
const char* const arg2,
const int size) noexcept
@@ -1642,31 +1642,30 @@ bool CarlaPipeServer::startPipeServer(const char* const filename,
//-----------------------------------------------------------------------------------------------------------------
// set arguments

const char* argv[8];
const char* argv[9] = {};
int i = 0;

if (helperTool != nullptr)
argv[i++] = helperTool;

//-----------------------------------------------------------------------------------------------------------------
// argv[0] => filename

argv[0] = filename;
argv[i++] = filename;

//-----------------------------------------------------------------------------------------------------------------
// argv[1-2] => args

argv[1] = arg1;
argv[2] = arg2;
argv[i++] = arg1;
argv[i++] = arg2;

//-----------------------------------------------------------------------------------------------------------------
// argv[3-6] => pipes

argv[3] = pipeRecvServerStr;
argv[4] = pipeSendServerStr;
argv[5] = pipeRecvClientStr;
argv[6] = pipeSendClientStr;

//-----------------------------------------------------------------------------------------------------------------
// argv[7] => null

argv[7] = nullptr;
argv[i++] = pipeRecvServerStr;
argv[i++] = pipeSendServerStr;
argv[i++] = pipeRecvClientStr;
argv[i++] = pipeSendClientStr;

//-----------------------------------------------------------------------------------------------------------------
// start process
@@ -1766,6 +1765,14 @@ bool CarlaPipeServer::startPipeServer(const char* const filename,
(void)size; (void)ovRecv; (void)process;
}

bool CarlaPipeServer::startPipeServer(const char* const filename,
const char* const arg1,
const char* const arg2,
const int size) noexcept
{
return startPipeServer(nullptr, filename, arg1, arg2, size);
}

void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcept
{
carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds);


+ 9
- 2
source/utils/CarlaPipeUtils.hpp View File

@@ -285,13 +285,20 @@ public:
* Start the pipe server using @a filename with 2 arguments.
* @see fail()
*/
bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2, const int size = -1) noexcept;
bool startPipeServer(const char* helperTool,
const char* filename, const char* arg1, const char* arg2, int size = -1) noexcept;

/*!
* Start the pipe server using @a filename with 2 arguments.
* @see fail()
*/
bool startPipeServer(const char* filename, const char* arg1, const char* arg2, int size = -1) noexcept;

/*!
* Stop the pipe server.
* This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
*/
void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept;
void stopPipeServer(uint32_t timeOutMilliseconds) noexcept;

/*!
* Close the pipes without waiting for the child process to terminate.


Loading…
Cancel
Save