Browse Source

Several fixes for discovery; misc changes

tags/1.9.4
falkTX 11 years ago
parent
commit
0af1201dfb
13 changed files with 245 additions and 201 deletions
  1. +3
    -1
      source/Makefile.mk
  2. +2
    -1
      source/backend/CarlaBackend.hpp
  3. +2
    -0
      source/backend/engine/CarlaEngineJack.cpp
  4. +1
    -1
      source/bridges/Makefile
  5. +2
    -1
      source/carla_backend.py
  6. +33
    -37
      source/carla_database.py
  7. +22
    -18
      source/carla_shared.py
  8. +11
    -8
      source/discovery/Makefile
  9. +155
    -130
      source/discovery/carla-discovery.cpp
  10. +4
    -0
      source/includes/CarlaDefines.hpp
  11. +3
    -3
      source/modules/jackbridge/JackBridge.hpp
  12. +5
    -1
      source/modules/jackbridge/JackBridge1.cpp
  13. +2
    -0
      source/utils/CarlaVstUtils.hpp

+ 3
- 1
source/Makefile.mk View File

@@ -17,7 +17,7 @@ CARLA_CSOUND_SUPPORT = true
CARLA_SAMPLERS_SUPPORT = true

# Use the free vestige header instead of the official VST SDK
CARLA_VESTIGE_HEADER = true
# CARLA_VESTIGE_HEADER = true

# --------------------------------------------------------------
# DO NOT MODIFY PAST THIS POINT!
@@ -142,6 +142,7 @@ ifeq ($(HAVE_OPENGL),true)
DGL_FLAGS = $(shell pkg-config --cflags gl x11)
DGL_LIBS = $(shell pkg-config --libs gl x11)
endif
LILV_LIBS = -lrt -ldl
JUCE_CORE_LIBS = -lrt -ldl -lpthread
JUCE_EVENTS_FLAGS = $(shell pkg-config --cflags x11)
JUCE_EVENTS_LIBS = $(shell pkg-config --libs x11)
@@ -153,6 +154,7 @@ endif

ifeq ($(MACOS),true)
DGL_LIBS = -framework OpenGL -framework Cocoa
LILV_LIBS = -ldl
JUCE_AUDIO_BASICS_LIBS = -framework Accelerate
JUCE_AUDIO_DEVICES_LIBS = -framework CoreAudio -framework CoreMIDI -framework DiscRecording
JUCE_AUDIO_FORMATS_LIBS = -framework CoreAudio -framework CoreMIDI -framework QuartzCore -framework AudioToolbox


+ 2
- 1
source/backend/CarlaBackend.hpp View File

@@ -58,7 +58,8 @@ const unsigned int MAX_DEFAULT_PARAMETERS = 200; //!< Maximum default number of
*/
const unsigned int PLUGIN_IS_BRIDGE = 0x001; //!< Plugin is a bridge. This hint is required because "bridge" itself is not a plugin type.
const unsigned int PLUGIN_IS_RTSAFE = 0x002; //!< Plugin is hard real-time safe.
const unsigned int PLUGIN_HAS_GUI = 0x004; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_IS_SYNTH = 0x004; //!< Plugin is hard real-time safe.
const unsigned int PLUGIN_HAS_GUI = 0x008; //!< Plugin has its own custom GUI.
const unsigned int PLUGIN_CAN_DRYWET = 0x010; //!< Plugin can use internal Dry/Wet control.
const unsigned int PLUGIN_CAN_VOLUME = 0x020; //!< Plugin can use internal Volume control.
const unsigned int PLUGIN_CAN_BALANCE = 0x040; //!< Plugin can use internal Left & Right Balance controls.


+ 2
- 0
source/backend/engine/CarlaEngineJack.cpp View File

@@ -19,6 +19,8 @@
#include "CarlaBackendUtils.hpp"
#include "CarlaMIDI.h"

#define JACKBRIDGE_DIRECT 1

#ifdef JACKBRIDGE_EXPORT
# include "jackbridge/JackBridge.hpp"
#else


+ 1
- 1
source/bridges/Makefile View File

@@ -39,7 +39,7 @@ endif
POSIX_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS)
POSIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu
POSIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu
POSIX_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) -ldl
POSIX_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) -ldl -ljack

ifneq ($(MACOS),true)
POSIX_LINK_FLAGS += -lrt


+ 2
- 1
source/carla_backend.py View File

@@ -95,7 +95,8 @@ MAX_DEFAULT_PARAMETERS = 200
# Plugin Hints
PLUGIN_IS_BRIDGE = 0x001
PLUGIN_IS_RTSAFE = 0x002
PLUGIN_HAS_GUI = 0x004
PLUGIN_IS_SYNTH = 0x004
PLUGIN_HAS_GUI = 0x008
PLUGIN_CAN_DRYWET = 0x010
PLUGIN_CAN_VOLUME = 0x020
PLUGIN_CAN_BALANCE = 0x040


+ 33
- 37
source/carla_database.py View File

