@@ -457,37 +457,47 @@ typedef enum { | |||||
*/ | */ | ||||
PLUGIN_VST = 5, | PLUGIN_VST = 5, | ||||
/*! | |||||
* VST3 plugin. | |||||
*/ | |||||
PLUGIN_VST3 = 6, | |||||
/*! | /*! | ||||
* AU plugin. | * AU plugin. | ||||
* @note MacOS only | * @note MacOS only | ||||
*/ | */ | ||||
PLUGIN_AU = 6, | |||||
PLUGIN_AU = 7, | |||||
/*! | |||||
* JACK plugin. | |||||
*/ | |||||
PLUGIN_JACK = 8, | |||||
/*! | /*! | ||||
* ReWire plugin. | * ReWire plugin. | ||||
* @note Windows and MacOS only | * @note Windows and MacOS only | ||||
*/ | */ | ||||
PLUGIN_REWIRE = 7, | |||||
PLUGIN_REWIRE = 9, | |||||
/*! | /*! | ||||
* Single CSD file (Csound). | * Single CSD file (Csound). | ||||
*/ | */ | ||||
PLUGIN_FILE_CSD = 8, | |||||
PLUGIN_FILE_CSD = 10, | |||||
/*! | /*! | ||||
* Single GIG file. | * Single GIG file. | ||||
*/ | */ | ||||
PLUGIN_FILE_GIG = 9, | |||||
PLUGIN_FILE_GIG = 11, | |||||
/*! | /*! | ||||
* Single SF2 file (SoundFont). | * Single SF2 file (SoundFont). | ||||
*/ | */ | ||||
PLUGIN_FILE_SF2 = 10, | |||||
PLUGIN_FILE_SF2 = 12, | |||||
/*! | /*! | ||||
* Single SFZ file. | * Single SFZ file. | ||||
*/ | */ | ||||
PLUGIN_FILE_SFZ = 11 | |||||
PLUGIN_FILE_SFZ = 13 | |||||
} PluginType; | } PluginType; | ||||
@@ -839,7 +839,9 @@ public: | |||||
static CarlaPlugin* newDSSI(const Initializer& init); | static CarlaPlugin* newDSSI(const Initializer& init); | ||||
static CarlaPlugin* newLV2(const Initializer& init); | static CarlaPlugin* newLV2(const Initializer& init); | ||||
static CarlaPlugin* newVST(const Initializer& init); | static CarlaPlugin* newVST(const Initializer& init); | ||||
static CarlaPlugin* newVST3(const Initializer& init); | |||||
static CarlaPlugin* newAU(const Initializer& init); | static CarlaPlugin* newAU(const Initializer& init); | ||||
static CarlaPlugin* newJACK(const Initializer& init); | |||||
static CarlaPlugin* newReWire(const Initializer& init); | static CarlaPlugin* newReWire(const Initializer& init); | ||||
static CarlaPlugin* newCsound(const Initializer& init); | static CarlaPlugin* newCsound(const Initializer& init); | ||||
@@ -795,7 +795,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||||
bridgeBinary.clear(); | bridgeBinary.clear(); | ||||
} | } | ||||
if (btype != BINARY_NATIVE || (pData->options.preferPluginBridges && bridgeBinary.isNotEmpty())) | |||||
if (ptype != PLUGIN_INTERNAL && ptype != PLUGIN_JACK && (btype != BINARY_NATIVE || (pData->options.preferPluginBridges && bridgeBinary.isNotEmpty()))) | |||||
{ | { | ||||
if (bridgeBinary.isNotEmpty()) | if (bridgeBinary.isNotEmpty()) | ||||
{ | { | ||||
@@ -891,10 +891,20 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||||
plugin = CarlaPlugin::newVST(initializer); | plugin = CarlaPlugin::newVST(initializer); | ||||
break; | break; | ||||
case PLUGIN_VST3: | |||||
plugin = CarlaPlugin::newVST3(initializer); | |||||
break; | |||||
case PLUGIN_AU: | case PLUGIN_AU: | ||||
plugin = CarlaPlugin::newAU(initializer); | plugin = CarlaPlugin::newAU(initializer); | ||||
break; | break; | ||||
case PLUGIN_JACK: | |||||
#ifndef BUILD_BRIDGE | |||||
plugin = CarlaPlugin::newJACK(initializer); | |||||
#endif | |||||
break; | |||||
case PLUGIN_REWIRE: | case PLUGIN_REWIRE: | ||||
plugin = CarlaPlugin::newReWire(initializer); | plugin = CarlaPlugin::newReWire(initializer); | ||||
break; | break; | ||||
@@ -1661,7 +1661,9 @@ public: | |||||
pData->name = pData->engine->getUniquePluginName(name); | pData->name = pData->engine->getUniquePluginName(name); | ||||
pData->filename = carla_strdup(filename); | pData->filename = carla_strdup(filename); | ||||
fBridgeBinary = bridgeBinary; | |||||
if (bridgeBinary != nullptr) | |||||
fBridgeBinary = bridgeBinary; | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// SHM Audio Pool | // SHM Audio Pool | ||||
@@ -1917,6 +1919,35 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P | |||||
#endif | #endif | ||||
} | } | ||||
CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init) | |||||
{ | |||||
carla_debug("CarlaPlugin::newJACK({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label); | |||||
#ifndef BUILD_BRIDGE | |||||
BridgePlugin* const plugin(new BridgePlugin(init.engine, init.id, BINARY_NATIVE, PLUGIN_JACK)); | |||||
if (! plugin->init(init.filename, init.name, init.label, nullptr)) | |||||
{ | |||||
delete plugin; | |||||
return nullptr; | |||||
} | |||||
plugin->reload(); | |||||
if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) | |||||
{ | |||||
init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!"); | |||||
delete plugin; | |||||
return nullptr; | |||||
} | |||||
return plugin; | |||||
#else | |||||
init.engine->setLastError("JACK app bridge support not available"); | |||||
return nullptr; | |||||
#endif | |||||
} | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
// ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
// Bridge Helper | // Bridge Helper | ||||
@@ -126,6 +126,35 @@ void CarlaPluginThread::run() | |||||
name = "(none)"; | name = "(none)"; | ||||
QStringList arguments; | QStringList arguments; | ||||
QProcessEnvironment env(QProcessEnvironment::systemEnvironment()); | |||||
const EngineOptions& options(fEngine->getOptions()); | |||||
char strBuf[STR_MAX+1]; | |||||
env.insert("ENGINE_OPTION_UIS_ALWAYS_ON_TOP", options.uisAlwaysOnTop ? "true" : "false"); | |||||
if (options.maxParameters != 0) | |||||
{ | |||||
std::sprintf(strBuf, "%u", options.maxParameters); | |||||
env.insert("ENGINE_OPTION_MAX_PARAMETERS", strBuf); | |||||
} | |||||
if (options.uiBridgesTimeout != 0) | |||||
{ | |||||
std::sprintf(strBuf, "%u", options.uiBridgesTimeout); | |||||
env.insert("ENGINE_OPTION_UI_BRIDGES_TIMEOUT", strBuf); | |||||
} | |||||
if (options.frontendWinId != 0) | |||||
{ | |||||
std::sprintf(strBuf, P_INTPTR, options.frontendWinId); | |||||
env.insert("ENGINE_OPTION_FRONTEND_WIN_ID", strBuf); | |||||
} | |||||
if (options.binaryDir != nullptr) | |||||
env.insert("ENGINE_OPTION_PATH_BINARIES", options.binaryDir); | |||||
if (options.resourceDir != nullptr) | |||||
env.insert("ENGINE_OPTION_PATH_RESOURCES", options.resourceDir); | |||||
switch (fMode) | switch (fMode) | ||||
{ | { | ||||
@@ -153,15 +182,25 @@ void CarlaPluginThread::run() | |||||
break; | break; | ||||
case PLUGIN_THREAD_BRIDGE: | case PLUGIN_THREAD_BRIDGE: | ||||
/* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathUDP()).arg(fPlugin->getId()); | |||||
/* stype */ arguments << (const char*)fExtra1; | |||||
/* filename */ arguments << fPlugin->getFilename(); | |||||
/* name */ arguments << name; | |||||
/* label */ arguments << (const char*)fLabel; | |||||
/* SHM ids */ arguments << (const char*)fExtra2; | |||||
env.insert("ENGINE_BRIDGE_SHM_IDS", fExtra2.getBuffer()); | |||||
if (fPlugin->getType() != PLUGIN_JACK) | |||||
{ | |||||
/* osc-url */ arguments << QString("%1/%2").arg(fEngine->getOscServerPathUDP()).arg(fPlugin->getId()); | |||||
/* stype */ arguments << (const char*)fExtra1; | |||||
/* filename */ arguments << fPlugin->getFilename(); | |||||
/* name */ arguments << name; | |||||
/* label */ arguments << (const char*)fLabel; | |||||
} | |||||
else | |||||
{ | |||||
/* filename */ arguments << fPlugin->getFilename(); | |||||
} | |||||
break; | break; | ||||
} | } | ||||
fProcess->setProcessEnvironment(env); | |||||
fProcess->start((const char*)fBinary, arguments); | fProcess->start((const char*)fBinary, arguments); | ||||
fProcess->waitForStarted(); | fProcess->waitForStarted(); | ||||
@@ -26,6 +26,7 @@ OBJS = \ | |||||
DssiPlugin.cpp.o \ | DssiPlugin.cpp.o \ | ||||
Lv2Plugin.cpp.o \ | Lv2Plugin.cpp.o \ | ||||
VstPlugin.cpp.o \ | VstPlugin.cpp.o \ | ||||
Vst3Plugin.cpp.o \ | |||||
AuPlugin.cpp.o \ | AuPlugin.cpp.o \ | ||||
ReWirePlugin.cpp.o \ | ReWirePlugin.cpp.o \ | ||||
CsoundPlugin.cpp.o \ | CsoundPlugin.cpp.o \ | ||||
@@ -85,6 +86,9 @@ Lv2Plugin.cpp.o: Lv2Plugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) | |||||
VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) | VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CARLA_PLUGIN_UI_HPP) | ||||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ | ||||
Vst3Plugin.cpp.o: Vst3Plugin.cpp $(CARLA_PLUGIN_HPP) $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) | |||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||||
AuPlugin.cpp.o: AuPlugin.cpp $(CARLA_PLUGIN_HPP) $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) | AuPlugin.cpp.o: AuPlugin.cpp $(CARLA_PLUGIN_HPP) $(CARLA_ENGINE_HPP) $(CARLA_UTILS_HPP) | ||||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | ||||
@@ -583,7 +583,9 @@ int main(int argc, char* argv[]) | |||||
// --------------------------------------------------------------------- | // --------------------------------------------------------------------- | ||||
// Setup args | // Setup args | ||||
const bool useBridge = (argc == 7); | |||||
const char* const shmIds(std::getenv("ENGINE_BRIDGE_SHM_IDS")); | |||||
const bool useBridge = (shmIds != nullptr); | |||||
const bool useOsc = (std::strcmp(oscUrl, "null") != 0 && std::strcmp(oscUrl, "(null)") != 0 && std::strcmp(oscUrl, "NULL") != 0); | const bool useOsc = (std::strcmp(oscUrl, "null") != 0 && std::strcmp(oscUrl, "(null)") != 0 && std::strcmp(oscUrl, "NULL") != 0); | ||||
if (std::strcmp(name, "(none)") == 0) | if (std::strcmp(name, "(none)") == 0) | ||||
@@ -597,9 +599,9 @@ int main(int argc, char* argv[]) | |||||
if (useBridge) | if (useBridge) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(std::strlen(argv[6]) == 6*2, 1); | |||||
std::strncpy(bridgeBaseAudioName, argv[6], 6); | |||||
std::strncpy(bridgeBaseControlName, argv[6]+6, 6); | |||||
CARLA_SAFE_ASSERT_RETURN(std::strlen(shmIds) == 6*2, 1); | |||||
std::strncpy(bridgeBaseAudioName, shmIds, 6); | |||||
std::strncpy(bridgeBaseControlName, shmIds+6, 6); | |||||
bridgeBaseAudioName[6] = '\0'; | bridgeBaseAudioName[6] = '\0'; | ||||
bridgeBaseControlName[6] = '\0'; | bridgeBaseControlName[6] = '\0'; | ||||
} | } | ||||
@@ -416,6 +416,7 @@ OBJS_PLUGIN = \ | |||||
../backend/plugin/DssiPlugin__native.o \ | ../backend/plugin/DssiPlugin__native.o \ | ||||
../backend/plugin/Lv2Plugin__native.o \ | ../backend/plugin/Lv2Plugin__native.o \ | ||||
../backend/plugin/VstPlugin__native.o \ | ../backend/plugin/VstPlugin__native.o \ | ||||
../backend/plugin/Vst3Plugin__native.o \ | |||||
../backend/plugin/AuPlugin__native.o \ | ../backend/plugin/AuPlugin__native.o \ | ||||
../backend/plugin/ReWirePlugin__native.o \ | ../backend/plugin/ReWirePlugin__native.o \ | ||||
../backend/plugin/CsoundPlugin__native.o \ | ../backend/plugin/CsoundPlugin__native.o \ | ||||
@@ -479,6 +480,7 @@ OBJS_NATIVE += \ | |||||
../backend/plugin/DssiPlugin__native.o \ | ../backend/plugin/DssiPlugin__native.o \ | ||||
../backend/plugin/Lv2Plugin__native.o \ | ../backend/plugin/Lv2Plugin__native.o \ | ||||
../backend/plugin/VstPlugin__native.o \ | ../backend/plugin/VstPlugin__native.o \ | ||||
../backend/plugin/Vst3Plugin__native.o \ | |||||
../backend/plugin/AuPlugin__native.o \ | ../backend/plugin/AuPlugin__native.o \ | ||||
../backend/plugin/ReWirePlugin__native.o \ | ../backend/plugin/ReWirePlugin__native.o \ | ||||
../backend/plugin/CsoundPlugin__native.o \ | ../backend/plugin/CsoundPlugin__native.o \ | ||||
@@ -347,25 +347,31 @@ PLUGIN_LV2 = 4 | |||||
# VST plugin. | # VST plugin. | ||||
PLUGIN_VST = 5 | PLUGIN_VST = 5 | ||||
# VST3 plugin. | |||||
PLUGIN_VST3 = 6 | |||||
# AU plugin. | # AU plugin. | ||||
# @note MacOS only | # @note MacOS only | ||||
PLUGIN_AU = 6 | |||||
PLUGIN_AU = 7 | |||||
# JACK plugin. | |||||
PLUGIN_JACK = 8 | |||||
# ReWire plugin. | # ReWire plugin. | ||||
# @note Windows and MacOS only | # @note Windows and MacOS only | ||||
PLUGIN_REWIRE = 7 | |||||
PLUGIN_REWIRE = 9 | |||||
# Single CSD file (Csound). | # Single CSD file (Csound). | ||||
PLUGIN_FILE_CSD = 8 | |||||
PLUGIN_FILE_CSD = 10 | |||||
# Single GIG file. | # Single GIG file. | ||||
PLUGIN_FILE_GIG = 9 | |||||
PLUGIN_FILE_GIG = 11 | |||||
# Single SF2 file (SoundFont). | # Single SF2 file (SoundFont). | ||||
PLUGIN_FILE_SF2 = 10 | |||||
PLUGIN_FILE_SF2 = 12 | |||||
# Single SFZ file. | # Single SFZ file. | ||||
PLUGIN_FILE_SFZ = 11 | |||||
PLUGIN_FILE_SFZ = 13 | |||||
# ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
# Plugin Category | # Plugin Category | ||||
@@ -97,8 +97,12 @@ const char* PluginType2Str(const PluginType type) noexcept | |||||
return "PLUGIN_LV2"; | return "PLUGIN_LV2"; | ||||
case PLUGIN_VST: | case PLUGIN_VST: | ||||
return "PLUGIN_VST"; | return "PLUGIN_VST"; | ||||
case PLUGIN_VST3: | |||||
return "PLUGIN_VST3"; | |||||
case PLUGIN_AU: | case PLUGIN_AU: | ||||
return "PLUGIN_AU"; | return "PLUGIN_AU"; | ||||
case PLUGIN_JACK: | |||||
return "PLUGIN_JACK"; | |||||
case PLUGIN_REWIRE: | case PLUGIN_REWIRE: | ||||
return "PLUGIN_REWIRE"; | return "PLUGIN_REWIRE"; | ||||
case PLUGIN_FILE_CSD: | case PLUGIN_FILE_CSD: | ||||
@@ -402,8 +406,12 @@ const char* getPluginTypeAsString(const PluginType type) noexcept | |||||
return "LV2"; | return "LV2"; | ||||
case PLUGIN_VST: | case PLUGIN_VST: | ||||
return "VST"; | return "VST"; | ||||
case PLUGIN_VST3: | |||||
return "VST3"; | |||||
case PLUGIN_AU: | case PLUGIN_AU: | ||||
return "AU"; | return "AU"; | ||||
case PLUGIN_JACK: | |||||
return "JACK"; | |||||
case PLUGIN_REWIRE: | case PLUGIN_REWIRE: | ||||
return "ReWire"; | return "ReWire"; | ||||
case PLUGIN_FILE_CSD: | case PLUGIN_FILE_CSD: | ||||
@@ -441,8 +449,12 @@ PluginType getPluginTypeFromString(const char* const ctype) | |||||
return PLUGIN_LV2; | return PLUGIN_LV2; | ||||
if (stype == "vst") | if (stype == "vst") | ||||
return PLUGIN_VST; | return PLUGIN_VST; | ||||
if (stype == "vst3") | |||||
return PLUGIN_VST3; | |||||
if (stype == "au") | if (stype == "au") | ||||
return PLUGIN_AU; | return PLUGIN_AU; | ||||
if (stype == "jack") | |||||
return PLUGIN_JACK; | |||||
if (stype == "rewire") | if (stype == "rewire") | ||||
return PLUGIN_REWIRE; | return PLUGIN_REWIRE; | ||||
if (stype == "csd") | if (stype == "csd") | ||||
@@ -440,11 +440,19 @@ void fillXmlStringFromSaveState(QString& content, const SaveState& saveState) | |||||
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | ||||
info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | ||||
break; | break; | ||||
case PLUGIN_VST3: | |||||
// TODO? | |||||
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | |||||
info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | |||||
break; | |||||
case PLUGIN_AU: | case PLUGIN_AU: | ||||
// TODO? | // TODO? | ||||
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | ||||
info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | info += QString(" <UniqueID>%1</UniqueID>\n").arg(saveState.uniqueID); | ||||
break; | break; | ||||
case PLUGIN_JACK: | |||||
info += QString(" <Binary>%1</Binary>\n").arg(xmlSafeString(saveState.binary, true)); | |||||
break; | |||||
case PLUGIN_REWIRE: | case PLUGIN_REWIRE: | ||||
info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true)); | info += QString(" <Label>%1</Label>\n").arg(xmlSafeString(saveState.label, true)); | ||||
break; | break; | ||||