Browse Source

More cleanup, vst discovery fixes

tags/v0.9.0
falkTX 12 years ago
parent
commit
ec57ce07aa
8 changed files with 254 additions and 342 deletions
  1. +1
    -1
      c++/Makefile.mk
  2. +4
    -4
      c++/carla-backend/carla_backend.hpp
  3. +30
    -6
      c++/carla-discovery/carla-discovery.cpp
  4. +2
    -0
      c++/carla-plugin/vst.cpp
  5. +6
    -0
      c++/carla-utils/carla_utils.hpp
  6. +1
    -0
      c++/carla-utils/carla_vst_utils.hpp
  7. +203
    -299
      src/carla_backend.py
  8. +7
    -32
      src/shared_carla.py

+ 1
- 1
c++/Makefile.mk View File

@@ -1,6 +1,6 @@
#!/usr/bin/make -f #!/usr/bin/make -f
# Makefile for Cadence C++ code # # Makefile for Cadence C++ code #
# ------------------------------------ #
# -------------------------------------------- #
# Created by falkTX # Created by falkTX
# #




+ 4
- 4
c++/carla-backend/carla_backend.hpp View File

@@ -18,10 +18,10 @@
#ifndef CARLA_BACKEND_HPP #ifndef CARLA_BACKEND_HPP
#define CARLA_BACKEND_HPP #define CARLA_BACKEND_HPP


#include <cstdint>

#include "carla_defines.hpp" #include "carla_defines.hpp"


#include <cstdint>