@@ -123,7 +123,6 @@ PyPluginInfo = {
'API': PLUGIN_QUERY_API_VERSION,
'build': BINARY_NONE,
'type': PLUGIN_NONE,
'category': PLUGIN_CATEGORY_NONE,
'hints': 0x0,
'binary': "",
'name': "",
@@ -143,8 +142,8 @@ PyPluginInfo = {
'programs.total': 0
}

global discoveryProcess
discoveryProcess = None
global gDiscoveryProcess
gDiscoveryProcess = None

def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
if not os.path.exists(tool):
@@ -163,21 +162,29 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
command.append(stype)
command.append(filename)

global discoveryProcess
discoveryProcess = Popen(command, stdout=PIPE)

try:
discoveryProcess.wait()
output = discoveryProcess.stdout.read().decode("utf-8", errors="ignore").split("\n")
except:
output = ()
global gDiscoveryProcess
gDiscoveryProcess = Popen(command, stdout=PIPE)

pinfo = None
plugins = []
fakeLabel = os.path.basename(filename).rsplit(".", 1)[0]

for line in output:
line = line.strip()
#try:
#gDiscoveryProcess.wait()
#output = gDiscoveryProcess.stdout.read().decode("utf-8", errors="ignore").split("\n")
#except:
#output = ()

#for line in output:

while gDiscoveryProcess.poll() is None:
try:
line = gDiscoveryProcess.stdout.readline().decode("utf-8", errors="ignore").strip()
except:
break

#line = line.strip()

if line == "carla-discovery::init::-----------":
pinfo = deepcopy(PyPluginInfo)
pinfo['type'] = itype
@@ -222,8 +229,6 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
if value.isdigit(): pinfo['uniqueId'] = int(value)
elif prop == "hints":
if value.isdigit(): pinfo['hints'] = int(value)
elif prop == "category":
if value.isdigit(): pinfo['category'] = int(value)
elif prop == "audio.ins":
if value.isdigit(): pinfo['audio.ins'] = int(value)
elif prop == "audio.outs":
@@ -255,17 +260,17 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False):
continue

# FIXME?
tmp = discoveryProcess
discoveryProcess = None
del discoveryProcess, tmp
tmp = gDiscoveryProcess
gDiscoveryProcess = None
del gDiscoveryProcess, tmp

return plugins

def killDiscovery():
global discoveryProcess
global gDiscoveryProcess

if discoveryProcess is not None:
discoveryProcess.kill()
if gDiscoveryProcess is not None:
gDiscoveryProcess.kill()

def checkPluginInternal(desc):
plugins = []
@@ -273,7 +278,6 @@ def checkPluginInternal(desc):
pinfo = deepcopy(PyPluginInfo)
pinfo['build'] = BINARY_NATIVE
pinfo['type'] = PLUGIN_INTERNAL
pinfo['category'] = int(desc['category'])
pinfo['hints'] = int(desc['hints'])
pinfo['name'] = cString(desc['name'])
pinfo['label'] = cString(desc['label'])
@@ -1304,8 +1308,7 @@ class PluginDatabaseW(QDialog):
mIns = plugin['midi.ins']
mOuts = plugin['midi.outs']
ptype = self.ui.tableWidget.item(i, 12).text()
#isSynth = bool(plugin['hints'] & PLUGIN_IS_SYNTH)
isSynth = bool(plugin['category'] == PLUGIN_CATEGORY_SYNTH)
isSynth = bool(plugin['hints'] & PLUGIN_IS_SYNTH)
isEffect = bool(aIns > 0 < aOuts and not isSynth)
isMidi = bool(aIns == 0 and aOuts == 0 and mIns > 0 < mOuts)
isKit = bool(ptype in ("GIG", "SF2", "SFZ"))
@@ -1408,7 +1411,7 @@ class PluginDatabaseW(QDialog):
self.ui.tableWidget.setItem(index, 7, QTableWidgetItem(str(plugin['parameters.outs'])))
self.ui.tableWidget.setItem(index, 8, QTableWidgetItem(str(plugin['programs.total'])))
self.ui.tableWidget.setItem(index, 9, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_HAS_GUI) else self.tr("No")))
self.ui.tableWidget.setItem(index, 10, QTableWidgetItem(self.tr("Yes") if (plugin['category'] == PLUGIN_CATEGORY_SYNTH) else self.tr("No")))
self.ui.tableWidget.setItem(index, 10, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_IS_SYNTH) else self.tr("No")))
self.ui.tableWidget.setItem(index, 11, QTableWidgetItem(bridgeText))
self.ui.tableWidget.setItem(index, 12, QTableWidgetItem(ptype))
self.ui.tableWidget.setItem(index, 13, QTableWidgetItem(str(plugin['binary'])))
@@ -1669,18 +1672,11 @@ class PluginDatabaseW(QDialog):
# Main

if __name__ == '__main__':
try:
from PyQt5.QtWidgets import QApplication
except:
from PyQt4.QtGui import QApplication

app = QApplication(sys.argv)
app.setApplicationName("Carla")
app.setApplicationVersion(VERSION)
app.setOrganizationName("falkTX")
app.setWindowIcon(QIcon(":/scalable/carla.svg"))

initHost(False)
from carla_style import *

app = CarlaApplication()

initHost("Settings", None, False)

gui = PluginDatabaseW(None)
gui.show()


+ 22
- 18
source/carla_shared.py View File

@@ -464,9 +464,9 @@ def initHost(appName, libPrefix = None, failError = True):
libname = "libcarla_"

if Carla.isControl:
libname += "control"
libname += "control2"
else:
libname += "standalone"
libname += "standalone2"

if WINDOWS:
libname += ".dll"
@@ -481,22 +481,26 @@ def initHost(appName, libPrefix = None, failError = True):
else:
if os.path.exists(os.path.join(CWD, "backend", libname)):
libfilename = os.path.join(CWD, "backend", libname)
#else:
#CARLA_LIB_PATH = os.getenv("CARLA_LIB_PATH")

#if CARLA_LIB_PATH and os.path.exists(CARLA_LIB_PATH):
#CARLA_LIB_PATH = os.path.join(CARLA_LIB_PATH, "..")
#elif WINDOWS:
#CARLA_LIB_PATH = (os.path.join(PROGRAMFILES, "Carla"),)
#elif MACOS:
#CARLA_LIB_PATH = ("/opt/local/lib", "/usr/local/lib/", "/usr/lib")
#else:
#CARLA_LIB_PATH = ("/usr/local/lib/", "/usr/lib")

#for path in CARLA_LIB_PATH:
#if os.path.exists(os.path.join(path, "carla", libname)):
#libfilename = os.path.join(path, "carla", libname)
#break
else:
CARLA_LIB_PATH_env = os.getenv("CARLA_LIB_PATH")

if CARLA_LIB_PATH_env and os.path.exists(CARLA_LIB_PATH_env):
CARLA_LIB_PATH = (CARLA_LIB_PATH_env,)
elif WINDOWS:
CARLA_LIB_PATH = (os.path.join(PROGRAMFILES, "Carla"),)
elif MACOS:
CARLA_LIB_PATH = ("/opt/local/lib", "/usr/local/lib/", "/usr/lib")
else:
CARLA_LIB_PATH = ("/usr/local/lib/", "/usr/lib")

del CARLA_LIB_PATH_env

for path in CARLA_LIB_PATH:
if os.path.exists(os.path.join(path, "carla", libname)):
libfilename = os.path.join(path, "carla", libname)
break
else:
libfilename = ""

# -------------------------------------------------------------
# Search for Carla tools


+ 11
- 8
source/discovery/Makefile View File

@@ -30,23 +30,20 @@ ifeq ($(HAVE_LINUXSAMPLER),true)
NATIVE_FLAGS += $(shell pkg-config --cflags --libs linuxsampler) -DWANT_LINUXSAMPLER
endif

LINK_FLAGS += $(JUCE_AUDIO_BASICS_LIBS)
LINK_FLAGS += $(JUCE_CORE_LIBS)

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

POSIX_BUILD_FLAGS = $(BUILD_CXX_FLAGS)
POSIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu
POSIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu
POSIX_LINK_FLAGS = $(LINK_FLAGS) $(EXTRA_LIBS) -ldl -lpthread

ifeq ($(MACOS),true)
POSIX_LINK_FLAGS += -framework Cocoa -framework IOKit
else
POSIX_LINK_FLAGS += -lrt
endif
POSIX_LINK_FLAGS = $(LINK_FLAGS) -ldl

WIN_BUILD_FLAGS = $(BUILD_CXX_FLAGS)
WIN_32BIT_FLAGS = $(32BIT_FLAGS)
WIN_64BIT_FLAGS = $(64BIT_FLAGS)
WIN_LINK_FLAGS = $(LINK_FLAGS) $(EXTRA_LIBS) -lole32 -lshlwapi -lversion -lwininet -lwinmm -lws2_32
WIN_LINK_FLAGS = $(LINK_FLAGS) -lkernel32

LIBS = ../modules/juce_audio_basics.a
LIBS_posix32 = ../modules/juce_audio_basics.posix32.a
@@ -66,6 +63,7 @@ LIBS_posix32 += ../modules/lilv.posix32.a
LIBS_posix64 += ../modules/lilv.posix64.a
LIBS_win32 += ../modules/lilv.win32.a
LIBS_win64 += ../modules/lilv.win64.a
LINK_FLAGS += $(LILV_LIBS)
endif

OBJS = carla-discovery.cpp
@@ -116,6 +114,9 @@ debug:
.FORCE:
.PHONY: .FORCE

../modules/juce_audio_basics.%.a: .FORCE
$(MAKE) -C ../modules juce_audio_basics_$*

../modules/juce_core.%.a: .FORCE
$(MAKE) -C ../modules juce_core_$*

@@ -124,3 +125,5 @@ debug:

../modules/%.a: .FORCE
$(MAKE) -C ../modules $*

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

+ 155
- 130
source/discovery/carla-discovery.cpp View File

@@ -20,6 +20,8 @@
#include "CarlaString.hpp"
#include "CarlaMIDI.h"

#define VST_FORCE_DEPRECATED 0

#ifdef WANT_LADSPA
# include "CarlaLadspaUtils.hpp"
#endif
@@ -50,6 +52,7 @@

#define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl;

using juce::File;
using juce::FloatVectorOperations;

CARLA_BACKEND_USE_NAMESPACE
@@ -75,15 +78,23 @@ void print_lib_error(const char* const filename)
// --------------------------------------------------------------------------
// VST stuff

// Check if plugin is currently processing
bool gVstIsProcessing = false;

// Check if plugin needs idle
bool gVstNeedsIdle = false;

// Check if plugin wants midi
bool gVstWantsMidi = false;