#define CARLA_BACKEND_START_NAMESPACE namespace CarlaBackend { #define CARLA_BACKEND_START_NAMESPACE namespace CarlaBackend {
#define CARLA_BACKEND_END_NAMESPACE } #define CARLA_BACKEND_END_NAMESPACE }
#define CARLA_BACKEND_USE_NAMESPACE using namespace CarlaBackend; #define CARLA_BACKEND_USE_NAMESPACE using namespace CarlaBackend;
@@ -500,8 +500,8 @@ enum CallbackType {
enum ProcessMode { enum ProcessMode {
PROCESS_MODE_SINGLE_CLIENT = 0, //!< Single client mode (dynamic input/outputs as needed by plugins) PROCESS_MODE_SINGLE_CLIENT = 0, //!< Single client mode (dynamic input/outputs as needed by plugins)
PROCESS_MODE_MULTIPLE_CLIENTS = 1, //!< Multiple client mode (1 master client + 1 client per plugin) PROCESS_MODE_MULTIPLE_CLIENTS = 1, //!< Multiple client mode (1 master client + 1 client per plugin)
PROCESS_MODE_CONTINUOUS_RACK = 2, //!< Single client, "rack" mode. Processes plugins in order of id, with forced stereo.
PROCESS_MODE_PATCHBAY = 3 //!< Single client, "patchbay" mode.
PROCESS_MODE_CONTINUOUS_RACK = 2, //!< Single client, 'rack' mode. Processes plugins in order of id, with forced stereo.
PROCESS_MODE_PATCHBAY = 3 //!< Single client, 'patchbay' mode.
}; };


/*! /*!


+ 30
- 6
c++/carla-discovery/carla-discovery.cpp View File

@@ -62,6 +62,7 @@ using namespace CarlaBackend;
// ------------------------------ VST Stuff ------------------------------ // ------------------------------ VST Stuff ------------------------------


#ifdef WANT_VST #ifdef WANT_VST
bool vstWantsMidi = false;
intptr_t vstCurrentUniqueId = 0; intptr_t vstCurrentUniqueId = 0;


intptr_t vstHostCanDo(const char* const feature) intptr_t vstHostCanDo(const char* const feature)
@@ -120,7 +121,10 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
{ {
case audioMasterAutomate: case audioMasterAutomate:
if (effect) if (effect)
{
effect->setParameter(effect, index, opt); effect->setParameter(effect, index, opt);
ret = 1;
}
break; break;


case audioMasterVersion: case audioMasterVersion:
@@ -131,6 +135,11 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
ret = vstCurrentUniqueId; ret = vstCurrentUniqueId;
break; break;


case audioMasterWantMidi:
vstWantsMidi = true;
ret = 1;
break;

case audioMasterGetTime: case audioMasterGetTime:
static VstTimeInfo_R timeInfo; static VstTimeInfo_R timeInfo;
memset(&timeInfo, 0, sizeof(VstTimeInfo_R)); memset(&timeInfo, 0, sizeof(VstTimeInfo_R));
@@ -154,7 +163,11 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
break; break;


case audioMasterGetNumAutomatableParameters: case audioMasterGetNumAutomatableParameters:
ret = MAX_PARAMETERS;
ret = carla_minPositiveI(effect->numParams, MAX_PARAMETERS);
break;

case audioMasterGetParameterQuantization:
ret = 1; // full single float precision
break; break;


case audioMasterGetSampleRate: case audioMasterGetSampleRate:
@@ -165,22 +178,32 @@ intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode
ret = bufferSize; ret = bufferSize;
break; break;


case audioMasterWillReplaceOrAccumulate:
ret = 1; // replace
break;

case audioMasterGetCurrentProcessLevel: case audioMasterGetCurrentProcessLevel:
ret = kVstProcessLevelUser; ret = kVstProcessLevelUser;
break; break;


case audioMasterGetAutomationState: case audioMasterGetAutomationState:
ret = kVstAutomationReadWrite;
ret = kVstAutomationOff;
break; break;


case audioMasterGetVendorString: case audioMasterGetVendorString:
if (ptr) if (ptr)
{
strcpy((char*)ptr, "Cadence"); strcpy((char*)ptr, "Cadence");
ret = 1;
}
break; break;


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


case audioMasterGetVendorVersion: case audioMasterGetVendorVersion:
@@ -772,7 +795,7 @@ void do_vst_check(void* const libHandle, const bool init)


if (! (effect && effect->magic == kEffectMagic)) if (! (effect && effect->magic == kEffectMagic))
{ {
DISCOVERY_OUT("error", "Failed to init VST plugin");
DISCOVERY_OUT("error", "Failed to init VST plugin, or VST magic failed");
return; return;
} }


@@ -781,6 +804,8 @@ void do_vst_check(void* const libHandle, const bool init)
const char* cVendor; const char* cVendor;
char strBuf[255] = { 0 }; char strBuf[255] = { 0 };


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

effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f); effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f);
cName = strdup((strBuf[0] != 0) ? strBuf : ""); cName = strdup((strBuf[0] != 0) ? strBuf : "");


@@ -795,8 +820,6 @@ void do_vst_check(void* const libHandle, const bool init)
vstCurrentUniqueId = effect->uniqueID; vstCurrentUniqueId = effect->uniqueID;
intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f); intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f);


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

while (true) while (true)
{ {
int hints = 0; int hints = 0;
@@ -816,7 +839,7 @@ void do_vst_check(void* const libHandle, const bool init)
if (effect->flags & effFlagsIsSynth) if (effect->flags & effFlagsIsSynth)
hints |= PLUGIN_IS_SYNTH; hints |= PLUGIN_IS_SYNTH;


if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || (effect->flags & effFlagsIsSynth) > 0)
if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || vstWantsMidi || (effect->flags & effFlagsIsSynth) > 0)
midiIns = 1; midiIns = 1;


if (vstPluginCanDo(effect, "sendVstEvents") || vstPluginCanDo(effect, "sendVstMidiEvent")) if (vstPluginCanDo(effect, "sendVstEvents") || vstPluginCanDo(effect, "sendVstMidiEvent"))
@@ -925,6 +948,7 @@ void do_vst_check(void* const libHandle, const bool init)
break; break;


strBuf[0] = 0; strBuf[0] = 0;
vstWantsMidi = false;
vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f); vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f);


if (vstCurrentUniqueId != 0) if (vstCurrentUniqueId != 0)


+ 2
- 0
c++/carla-plugin/vst.cpp View File

@@ -1980,6 +1980,8 @@ public:
#endif #endif
if (effect && ret > effect->numParams) if (effect && ret > effect->numParams)
ret = effect->numParams; ret = effect->numParams;
// FIXME
//ret = carla_minPositiveI(effect->numParams, MAX_PARAMETERS);
break; break;


case audioMasterGetParameterQuantization: case audioMasterGetParameterQuantization:


+ 6
- 0
c++/carla-utils/carla_utils.hpp View File

@@ -104,6 +104,12 @@ void carla_zeroF(float* data, const unsigned int size)
*data++ = 0.0f; *data++ = 0.0f;
} }


static inline
unsigned int carla_minPositiveI(const int& x, const int& y)
{
return ((x < 0 || y < 0) ? 0 : (x < y ? x : y));
}

static inline static inline
unsigned int carla_minU(const unsigned int& x, const unsigned int& y) unsigned int carla_minU(const unsigned int& x, const unsigned int& y)
{ {


+ 1
- 0
c++/carla-utils/carla_vst_utils.hpp View File

@@ -94,6 +94,7 @@
#define kPlugCategRestoration 8 #define kPlugCategRestoration 8
#define kPlugCategShell 10 #define kPlugCategShell 10
#define kPlugCategGenerator 11 #define kPlugCategGenerator 11
#define kVstAutomationOff 1
#define kVstAutomationReadWrite 4 #define kVstAutomationReadWrite 4
#define kVstProcessLevelUnknown 0 #define kVstProcessLevelUnknown 0
#define kVstProcessLevelUser 1 #define kVstProcessLevelUser 1


+ 203
- 299
src/carla_backend.py View File

@@ -16,13 +16,17 @@
# #
# For a full copy of the GNU General Public License see the COPYING file # For a full copy of the GNU General Public License see the COPYING file


# ------------------------------------------------------------------------------------------------------------
# Imports (Global) # Imports (Global)

import os import os
from ctypes import * from ctypes import *
from copy import deepcopy from copy import deepcopy
from subprocess import Popen, PIPE from subprocess import Popen, PIPE


# ------------------------------------------------------------------------------------------------------------
# Imports (Custom) # Imports (Custom)

from shared_carla import * from shared_carla import *


try: try:
@@ -32,11 +36,13 @@ except:
print("LRDF Support not available (LADSPA-RDF will be disabled)") print("LRDF Support not available (LADSPA-RDF will be disabled)")
haveLRDF = False haveLRDF = False


# ------------------------------------------------------------------------------------------------------------
# Convert a ctypes struct into a dict # Convert a ctypes struct into a dict

def struct_to_dict(struct): def struct_to_dict(struct):
return dict((attr, getattr(struct, attr)) for attr, value in struct._fields_) return dict((attr, getattr(struct, attr)) for attr, value in struct._fields_)


# ------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Default Plugin Folders # Default Plugin Folders


if WINDOWS: if WINDOWS:
@@ -92,18 +98,41 @@ if WINDOWS:
] ]


if PROGRAMFILESx86: if PROGRAMFILESx86:
DEFAULT_LADSPA_PATH += [
os.path.join(PROGRAMFILESx86, "LADSPA")
]
DEFAULT_LADSPA_PATH.append(os.path.join(PROGRAMFILESx86, "LADSPA"))
DEFAULT_DSSI_PATH.append(os.path.join(PROGRAMFILESx86, "DSSI"))
DEFAULT_VST_PATH.append(os.path.join(PROGRAMFILESx86, "VstPlugins"))
DEFAULT_VST_PATH.append(os.path.join(PROGRAMFILESx86, "Steinberg", "VstPlugins"))

elif HAIKU:
splitter = ":"

DEFAULT_LADSPA_PATH = [
# TODO
]

DEFAULT_DSSI_PATH = [
# TODO
]


DEFAULT_DSSI_PATH += [
os.path.join(PROGRAMFILESx86, "DSSI")
]
DEFAULT_LV2_PATH = [
# TODO
]


DEFAULT_VST_PATH += [
os.path.join(PROGRAMFILESx86, "VstPlugins"),
os.path.join(PROGRAMFILESx86, "Steinberg", "VstPlugins")
]
DEFAULT_VST_PATH = [
# TODO
]

DEFAULT_GIG_PATH = [
# TODO
]

DEFAULT_SF2_PATH = [
# TODO
]

DEFAULT_SFZ_PATH = [
# TODO
]


elif MACOS: elif MACOS:
splitter = ":" splitter = ":"
@@ -182,10 +211,10 @@ else:
os.path.join("/", "usr", "share", "sounds", "sfz") os.path.join("/", "usr", "share", "sounds", "sfz")
] ]


# ------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Default Plugin Folders (set) # Default Plugin Folders (set)


global LADSPA_PATH, DSSI_PATH, LV2_PATH, VST_PATH, SF2_PATH
global LADSPA_PATH, DSSI_PATH, LV2_PATH, VST_PATH, GIG_PATH, SF2_PATH, SFZ_PATH


LADSPA_PATH_env = os.getenv("LADSPA_PATH") LADSPA_PATH_env = os.getenv("LADSPA_PATH")
DSSI_PATH_env = os.getenv("DSSI_PATH") DSSI_PATH_env = os.getenv("DSSI_PATH")
@@ -234,8 +263,17 @@ if haveLRDF:
LADSPA_RDF_PATH_env = os.getenv("LADSPA_RDF_PATH") LADSPA_RDF_PATH_env = os.getenv("LADSPA_RDF_PATH")
if LADSPA_RDF_PATH_env: if LADSPA_RDF_PATH_env:
ladspa_rdf.set_rdf_path(LADSPA_RDF_PATH_env.split(splitter)) ladspa_rdf.set_rdf_path(LADSPA_RDF_PATH_env.split(splitter))
del LADSPA_RDF_PATH_env


# ------------------------------------------------------------------------------------------------
del LADSPA_PATH_env
del DSSI_PATH_env
del LV2_PATH_env
del VST_PATH_env
del GIG_PATH_env
del SF2_PATH_env
del SFZ_PATH_env

# ------------------------------------------------------------------------------------------------------------
# Search for Carla library and tools # Search for Carla library and tools


global carla_library_path global carla_library_path
@@ -275,8 +313,8 @@ CWD = sys.path[0]
CWDpp = os.path.join(CWD, "..", "c++") CWDpp = os.path.join(CWD, "..", "c++")


# make it work with cxfreeze # make it work with cxfreeze
if CWD.endswith(os.sep+"carla"):
CWD = CWD.rsplit(os.sep+"carla",1)[0]
if CWD.endswith("%scarla" % os.sep):
CWD = CWD.rsplit("%scarla" % os.sep, 1)[0]
CWDpp = CWD CWDpp = CWD


# find carla_library_path # find carla_library_path
@@ -286,193 +324,63 @@ else:
if WINDOWS: if WINDOWS:
CARLA_PATH = (os.path.join(PROGRAMFILES, "Cadence", "carla"),) CARLA_PATH = (os.path.join(PROGRAMFILES, "Cadence", "carla"),)
elif MACOS: elif MACOS:
# TODO
CARLA_PATH = ("/usr/lib", "/usr/local/lib/")
CARLA_PATH = ("/opt/local/lib", "/usr/local/lib/", "/usr/lib")
else: else:
CARLA_PATH = ("/usr/lib", "/usr/local/lib/")
CARLA_PATH = ("/usr/local/lib/", "/usr/lib")


for p in CARLA_PATH: for p in CARLA_PATH:
if os.path.exists(os.path.join(p, "cadence", carla_libname)): if os.path.exists(os.path.join(p, "cadence", carla_libname)):
carla_library_path = os.path.join(p, "cadence", carla_libname) carla_library_path = os.path.join(p, "cadence", carla_libname)
break break


# find carla_discovery_win32
if os.path.exists(os.path.join(CWDpp, "carla-discovery", "carla-discovery-win32.exe")):
carla_discovery_win32 = os.path.join(CWDpp, "carla-discovery", "carla-discovery-win32.exe")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-discovery-win32.exe")):
carla_discovery_win32 = os.path.join(p, "carla-discovery-win32.exe")
break
# find any tool
def findTool(tdir, tname):
if os.path.exists(os.path.join(CWDpp, tdir, tname)):
return os.path.join(CWDpp, tdir, tname)


# find carla_discovery_win64
if os.path.exists(os.path.join(CWDpp, "carla-discovery", "carla-discovery-win64.exe")):
carla_discovery_win64 = os.path.join(CWDpp, "carla-discovery", "carla-discovery-win64.exe")
else:
for p in PATH: for p in PATH:
if os.path.exists(os.path.join(p, "carla-discovery-win64.exe")):
carla_discovery_win64 = os.path.join(p, "carla-discovery-win64.exe")
break
if os.path.exists(os.path.join(p, tname)):
return os.path.join(p, tname)


# find carla_bridge_win32
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-win32.exe")):
carla_bridge_win32 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-win32.exe")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-win32.exe")):
carla_bridge_win32 = os.path.join(p, "carla-bridge-win32.exe")
break
return ""


# find carla_bridge_win64
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-win64.exe")):
carla_bridge_win64 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-win64.exe")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-win64.exe")):
carla_bridge_win64 = os.path.join(p, "carla-bridge-win64.exe")
break
# find wine/windows tools
carla_discovery_win32 = findTool("carla-discovery", "carla-discovery-win32.exe")
carla_discovery_win64 = findTool("carla-discovery", "carla-discovery-win64.exe")
carla_bridge_win32 = findTool("carla-bridge", "carla-bridge-win32.exe")
carla_bridge_win64 = findTool("carla-bridge", "carla-bridge-win64.exe")


# find native and posix only tools
if not WINDOWS: if not WINDOWS:
# find carla_discovery_native
if os.path.exists(os.path.join(CWDpp, "carla-discovery", "carla-discovery-native")):
carla_discovery_native = os.path.join(CWDpp, "carla-discovery", "carla-discovery-native")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-discovery-native")):
carla_discovery_native = os.path.join(p, "carla-discovery-native")
break

# find carla_discovery_posix32
if os.path.exists(os.path.join(CWDpp, "carla-discovery", "carla-discovery-posix32")):
carla_discovery_posix32 = os.path.join(CWDpp, "carla-discovery", "carla-discovery-posix32")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-discovery-posix32")):
carla_discovery_posix32 = os.path.join(p, "carla-discovery-posix32")
break

# find carla_discovery_posix64
if os.path.exists(os.path.join(CWDpp, "carla-discovery", "carla-discovery-posix64")):
carla_discovery_posix64 = os.path.join(CWDpp, "carla-discovery", "carla-discovery-posix64")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-discovery-posix64")):
carla_discovery_posix64 = os.path.join(p, "carla-discovery-posix64")
break

# find carla_bridge_posix32
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-posix32")):
carla_bridge_posix32 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-posix32")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-posix32")):
carla_bridge_posix32 = os.path.join(p, "carla-bridge-posix32")
break

# find carla_bridge_posix64
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-posix64")):
carla_bridge_posix64 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-posix64")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-posix64")):
carla_bridge_posix64 = os.path.join(p, "carla-bridge-posix64")
break
carla_discovery_native = findTool("carla-discovery", "carla-discovery-native")
carla_discovery_posix32 = findTool("carla-discovery", "carla-discovery-posix32")
carla_discovery_posix64 = findTool("carla-discovery", "carla-discovery-posix64")
carla_bridge_posix32 = findTool("carla-bridge", "carla-bridge-posix32")
carla_bridge_posix64 = findTool("carla-bridge", "carla-bridge-posix64")


# find windows only tools
if WINDOWS: if WINDOWS:
# find carla_bridge_lv2_windows
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-windows.exe")):
carla_bridge_lv2_windows = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-windows.exe")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-windows.exe")):
carla_bridge_lv2_windows = os.path.join(p, "carla-bridge-lv2-windows.exe")
break

# find carla_bridge_vst_hwnd
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-vst-hwnd.exe")):
carla_bridge_vst_hwnd = os.path.join(CWDpp, "carla-bridge", "carla-bridge-vst-hwnd.exe")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-vst-hwnd.exe")):
carla_bridge_vst_hwnd = os.path.join(p, "carla-bridge-vst-hwnd.exe")
break
carla_bridge_lv2_windows = findTool("carla-bridge", "carla-bridge-lv2-windows.exe")
carla_bridge_vst_hwnd = findTool("carla-bridge", "carla-bridge-vst-hwnd.exe")


# find mac os only tools
elif MACOS: elif MACOS:
# find carla_bridge_lv2_cocoa
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-cocoa")):
carla_bridge_lv2_cocoa = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-cocoa")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-cocoa")):
carla_bridge_lv2_cocoa = os.path.join(p, "carla-bridge-lv2-cocoa")
break

# find carla_bridge_vst_cocoa
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-vst-cocoa")):
carla_bridge_vst_cocoa = os.path.join(CWDpp, "carla-bridge", "carla-bridge-vst-cocoa")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-vst-cocoa")):
carla_bridge_vst_cocoa = os.path.join(p, "carla-bridge-vst-cocoa")
break
carla_bridge_lv2_cocoa = findTool("carla-bridge", "carla-bridge-lv2-cocoa")
carla_bridge_vst_cocoa = findTool("carla-bridge", "carla-bridge-vst-cocoa")


# find generic tools
else: else:
# find carla_bridge_lv2_gtk2
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-gtk2")):
carla_bridge_lv2_gtk2 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-gtk2")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-gtk2")):
carla_bridge_lv2_gtk2 = os.path.join(p, "carla-bridge-lv2-gtk2")
break

# find carla_bridge_lv2_gtk3
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-gtk3")):
carla_bridge_lv2_gtk3 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-gtk3")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-gtk3")):
carla_bridge_lv2_gtk3 = os.path.join(p, "carla-bridge-lv2-gtk3")
break

# find carla_bridge_lv2_qt4
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-qt4")):
carla_bridge_lv2_qt4 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-qt4")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-qt4")):
carla_bridge_lv2_qt4 = os.path.join(p, "carla-bridge-lv2-qt4")
break

# find carla_bridge_lv2_qt5
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-qt5")):
carla_bridge_lv2_qt5 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-qt5")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-qt5")):
carla_bridge_lv2_qt5 = os.path.join(p, "carla-bridge-lv2-qt5")
break
carla_bridge_lv2_gtk2 = findTool("carla-bridge", "carla-bridge-lv2-gtk2")
carla_bridge_lv2_gtk3 = findTool("carla-bridge", "carla-bridge-lv2-gtk3")
carla_bridge_lv2_qt4 = findTool("carla-bridge", "carla-bridge-lv2-qt4")
carla_bridge_lv2_qt5 = findTool("carla-bridge", "carla-bridge-lv2-qt5")


# find linux only tools
if LINUX: if LINUX:
# find carla_bridge_lv2_x11
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-x11")):
carla_bridge_lv2_x11 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-lv2-x11")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-lv2-x11")):
carla_bridge_lv2_x11 = os.path.join(p, "carla-bridge-lv2-x11")
break

# find carla_bridge_vst_x11
if os.path.exists(os.path.join(CWDpp, "carla-bridge", "carla-bridge-vst-x11")):
carla_bridge_vst_x11 = os.path.join(CWDpp, "carla-bridge", "carla-bridge-vst-x11")
else:
for p in PATH:
if os.path.exists(os.path.join(p, "carla-bridge-vst-x11")):
carla_bridge_vst_x11 = os.path.join(p, "carla-bridge-vst-x11")
break
carla_bridge_lv2_x11 = os.path.join("carla-bridge", "carla-bridge-lv2-x11")
carla_bridge_vst_x11 = os.path.join("carla-bridge", "carla-bridge-vst-x11")


# ------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Plugin Query (helper functions) # Plugin Query (helper functions)


def findBinaries(bPATH, OS): def findBinaries(bPATH, OS):
@@ -520,32 +428,32 @@ def findSoundKits(bPATH, stype):
return soundfonts return soundfonts


def findDSSIGUI(filename, name, label): def findDSSIGUI(filename, name, label):
plugin_dir = filename.rsplit(".", 1)[0]
short_name = os.path.basename(plugin_dir)
gui_filename = ""
pluginDir = filename.rsplit(".", 1)[0]
shortName = os.path.basename(pluginDir)
guiFilename = ""


check_name = name.replace(" ", "_")
check_label = label
check_sname = short_name
checkName = name.replace(" ", "_")
checkLabel = label
checkSName = shortName


if check_name[-1] != "_": check_name += "_"
if check_label[-1] != "_": check_label += "_"
if check_sname[-1] != "_": check_sname += "_"
if checkName[-1] != "_": checkName += "_"
if checkLabel[-1] != "_": checkLabel += "_"
if checkSName[-1] != "_": checkSName += "_"


for root, dirs, files in os.walk(plugin_dir):
gui_files = files
for root, dirs, files in os.walk(pluginDir):
guiFiles = files
break break
else: else:
gui_files = []
guiFiles = []


for gui in gui_files:
if gui.startswith(check_name) or gui.startswith(check_label) or gui.startswith(check_sname):
gui_filename = os.path.join(plugin_dir, gui)
for gui in guiFiles:
if gui.startswith(checkName) or gui.startswith(checkLabel) or gui.startswith(checkSName):
guiFilename = os.path.join(pluginDir, gui)
break break


return gui_filename
return guiFilename


# ------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Plugin Query # Plugin Query


PLUGIN_QUERY_API_VERSION = 1 PLUGIN_QUERY_API_VERSION = 1
@@ -700,7 +608,7 @@ def checkPluginSF2(filename, tool):
def checkPluginSFZ(filename, tool): def checkPluginSFZ(filename, tool):
return runCarlaDiscovery(PLUGIN_SFZ, "SFZ", filename, tool) return runCarlaDiscovery(PLUGIN_SFZ, "SFZ", filename, tool)


# ------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Backend C++ -> Python variables # Backend C++ -> Python variables


c_enum = c_int c_enum = c_int
@@ -740,7 +648,7 @@ class MidiProgramData(Structure):


class CustomData(Structure): class CustomData(Structure):
_fields_ = [ _fields_ = [
("type", c_enum),
("type", c_char_p),
("key", c_char_p), ("key", c_char_p),
("value", c_char_p) ("value", c_char_p)
] ]
@@ -787,12 +695,9 @@ class GuiInfo(Structure):


CallbackFunc = CFUNCTYPE(None, c_void_p, c_enum, c_ushort, c_int, c_int, c_double, c_char_p) CallbackFunc = CFUNCTYPE(None, c_void_p, c_enum, c_ushort, c_int, c_int, c_double, c_char_p)


# ------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Backend C++ -> Python object # Backend C++ -> Python object


global Callback
Callback = None

class Host(object): class Host(object):
def __init__(self, lib_prefix_arg): def __init__(self, lib_prefix_arg):
object.__init__(self) object.__init__(self)
@@ -1009,8 +914,8 @@ class Host(object):
def get_internal_plugin_info(self, index): def get_internal_plugin_info(self, index):
return struct_to_dict(self.lib.get_internal_plugin_info(index).contents) return struct_to_dict(self.lib.get_internal_plugin_info(index).contents)


def engine_init(self, driver_name, client_name):
return self.lib.engine_init(driver_name.encode("utf-8"), client_name.encode("utf-8"))
def engine_init(self, driverName, clientName):
return self.lib.engine_init(driverName.encode("utf-8"), clientName.encode("utf-8"))


def engine_close(self): def engine_close(self):
return self.lib.engine_close() return self.lib.engine_close()
@@ -1018,148 +923,147 @@ class Host(object):
def is_engine_running(self): def is_engine_running(self):
return self.lib.is_engine_running() return self.lib.is_engine_running()


def add_plugin(self, btype, ptype, filename, name, label, extra_stuff):
return self.lib.add_plugin(btype, ptype, filename.encode("utf-8"), name.encode("utf-8") if name else c_nullptr, label.encode("utf-8"), cast(extra_stuff, c_void_p))
def add_plugin(self, btype, ptype, filename, name, label, extraStuff):
return self.lib.add_plugin(btype, ptype, filename.encode("utf-8"), name.encode("utf-8") if name else c_nullptr, label.encode("utf-8"), cast(extraStuff, c_void_p))


def remove_plugin(self, plugin_id):
return self.lib.remove_plugin(plugin_id)
def remove_plugin(self, pluginId):
return self.lib.remove_plugin(pluginId)


def get_plugin_info(self, plugin_id):
return struct_to_dict(self.lib.get_plugin_info(plugin_id).contents)
def get_plugin_info(self, pluginId):
return struct_to_dict(self.lib.get_plugin_info(pluginId).contents)


def get_audio_port_count_info(self, plugin_id):
return struct_to_dict(self.lib.get_audio_port_count_info(plugin_id).contents)
def get_audio_port_count_info(self, pluginId):
return struct_to_dict(self.lib.get_audio_port_count_info(pluginId).contents)


def get_midi_port_count_info(self, plugin_id):
return struct_to_dict(self.lib.get_midi_port_count_info(plugin_id).contents)
def get_midi_port_count_info(self, pluginId):
return struct_to_dict(self.lib.get_midi_port_count_info(pluginId).contents)


def get_parameter_count_info(self, plugin_id):
return struct_to_dict(self.lib.get_parameter_count_info(plugin_id).contents)
def get_parameter_count_info(self, pluginId):
return struct_to_dict(self.lib.get_parameter_count_info(pluginId).contents)


def get_parameter_info(self, plugin_id, parameter_id):
return struct_to_dict(self.lib.get_parameter_info(plugin_id, parameter_id).contents)
def get_parameter_info(self, pluginId, parameterId):
return struct_to_dict(self.lib.get_parameter_info(pluginId, parameterId).contents)


def get_parameter_scalepoint_info(self, plugin_id, parameter_id, scalepoint_id):
return struct_to_dict(self.lib.get_parameter_scalepoint_info(plugin_id, parameter_id, scalepoint_id).contents)
def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
return struct_to_dict(self.lib.get_parameter_scalepoint_info(pluginId, parameterId, scalePointId).contents)


def get_parameter_data(self, plugin_id, parameter_id):
return struct_to_dict(self.lib.get_parameter_data(plugin_id, parameter_id).contents)
def get_parameter_data(self, pluginId, parameterId):
return struct_to_dict(self.lib.get_parameter_data(pluginId, parameterId).contents)


def get_parameter_ranges(self, plugin_id, parameter_id):
return struct_to_dict(self.lib.get_parameter_ranges(plugin_id, parameter_id).contents)
def get_parameter_ranges(self, pluginId, parameterId):
return struct_to_dict(self.lib.get_parameter_ranges(pluginId, parameterId).contents)


def get_midi_program_data(self, plugin_id, midi_program_id):
return struct_to_dict(self.lib.get_midi_program_data(plugin_id, midi_program_id).contents)
def get_midi_program_data(self, pluginId, midiProgramId):
return struct_to_dict(self.lib.get_midi_program_data(pluginId, midiProgramId).contents)


def get_custom_data(self, plugin_id, custom_data_id):
return struct_to_dict(self.lib.get_custom_data(plugin_id, custom_data_id).contents)
def get_custom_data(self, pluginId, customDataId):
return struct_to_dict(self.lib.get_custom_data(pluginId, customDataId).contents)


def get_chunk_data(self, plugin_id):
return self.lib.get_chunk_data(plugin_id)
def get_chunk_data(self, pluginId):
return self.lib.get_chunk_data(pluginId)


def get_gui_info(self, plugin_id):
return struct_to_dict(self.lib.get_gui_info(plugin_id).contents)
def get_gui_info(self, pluginId):
return struct_to_dict(self.lib.get_gui_info(pluginId).contents)


def get_parameter_count(self, plugin_id):
return self.lib.get_parameter_count(plugin_id)
def get_parameter_count(self, pluginId):
return self.lib.get_parameter_count(pluginId)


def get_program_count(self, plugin_id):
return self.lib.get_program_count(plugin_id)
def get_program_count(self, pluginId):
return self.lib.get_program_count(pluginId)


def get_midi_program_count(self, plugin_id):
return self.lib.get_midi_program_count(plugin_id)
def get_midi_program_count(self, pluginId):
return self.lib.get_midi_program_count(pluginId)


def get_custom_data_count(self, plugin_id):
return self.lib.get_custom_data_count(plugin_id)
def get_custom_data_count(self, pluginId):
return self.lib.get_custom_data_count(pluginId)


def get_parameter_text(self, plugin_id, program_id):
return self.lib.get_parameter_text(plugin_id, program_id)
def get_parameter_text(self, pluginId, parameterId):
return self.lib.get_parameter_text(pluginId, parameterId)


def get_program_name(self, plugin_id, program_id):
return self.lib.get_program_name(plugin_id, program_id)
def get_program_name(self, pluginId, programId):
return self.lib.get_program_name(pluginId, programId)


def get_midi_program_name(self, plugin_id, midi_program_id):
return self.lib.get_midi_program_name(plugin_id, midi_program_id)
def get_midi_program_name(self, pluginId, midiProgramId):
return self.lib.get_midi_program_name(pluginId, midiProgramId)


def get_real_plugin_name(self, plugin_id):
return self.lib.get_real_plugin_name(plugin_id)
def get_real_plugin_name(self, pluginId):
return self.lib.get_real_plugin_name(pluginId)


def get_current_program_index(self, plugin_id):
return self.lib.get_current_program_index(plugin_id)
def get_current_program_index(self, pluginId):
return self.lib.get_current_program_index(pluginId)


def get_current_midi_program_index(self, plugin_id):
return self.lib.get_current_midi_program_index(plugin_id)
def get_current_midi_program_index(self, pluginId):
return self.lib.get_current_midi_program_index(pluginId)


def get_default_parameter_value(self, plugin_id, parameter_id):
return self.lib.get_default_parameter_value(plugin_id, parameter_id)
def get_default_parameter_value(self, pluginId, parameterId):
return self.lib.get_default_parameter_value(pluginId, parameterId)


def get_current_parameter_value(self, plugin_id, parameter_id):
return self.lib.get_current_parameter_value(plugin_id, parameter_id)
def get_current_parameter_value(self, pluginId, parameterId):
return self.lib.get_current_parameter_value(pluginId, parameterId)


def get_input_peak_value(self, plugin_id, port_id):
return self.lib.get_input_peak_value(plugin_id, port_id)
def get_input_peak_value(self, pluginId, portId):
return self.lib.get_input_peak_value(pluginId, portId)


def get_output_peak_value(self, plugin_id, port_id):
return self.lib.get_output_peak_value(plugin_id, port_id)
def get_output_peak_value(self, pluginId, portId):
return self.lib.get_output_peak_value(pluginId, portId)


def set_active(self, plugin_id, onoff):
self.lib.set_active(plugin_id, onoff)
def set_active(self, pluginId, onOff):
self.lib.set_active(pluginId, onOff)


def set_drywet(self, plugin_id, value):
self.lib.set_drywet(plugin_id, value)
def set_drywet(self, pluginId, value):
self.lib.set_drywet(pluginId, value)


def set_volume(self, plugin_id, value):
self.lib.set_volume(plugin_id, value)
def set_volume(self, pluginId, value):
self.lib.set_volume(pluginId, value)


def set_balance_left(self, plugin_id, value):
self.lib.set_balance_left(plugin_id, value)
def set_balance_left(self, pluginId, value):
self.lib.set_balance_left(pluginId, value)


def set_balance_right(self, plugin_id, value):
self.lib.set_balance_right(plugin_id, value)
def set_balance_right(self, pluginId, value):
self.lib.set_balance_right(pluginId, value)


def set_parameter_value(self, plugin_id, parameter_id, value):
self.lib.set_parameter_value(plugin_id, parameter_id, value)
def set_parameter_value(self, pluginId, parameterId, value):
self.lib.set_parameter_value(pluginId, parameterId, value)


def set_parameter_midi_cc(self, plugin_id, parameter_id, midi_cc):
self.lib.set_parameter_midi_cc(plugin_id, parameter_id, midi_cc)
def set_parameter_midi_cc(self, pluginId, parameterId, cc):
self.lib.set_parameter_midi_cc(pluginId, parameterId, cc)


def set_parameter_midi_channel(self, plugin_id, parameter_id, channel):
self.lib.set_parameter_midi_channel(plugin_id, parameter_id, channel)
def set_parameter_midi_channel(self, pluginId, parameterId, channel):
self.lib.set_parameter_midi_channel(pluginId, parameterId, channel)


def set_program(self, plugin_id, program_id):
self.lib.set_program(plugin_id, program_id)
def set_program(self, pluginId, programId):
self.lib.set_program(pluginId, programId)


def set_midi_program(self, plugin_id, midi_program_id):
self.lib.set_midi_program(plugin_id, midi_program_id)
def set_midi_program(self, pluginId, midiProgramId):
self.lib.set_midi_program(pluginId, midiProgramId)


def set_custom_data(self, plugin_id, type_, key, value):
self.lib.set_custom_data(plugin_id, type_.encode("utf-8"), key.encode("utf-8"), value.encode("utf-8"))
def set_custom_data(self, pluginId, type_, key, value):
self.lib.set_custom_data(pluginId, type_.encode("utf-8"), key.encode("utf-8"), value.encode("utf-8"))


def set_chunk_data(self, plugin_id, chunk_data):
self.lib.set_chunk_data(plugin_id, chunk_data.encode("utf-8"))
def set_chunk_data(self, pluginId, chunkData):
self.lib.set_chunk_data(pluginId, chunkData.encode("utf-8"))


def set_gui_container(self, plugin_id, gui_addr):
self.lib.set_gui_container(plugin_id, gui_addr)
def set_gui_container(self, pluginId, guiAddr):
self.lib.set_gui_container(pluginId, guiAddr)


def show_gui(self, plugin_id, yesno):
self.lib.show_gui(plugin_id, yesno)
def show_gui(self, pluginId, yesNo):
self.lib.show_gui(pluginId, yesNo)


def idle_guis(self): def idle_guis(self):
self.lib.idle_guis() self.lib.idle_guis()


def send_midi_note(self, plugin_id, channel, note, velocity):
self.lib.send_midi_note(plugin_id, channel, note, velocity)
def send_midi_note(self, pluginId, channel, note, velocity):
self.lib.send_midi_note(pluginId, channel, note, velocity)


def prepare_for_save(self, plugin_id):
self.lib.prepare_for_save(plugin_id)
def prepare_for_save(self, pluginId):
self.lib.prepare_for_save(pluginId)


def set_callback_function(self, func): def set_callback_function(self, func):
global Callback
Callback = CallbackFunc(func)
self.lib.set_callback_function(Callback)
self.callback = CallbackFunc(func)
self.lib.set_callback_function(self.callback)


def set_option(self, option, value, value_str):
self.lib.set_option(option, value, value_str.encode("utf-8"))
def set_option(self, option, value, valueStr):
self.lib.set_option(option, value, valueStr.encode("utf-8"))


def get_last_error(self): def get_last_error(self):
return self.lib.get_last_error() return self.lib.get_last_error()


+ 7
- 32
src/shared_carla.py View File

@@ -23,7 +23,7 @@ import platform
from copy import deepcopy from copy import deepcopy
from decimal import Decimal from decimal import Decimal
from sip import unwrapinstance from sip import unwrapinstance
from PyQt4.QtCore import pyqtSlot, Qt, QSettings, QTimer
from PyQt4.QtCore import pyqtSlot, qFatal, Qt, QSettings, QTimer
from PyQt4.QtGui import QColor, QCursor, QDialog, QFontMetrics, QFrame, QGraphicsScene, QInputDialog, QLinearGradient, QMenu, QPainter, QPainterPath, QVBoxLayout, QWidget from PyQt4.QtGui import QColor, QCursor, QDialog, QFontMetrics, QFrame, QGraphicsScene, QInputDialog, QLinearGradient, QMenu, QPainter, QPainterPath, QVBoxLayout, QWidget
from PyQt4.QtXml import QDomDocument from PyQt4.QtXml import QDomDocument


@@ -69,6 +69,10 @@ PARAMETER_USES_SAMPLERATE = 0x20
PARAMETER_USES_SCALEPOINTS = 0x40 PARAMETER_USES_SCALEPOINTS = 0x40
PARAMETER_USES_CUSTOM_TEXT = 0x80 PARAMETER_USES_CUSTOM_TEXT = 0x80


# group custom data types
CUSTOM_DATA_INVALID = None
CUSTOM_DATA_STRING = "urn:carla:string"

# enum BinaryType # enum BinaryType
BINARY_NONE = 0 BINARY_NONE = 0
BINARY_POSIX32 = 1 BINARY_POSIX32 = 1
@@ -116,13 +120,6 @@ PARAMETER_VOLUME = -4
PARAMETER_BALANCE_LEFT = -5 PARAMETER_BALANCE_LEFT = -5
PARAMETER_BALANCE_RIGHT = -6 PARAMETER_BALANCE_RIGHT = -6


# enum CustomDataType
CUSTOM_DATA_INVALID = 0
CUSTOM_DATA_STRING = 1
CUSTOM_DATA_PATH = 2
CUSTOM_DATA_CHUNK = 3
CUSTOM_DATA_BINARY = 4

# enum GuiType # enum GuiType
GUI_NONE = 0 GUI_NONE = 0
GUI_INTERNAL_QT4 = 1 GUI_INTERNAL_QT4 = 1
@@ -189,7 +186,7 @@ PROCESS_MODE_MULTIPLE_CLIENTS = 1
PROCESS_MODE_CONTINUOUS_RACK = 2 PROCESS_MODE_CONTINUOUS_RACK = 2
PROCESS_MODE_PATCHBAY = 3 PROCESS_MODE_PATCHBAY = 3


# TODO ...
# Set BINARY_NATIVE
if HAIKU or LINUX or MACOS: if HAIKU or LINUX or MACOS:
BINARY_NATIVE = BINARY_POSIX64 if is64bit else BINARY_POSIX32 BINARY_NATIVE = BINARY_POSIX64 if is64bit else BINARY_POSIX32
elif WINDOWS: elif WINDOWS:
@@ -269,28 +266,6 @@ CarlaSaveState = {
'Chunk': None 'Chunk': None
} }


def getCustomDataTypeString(dtype):
if dtype == CUSTOM_DATA_STRING:
return "string"
if dtype == CUSTOM_DATA_PATH:
return "path"
if dtype == CUSTOM_DATA_CHUNK:
return "chunk"
if dtype == CUSTOM_DATA_BINARY:
return "binary"
return "null"

def getCustomDataStringType(stype):
if stype == "string":
return CUSTOM_DATA_STRING
if stype == "path":
return CUSTOM_DATA_PATH
if stype == "chunk":
return CUSTOM_DATA_CHUNK
if stype == "binary":
return CUSTOM_DATA_BINARY
return CUSTOM_DATA_INVALID

def getSaveStateDictFromXML(xmlNode): def getSaveStateDictFromXML(xmlNode):
saveState = deepcopy(CarlaSaveState) saveState = deepcopy(CarlaSaveState)


@@ -402,7 +377,7 @@ def getSaveStateDictFromXML(xmlNode):
cText = xmlSubData.toElement().text().strip() cText = xmlSubData.toElement().text().strip()


if cTag == "type": if cTag == "type":
stateCustomData['type'] = getCustomDataStringType(cText)
stateCustomData['type'] = cText
elif cTag == "key": elif cTag == "key":
stateCustomData['key'] = xmlSafeString(cText, False) stateCustomData['key'] = xmlSafeString(cText, False)
elif cTag == "value": elif cTag == "value":


Loading…
Cancel
Save