// Check if plugin wants time
bool gVstWantsTime = false;

// Current uniqueId for VST shell plugins
intptr_t gVstCurrentUniqueId = 0;

// todo: add test, time requested without asking feature

// Supported Carla features
intptr_t vstHostCanDo(const char* const feature)
{
@@ -98,7 +109,10 @@ intptr_t vstHostCanDo(const char* const feature)
if (std::strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
return 1;
if (std::strcmp(feature, "sendVstTimeInfo") == 0)
{
gVstWantsTime = true;
return 1;
}
if (std::strcmp(feature, "receiveVstEvents") == 0)
return 1;
if (std::strcmp(feature, "receiveVstMidiEvent") == 0)
@@ -110,7 +124,7 @@ intptr_t vstHostCanDo(const char* const feature)
if (std::strcmp(feature, "acceptIOChanges") == 0)
return 1;
if (std::strcmp(feature, "sizeWindow") == 0)
return -1;
return 1;
if (std::strcmp(feature, "offline") == 0)
return -1;
if (std::strcmp(feature, "openFileSelector") == 0)
@@ -124,6 +138,10 @@ intptr_t vstHostCanDo(const char* const feature)
if (std::strcmp(feature, "shellCategory") == 0)
return -1; // FIXME

// non-official features found in some plugins:
// "asyncProcessing"
// "editFile"

// unimplemented
carla_stderr("vstHostCanDo(\"%s\") - unknown feature", feature);
return 0;
@@ -147,17 +165,22 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
break;

case audioMasterCurrentId:
if (gVstCurrentUniqueId == 0) DISCOVERY_OUT("warning", "plugin asked for uniqueId, but it's currently 0");

ret = gVstCurrentUniqueId;
break;

#if ! VST_FORCE_DEPRECATED
case audioMasterWantMidi:
case DECLARE_VST_DEPRECATED(audioMasterWantMidi):
if (gVstWantsMidi) DISCOVERY_OUT("warning", "plugin requested MIDI more than once");

gVstWantsMidi = true;
ret = 1;
break;
#endif

case audioMasterGetTime:
if (! gVstIsProcessing) DISCOVERY_OUT("warning", "plugin requested timeInfo out of process");
if (! gVstWantsTime) DISCOVERY_OUT("warning", "plugin requested timeInfo but didn't ask if host could do \"sendVstTimeInfo\"");

static VstTimeInfo_R timeInfo;
carla_zeroStruct<VstTimeInfo_R>(timeInfo);
timeInfo.sampleRate = kSampleRate;
@@ -178,22 +201,21 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
#endif
break;

#if ! VST_FORCE_DEPRECATED
case audioMasterTempoAt:
case DECLARE_VST_DEPRECATED(audioMasterTempoAt):
ret = 120 * 10000;
break;

case audioMasterGetNumAutomatableParameters:
case DECLARE_VST_DEPRECATED(audioMasterGetNumAutomatableParameters):
ret = carla_min<intptr_t>(effect->numParams, MAX_DEFAULT_PARAMETERS, 0);
break;

case audioMasterGetParameterQuantization:
case DECLARE_VST_DEPRECATED(audioMasterGetParameterQuantization):
ret = 1; // full single float precision
break;
#endif

case audioMasterNeedIdle:
// Deprecated in VST SDK 2.4
case DECLARE_VST_DEPRECATED(audioMasterNeedIdle):
if (gVstNeedsIdle) DISCOVERY_OUT("warning", "plugin requested idle more than once");

gVstNeedsIdle = true;
ret = 1;
break;
@@ -206,14 +228,12 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
ret = kBufferSize;
break;

#if ! VST_FORCE_DEPRECATED
case audioMasterWillReplaceOrAccumulate:
case DECLARE_VST_DEPRECATED(audioMasterWillReplaceOrAccumulate):
ret = 1; // replace
break;
#endif

case audioMasterGetCurrentProcessLevel:
ret = kVstProcessLevelUser;
ret = gVstIsProcessing ? kVstProcessLevelRealtime : kVstProcessLevelUser;
break;

case audioMasterGetAutomationState:
@@ -221,28 +241,24 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
break;

case audioMasterGetVendorString:
if (ptr != nullptr)
{
std::strcpy((char*)ptr, "falkTX");
ret = 1;
}
CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
std::strcpy((char*)ptr, "falkTX");
ret = 1;
break;

case audioMasterGetProductString:
if (ptr != nullptr)
{
std::strcpy((char*)ptr, "Carla-Discovery");
ret = 1;
}
CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
std::strcpy((char*)ptr, "Carla-Discovery");
ret = 1;
break;

case audioMasterGetVendorVersion:
ret = 0x110; // 1.1.0
ret = CARLA_VERSION_HEX;
break;

case audioMasterCanDo:
if (ptr != nullptr)
ret = vstHostCanDo((const char*)ptr);
CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
ret = vstHostCanDo((const char*)ptr);
break;

case audioMasterGetLanguage:
@@ -327,7 +343,7 @@ public:
}
}

static void outputInfo(LinuxSampler::InstrumentManager::instrument_info_t* const info, const int programs, const char* const basename = nullptr)
static void outputInfo(const LinuxSampler::InstrumentManager::instrument_info_t* const info, const int programs, const char* const basename = nullptr)
{
DISCOVERY_OUT("init", "-----------");

@@ -338,13 +354,13 @@ public:
DISCOVERY_OUT("maker", info->Artists);
DISCOVERY_OUT("copyright", info->Artists);
}
else if (basename != nullptr)
else if (basename != nullptr && basename[0] != '\0')
{
DISCOVERY_OUT("name", basename);
DISCOVERY_OUT("label", basename);
}

DISCOVERY_OUT("category", PLUGIN_CATEGORY_SYNTH);
DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
DISCOVERY_OUT("audio.outs", 2);
DISCOVERY_OUT("audio.total", 2);
DISCOVERY_OUT("midi.ins", 1);
@@ -378,7 +394,6 @@ void do_ladspa_check(void*& libHandle, const char* const filename, const bool in
return;
}

unsigned long i = 0;
const LADSPA_Descriptor* descriptor;

{
@@ -421,6 +436,8 @@ void do_ladspa_check(void*& libHandle, const char* const filename, const bool in
}
}

unsigned long i = 0;

while ((descriptor = descFn(i++)) != nullptr)
{
if (descriptor->instantiate == nullptr)
@@ -443,7 +460,7 @@ void do_ladspa_check(void*& libHandle, const char* const filename, const bool in
DISCOVERY_OUT("warning", "Plugin '" << descriptor->Name << "' is not hard real-time capable");
}

int hints = 0;
int hints = 0x0;
int audioIns = 0;
int audioOuts = 0;
int audioTotal = 0;
@@ -472,7 +489,7 @@ void do_ladspa_check(void*& libHandle, const char* const filename, const bool in
{
if (LADSPA_IS_PORT_INPUT(portDescriptor))
parametersIns += 1;
else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(descriptor->PortNames[j], "latency") && std::strcmp(descriptor->PortNames[j], "_latency"))
else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(descriptor->PortNames[j], "latency") != 0 && std::strcmp(descriptor->PortNames[j], "_latency") != 0)
parametersOuts += 1;

parametersTotal += 1;
@@ -623,7 +640,6 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init
return;
}

unsigned long i = 0;
const DSSI_Descriptor* descriptor;

{
@@ -668,6 +684,8 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init
}
}

unsigned long i = 0;

while ((descriptor = descFn(i++)) != nullptr)
{
const LADSPA_Descriptor* const ldescriptor(descriptor->LADSPA_Plugin);
@@ -702,8 +720,7 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init
DISCOVERY_OUT("warning", "Plugin '" << ldescriptor->Name << "' is not hard real-time capable");
}

bool isSynth = false;
int hints = 0;
int hints = 0x0;
int audioIns = 0;
int audioOuts = 0;
int audioTotal = 0;
@@ -735,18 +752,18 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init
{
if (LADSPA_IS_PORT_INPUT(portDescriptor))
parametersIns += 1;
else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(ldescriptor->PortNames[j], "latency") && std::strcmp(ldescriptor->PortNames[j], "_latency"))
else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(ldescriptor->PortNames[j], "latency") != 0 && std::strcmp(ldescriptor->PortNames[j], "_latency") != 0)
parametersOuts += 1;

parametersTotal += 1;
}
}

if (descriptor->run_synth || descriptor->run_multiple_synths)
if (descriptor->run_synth != nullptr || descriptor->run_multiple_synths != nullptr)
midiIns = midiTotal = 1;

if (midiIns > 0 && audioIns == 0 && audioOuts > 0)
isSynth = true;
hints |= PLUGIN_IS_SYNTH;

if (const char* const ui = find_dssi_ui(filename, ldescriptor->Label))
{
@@ -905,12 +922,8 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init
DISCOVERY_OUT("label", ldescriptor->Label);
DISCOVERY_OUT("maker", ldescriptor->Maker);
DISCOVERY_OUT("copyright", ldescriptor->Copyright);
DISCOVERY_OUT("unique_id", ldescriptor->UniqueID);
DISCOVERY_OUT("uniqueId", ldescriptor->UniqueID);
DISCOVERY_OUT("hints", hints);

if (isSynth)
DISCOVERY_OUT("category", PLUGIN_CATEGORY_SYNTH);

DISCOVERY_OUT("audio.ins", audioIns);
DISCOVERY_OUT("audio.outs", audioOuts);
DISCOVERY_OUT("audio.total", audioTotal);
@@ -1124,8 +1137,8 @@ void do_lv2_check(const char* const bundle, const bool init)
}
}

// if (rdfDescriptor->Type[1] & LV2_PLUGIN_INSTRUMENT)
// hints |= PLUGIN_IS_SYNTH;
if (rdfDescriptor->Type[1] & LV2_PLUGIN_INSTRUMENT)
hints |= PLUGIN_IS_SYNTH;

if (rdfDescriptor->UICount > 0)
hints |= PLUGIN_HAS_GUI;
@@ -1138,7 +1151,7 @@ void do_lv2_check(const char* const bundle, const bool init)
DISCOVERY_OUT("maker", rdfDescriptor->Author);
if (rdfDescriptor->License != nullptr)
DISCOVERY_OUT("copyright", rdfDescriptor->License);
DISCOVERY_OUT("unique_id", rdfDescriptor->UniqueID);
DISCOVERY_OUT("uniqueId", rdfDescriptor->UniqueID);
DISCOVERY_OUT("hints", hints);
DISCOVERY_OUT("audio.ins", audioIns);
DISCOVERY_OUT("audio.outs", audioOuts);
@@ -1189,54 +1202,64 @@ void do_vst_check(void*& libHandle, const bool init)
return;
}

char strBuf[STR_MAX+1] = { '\0' };
if (effect->uniqueID == 0)
{
DISCOVERY_OUT("error", "Plugin doesn't have an Unique ID");
effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
return;
}

gVstCurrentUniqueId = effect->uniqueID;

effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdentify), 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effSetBlockSizeAndSampleRate), 0, kBufferSize, nullptr, kSampleRate);
effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, kSampleRate);
effect->dispatcher(effect, effSetBlockSize, 0, kBufferSize, nullptr, 0.0f);
effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);

effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, effSetProgram, 0, 0, nullptr, 0.0f);

char strBuf[STR_MAX+1];
CarlaString cName;
CarlaString cProduct;
CarlaString cVendor;

effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);

#if 0 // FIXME
const intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f);

//for (int32_t i = effect->numInputs; --i >= 0;) effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effConnectInput), i, 1, 0, 0);
//for (int32_t i = effect->numOutputs; --i >= 0;) effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effConnectOutput), i, 1, 0, 0);

carla_zeroChar(strBuf, STR_MAX+1);

if (effect->dispatcher(effect, effGetVendorString, 0, 0, strBuf, 0.0f) == 1)
cVendor = strBuf;

carla_zeroChar(strBuf, STR_MAX+1);

if (vstCategory == kPlugCategShell)
{
if ((gVstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0)
cName = strBuf;
gVstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f);

CARLA_SAFE_ASSERT_RETURN(gVstCurrentUniqueId != 0,);
cName = strBuf;
}
else
#endif
{
gVstCurrentUniqueId = effect->uniqueID;

if (gVstCurrentUniqueId != 0 && effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f) == 1)
if (effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f) == 1)
cName = strBuf;
}

if (gVstCurrentUniqueId == 0)
for (;;)
{
DISCOVERY_OUT("error", "Plugin doesn't have an Unique ID");
effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
return;
}

carla_fill<char>(strBuf, STR_MAX+1, '\0');

if (effect->dispatcher(effect, effGetVendorString, 0, 0, strBuf, 0.0f) == 1)
cVendor = strBuf;

while (gVstCurrentUniqueId != 0)
{
carla_fill<char>(strBuf, STR_MAX+1, '\0');
carla_zeroChar(strBuf, STR_MAX+1);

if (effect->dispatcher(effect, effGetProductString, 0, 0, strBuf, 0.0f) == 1)
cProduct = strBuf;
else
cProduct.clear();

gVstWantsMidi = false;

int hints = 0;
int hints = 0x0;
int audioIns = effect->numInputs;
int audioOuts = effect->numOutputs;
int audioTotal = audioIns + audioOuts;
@@ -1250,8 +1273,8 @@ void do_vst_check(void*& libHandle, const bool init)
if (effect->flags & effFlagsHasEditor)
hints |= PLUGIN_HAS_GUI;

// if (effect->flags & effFlagsIsSynth)
// hints |= PLUGIN_IS_SYNTH;
if (effect->flags & effFlagsIsSynth)
hints |= PLUGIN_IS_SYNTH;

if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || (effect->flags & effFlagsIsSynth) > 0)
midiIns = 1;
@@ -1267,20 +1290,13 @@ void do_vst_check(void*& libHandle, const bool init)
if (init)
{
if (gVstNeedsIdle)
effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);

#if ! VST_FORCE_DEPRECATED
effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, kBufferSize, nullptr, kSampleRate);
#endif
effect->dispatcher(effect, effSetBlockSize, 0, kBufferSize, nullptr, 0.0f);
effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, kSampleRate);
effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);

effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);

if (gVstNeedsIdle)
effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);

// Plugin might call wantMidi() during resume
if (midiIns == 0 && gVstWantsMidi)
@@ -1310,15 +1326,10 @@ void do_vst_check(void*& libHandle, const bool init)

VstEventsFixed()
: numEvents(0),
#ifdef CARLA_PROPER_CPP11_SUPPORT
reserved(0),
data{0} {}
#else
reserved(0)
{
data[0] = data[1] = nullptr;
}
#endif
} events;

VstMidiEvent midiEvents[2];
@@ -1337,41 +1348,29 @@ void do_vst_check(void*& libHandle, const bool init)
midiEvents[1].deltaFrames = kBufferSize/2;

events.numEvents = 2;
events.reserved = 0;
events.data[0] = (VstEvent*)&midiEvents[0];
events.data[1] = (VstEvent*)&midiEvents[1];

// processing
{
if (midiIns > 0)
effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);

#if ! VST_FORCE_DEPRECATED
if ((effect->flags & effFlagsCanReplacing) > 0 && effect->processReplacing != nullptr && effect->processReplacing != effect->process)
effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
else if (effect->process != nullptr)
effect->process(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
else
DISCOVERY_OUT("error", "Plugin doesn't have a process function");
#else
CARLA_ASSERT(effect->flags & effFlagsCanReplacing);
if (effect->flags & effFlagsCanReplacing)
{
if (effect->processReplacing != nullptr)
effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, bufferSize);
else
DISCOVERY_OUT("error", "Plugin doesn't have a process function");
}
else
DISCOVERY_OUT("error", "Plugin doesn't have can't do process replacing");
#endif
}
gVstIsProcessing = true;

if (midiIns > 0)
effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);

if ((effect->flags & effFlagsCanReplacing) > 0 && effect->processReplacing != nullptr && effect->processReplacing != effect->DECLARE_VST_DEPRECATED(process))
effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
else if (effect->DECLARE_VST_DEPRECATED(process) != nullptr)
effect->DECLARE_VST_DEPRECATED(process)(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
else
DISCOVERY_OUT("error", "Plugin doesn't have a process function");

gVstIsProcessing = false;

effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);

if (gVstNeedsIdle)
effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);

for (int j=0; j < audioIns; ++j)
delete[] bufferAudioIn[j];
@@ -1387,7 +1386,7 @@ void do_vst_check(void*& libHandle, const bool init)
DISCOVERY_OUT("label", (const char*)cProduct);
DISCOVERY_OUT("maker", (const char*)cVendor);
DISCOVERY_OUT("copyright", (const char*)cVendor);
DISCOVERY_OUT("unique_id", gVstCurrentUniqueId);
DISCOVERY_OUT("uniqueId", gVstCurrentUniqueId);
DISCOVERY_OUT("hints", hints);
DISCOVERY_OUT("audio.ins", audioIns);
DISCOVERY_OUT("audio.outs", audioOuts);
@@ -1401,23 +1400,27 @@ void do_vst_check(void*& libHandle, const bool init)
DISCOVERY_OUT("build", BINARY_NATIVE);
DISCOVERY_OUT("end", "------------");

#if 0 // FIXME
if (vstCategory == kPlugCategShell)
{
carla_fill<char>(strBuf, STR_MAX+1, '\0');
if (vstCategory != kPlugCategShell)
break;

if ((gVstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0)
cName = strBuf;
}
gVstWantsMidi = false;
gVstWantsTime = false;

carla_zeroChar(strBuf, STR_MAX+1);

gVstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f);

if (gVstCurrentUniqueId != 0)
cName = strBuf;
else
#endif
break;
}

if (gVstNeedsIdle)
effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);

effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);

#else
DISCOVERY_OUT("error", "VST support not available");
return;
@@ -1481,7 +1484,6 @@ void do_fluidsynth_check(const char* const filename, const bool init)
DISCOVERY_OUT("label", (const char*)label);
DISCOVERY_OUT("maker", "");
DISCOVERY_OUT("copyright", "");
DISCOVERY_OUT("category", PLUGIN_CATEGORY_SYNTH);
DISCOVERY_OUT("audio.outs", 2);
DISCOVERY_OUT("audio.total", 2);
DISCOVERY_OUT("midi.ins", 1);
@@ -1502,7 +1504,7 @@ void do_fluidsynth_check(const char* const filename, const bool init)
DISCOVERY_OUT("name", (const char*)name);
DISCOVERY_OUT("label", (const char*)label);
DISCOVERY_OUT("copyright", "");
// DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
DISCOVERY_OUT("audio.outs", 32);
DISCOVERY_OUT("audio.total", 32);
DISCOVERY_OUT("midi.ins", 1);
@@ -1548,6 +1550,26 @@ void do_linuxsampler_check(const char* const filename, const char* const stype,
#endif
}

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

class ScopedWorkingDirSet
{
public:
ScopedWorkingDirSet(const char* const filename)
: fPreviousWorkingDirectory(File::getCurrentWorkingDirectory())
{
File(filename).getParentDirectory().setAsCurrentWorkingDirectory();
}

~ScopedWorkingDirSet()
{
fPreviousWorkingDirectory.setAsCurrentWorkingDirectory();
}

private:
const File fPreviousWorkingDirectory;
};

// ------------------------------ main entry point ------------------------------

int main(int argc, char* argv[])
@@ -1614,18 +1636,21 @@ int main(int argc, char* argv[])
const PluginType type = getPluginTypeFromString(stype);

CarlaString filenameStr(filename);
filenameStr.toLower();

if (filenameStr.contains("fluidsynth", true))
{
DISCOVERY_OUT("info", "skipping fluidsynth based plugin");
return 0;
}
if (filenameStr.contains("linuxsampler", true))
if (filenameStr.contains("linuxsampler", true) || filenameStr.endsWith("ls16.so"))
{
DISCOVERY_OUT("info", "skipping linuxsampler based plugin");
return 0;
}

const ScopedWorkingDirSet swds(filename);

bool openLib = false;
void* handle = nullptr;



+ 4
- 0
source/includes/CarlaDefines.hpp View File

@@ -23,6 +23,10 @@
# include "config.h"
#endif

// Set Version
#define CARLA_VERSION_HEX 0x01090
#define CARLA_VERSION_STRING "1.9.0"

// Check OS
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
# define CARLA_OS_WIN64


+ 3
- 3
source/modules/jackbridge/JackBridge.hpp View File

@@ -240,7 +240,7 @@ typedef int (*JackBufferSizeCallback)(jack_nframes_t nframes, void* arg);
typedef int (*JackSampleRateCallback)(jack_nframes_t nframes, void* arg);
typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int register_, void* arg);
typedef void (*JackClientRegistrationCallback)(const char* name, int register_, void* arg);
typedef int (*JackClientRenameCallback)(const char* old_name, const char* new_name, void* arg);
//typedef int (*JackClientRenameCallback)(const char* old_name, const char* new_name, void* arg);
typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int connect, void* arg);
typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* old_name, const char* new_name, void* arg);
typedef void (*JackFreewheelCallback)(int starting, void* arg);
@@ -257,7 +257,7 @@ CARLA_EXPORT void jackbridge_get_version(int* major_ptr, int* minor_ptr,
CARLA_EXPORT const char* jackbridge_get_version_string();

CARLA_EXPORT jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...);
CARLA_EXPORT const char* jackbridge_client_rename(jack_client_t* client, const char* new_name);
//CARLA_EXPORT const char* jackbridge_client_rename(jack_client_t* client, const char* new_name);
CARLA_EXPORT bool jackbridge_client_close(jack_client_t* client);

CARLA_EXPORT int jackbridge_client_name_size();
@@ -277,7 +277,7 @@ CARLA_EXPORT bool jackbridge_set_freewheel_callback(jack_client_t* client, JackF
CARLA_EXPORT bool jackbridge_set_buffer_size_callback(jack_client_t* client, JackBufferSizeCallback bufsize_callback, void* arg);
CARLA_EXPORT bool jackbridge_set_sample_rate_callback(jack_client_t* client, JackSampleRateCallback srate_callback, void* arg);
CARLA_EXPORT bool jackbridge_set_client_registration_callback(jack_client_t* client, JackClientRegistrationCallback registration_callback, void* arg);
CARLA_EXPORT bool jackbridge_set_client_rename_callback(jack_client_t* client, JackClientRenameCallback rename_callback, void* arg);
//CARLA_EXPORT bool jackbridge_set_client_rename_callback(jack_client_t* client, JackClientRenameCallback rename_callback, void* arg);
CARLA_EXPORT bool jackbridge_set_port_registration_callback(jack_client_t* client, JackPortRegistrationCallback registration_callback, void* arg);
CARLA_EXPORT bool jackbridge_set_port_connect_callback(jack_client_t* client, JackPortConnectCallback connect_callback, void* arg);
CARLA_EXPORT bool jackbridge_set_port_rename_callback(jack_client_t* client, JackPortRenameCallback rename_callback, void* arg);


+ 5
- 1
source/modules/jackbridge/JackBridge1.cpp View File

@@ -46,7 +46,7 @@ typedef int (*jacksym_set_freewheel_callback)(jack_client_t*, JackFreewheelCall
typedef int (*jacksym_set_buffer_size_callback)(jack_client_t*, JackBufferSizeCallback, void*);
typedef int (*jacksym_set_sample_rate_callback)(jack_client_t*, JackSampleRateCallback, void*);
typedef int (*jacksym_set_client_registration_callback)(jack_client_t*, JackClientRegistrationCallback, void*);
typedef int (*jacksym_set_client_rename_callback)(jack_client_t*, JackClientRenameCallback, void*);
//typedef int (*jacksym_set_client_rename_callback)(jack_client_t*, JackClientRenameCallback, void*);
typedef int (*jacksym_set_port_registration_callback)(jack_client_t*, JackPortRegistrationCallback, void*);
typedef int (*jacksym_set_port_connect_callback)(jack_client_t*, JackPortConnectCallback, void*);
typedef int (*jacksym_set_port_rename_callback)(jack_client_t*, JackPortRenameCallback, void*);
@@ -517,6 +517,7 @@ jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t op
return nullptr;
}

#if 0
const char* jackbridge_client_rename(jack_client_t* client, const char* new_name)
{
#if JACKBRIDGE_DUMMY
@@ -528,6 +529,7 @@ const char* jackbridge_client_rename(jack_client_t* client, const char* new_name
#endif
return nullptr;
}
#endif

bool jackbridge_client_close(jack_client_t* client)
{
@@ -715,6 +717,7 @@ bool jackbridge_set_client_registration_callback(jack_client_t* client, JackClie
return false;
}

#if 0
bool jackbridge_set_client_rename_callback(jack_client_t* client, JackClientRenameCallback rename_callback, void* arg)
{
#if JACKBRIDGE_DUMMY
@@ -726,6 +729,7 @@ bool jackbridge_set_client_rename_callback(jack_client_t* client, JackClientRena
#endif
return false;
}
#endif

bool jackbridge_set_port_registration_callback(jack_client_t* client, JackPortRegistrationCallback registration_callback, void *arg)
{


+ 2
- 0
source/utils/CarlaVstUtils.hpp View File

@@ -26,6 +26,7 @@
// Include fixes

// Disable deprecated VST features (NOT)
#define VST_2_4_EXTENSIONS 1
#define VST_FORCE_DEPRECATED 0

#if VESTIGE_HEADER
@@ -106,6 +107,7 @@
#define kVstProcessPrecision32 0
#define kVstTransportChanged 1
#define kVstVersion 2400
#define DECLARE_VST_DEPRECATED(idx) idx
#define VSTCALLBACK
struct ERect {
int16_t top, left, bottom, right;


Loading…
Cancel
Save