From 8a5d2b8bb03473ef5b78593408abad06d9738b3d Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 15 Aug 2013 06:45:09 +0100 Subject: [PATCH] Initial PyQt5 work --- Makefile | 12 +- source/backend/CarlaBackend.hpp | 13 +- source/carla_backend.py | 13 +- source/carla_shared.py | 333 ++++++++++++--------- source/ladspa_rdf.py | 2 +- source/modules/widgets/digitalpeakmeter.py | 7 +- source/modules/widgets/ledbutton.py | 7 +- source/modules/widgets/paramspinbox.py | 19 +- source/modules/widgets/pixmapbutton.py | 7 +- source/modules/widgets/pixmapdial.py | 11 +- source/modules/widgets/pixmapkeyboard.py | 9 +- 11 files changed, 257 insertions(+), 176 deletions(-) diff --git a/Makefile b/Makefile index c2b0d8f6e..2f737f2f6 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,8 @@ DESTDIR = SED_PREFIX = $(shell echo $(PREFIX) | sed "s/\//\\\\\\\\\//g") LINK = ln -sf -PYUIC ?= pyuic4 -PYRCC ?= pyrcc4 -py3 +PYUIC ?= pyuic5 +PYRCC ?= pyrcc5 # -------------------------------------------------------------- @@ -300,7 +300,7 @@ endif ifeq ($(CARLA_PLUGIN_SUPPORT),true) @echo "\033[36m---> LV2 UI toolkit support: \033[0m" - @echo "ExternalUI:$(ANS_YES) (direct)" + @echo "ExternalUI:$(ANS_YES) (direct+bridge)" ifeq ($(MACOS),true) # --- MacOS --- @echo "CocoaUI: $(ANS_YES) (direct+bridge)" @@ -323,16 +323,12 @@ else @echo "Gtk3UI: $(ANS_NO) $(mS)Gtk3 missing$(mE)" endif ifeq ($(HAVE_QT4),true) - @echo "Qt4UI: $(ANS_YES) (direct+bridge)" + @echo "Qt4UI: $(ANS_YES) (bridge)" else @echo "Qt4UI: $(ANS_NO) $(mS)Qt4 missing$(mE)" endif ifeq ($(HAVE_QT5),true) -ifeq ($(HAVE_QT4),true) @echo "Qt5UI: $(ANS_YES) (bridge)" -else - @echo "Qt5UI: $(ANS_YES) (direct+bridge)" -endif else @echo "Qt5UI: $(ANS_NO) $(mS)Qt5 missing$(mE)" endif diff --git a/source/backend/CarlaBackend.hpp b/source/backend/CarlaBackend.hpp index 9f84aa7d7..8456c3184 100644 --- a/source/backend/CarlaBackend.hpp +++ b/source/backend/CarlaBackend.hpp @@ -150,13 +150,12 @@ enum PluginType { PLUGIN_LADSPA = 2, //!< LADSPA plugin. PLUGIN_DSSI = 3, //!< DSSI plugin. PLUGIN_LV2 = 4, //!< LV2 plugin. - PLUGIN_VST = 5, //!< VST1/2 plugin. - PLUGIN_VST3 = 6, //!< VST3 plugin. - PLUGIN_AU = 7, //!< AU plugin. - PLUGIN_CSOUND = 8, //!< Csound file. - PLUGIN_GIG = 9, //!< GIG sound kit. - PLUGIN_SF2 = 10, //!< SF2 sound kit (aka SoundFont). - PLUGIN_SFZ = 11 //!< SFZ sound kit. + PLUGIN_VST = 5, //!< VST plugin. + PLUGIN_AU = 6, //!< AU plugin. + PLUGIN_CSOUND = 7, //!< Csound file. + PLUGIN_GIG = 8, //!< GIG sound kit. + PLUGIN_SF2 = 9, //!< SF2 sound kit (aka SoundFont). + PLUGIN_SFZ = 10 //!< SFZ sound kit. }; /*! diff --git a/source/carla_backend.py b/source/carla_backend.py index d000a2bc7..5c7b969ea 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) @@ -153,12 +153,11 @@ PLUGIN_LADSPA = 2 PLUGIN_DSSI = 3 PLUGIN_LV2 = 4 PLUGIN_VST = 5 -PLUGIN_VST3 = 6 -PLUGIN_AU = 7 -PLUGIN_CSOUND = 8 -PLUGIN_GIG = 9 -PLUGIN_SF2 = 10 -PLUGIN_SFZ = 11 +PLUGIN_AU = 6 +PLUGIN_CSOUND = 7 +PLUGIN_GIG = 8 +PLUGIN_SF2 = 9 +PLUGIN_SFZ = 10 # Plugin Category PLUGIN_CATEGORY_NONE = 0 diff --git a/source/carla_shared.py b/source/carla_shared.py index 4d033b531..30053453a 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -14,19 +14,22 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) import os -import json import sys from copy import deepcopy from subprocess import Popen, PIPE -from PyQt4.QtCore import pyqtSlot, qWarning, Qt, QByteArray, QSettings, QThread, QTimer, SIGNAL, SLOT -from PyQt4.QtGui import QColor, QCursor, QDialog, QIcon, QInputDialog, QFileDialog, QFontMetrics, QFrame, QMenu -from PyQt4.QtGui import QLineEdit, QMessageBox, QPainter, QPainterPath, QTableWidgetItem, QVBoxLayout, QWidget +from PyQt5.QtCore import qCritical, qFatal, qWarning, Qt, QByteArray, QThread, QSettings +from PyQt5.QtGui import QColor, QCursor, QFontMetrics, QIcon, QPainter, QPainterPath +from PyQt5.QtWidgets import QDialog, QFileDialog, QFrame, QInputDialog, QLineEdit, QMenu, QMessageBox +from PyQt5.QtWidgets import QTableWidgetItem, QVBoxLayout, QWidget + +# remove? +from PyQt5.QtCore import pyqtSlot # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) @@ -44,19 +47,22 @@ from carla_backend import * try: import ladspa_rdf + import json haveLRDF = True except: - print("LRDF Support not available (LADSPA-RDF will be disabled)") + qWarning("LRDF Support not available (LADSPA-RDF will be disabled)") haveLRDF = False # ------------------------------------------------------------------------------------------------------------ -# Try Import Signal +# Import Signal + +from signal import signal, SIGINT, SIGTERM try: - from signal import signal, SIGINT, SIGTERM, SIGUSR1 - haveSignal = True + from signal import SIGUSR1 + haveSIGUSR1 = True except: - haveSignal = False + haveSIGUSR1 = False # ------------------------------------------------------------------------------------------------------------ # Platform specific stuff @@ -70,7 +76,7 @@ elif WINDOWS: # ------------------------------------------------------------------------------------------------------------ # Set Version -VERSION = "1.1.0" +VERSION = "1.9.0" # ------------------------------------------------------------------------------------------------------------ # Set TMP @@ -132,6 +138,7 @@ class CarlaObject(object): 'DSSI_PATH', 'LV2_PATH', 'VST_PATH', + 'CSOUND_PATH', 'GIG_PATH', 'SF2_PATH', 'SFZ_PATH' @@ -140,8 +147,8 @@ class CarlaObject(object): Carla = CarlaObject() Carla.host = None Carla.gui = None -Carla.isControl = False -Carla.isLocal = True +Carla.isControl = True +Carla.isLocal = False Carla.processMode = PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else PROCESS_MODE_CONTINUOUS_RACK Carla.maxParameters = MAX_DEFAULT_PARAMETERS @@ -153,16 +160,6 @@ ICON_STATE_OFF = 1 ICON_STATE_WAIT = 2 ICON_STATE_ON = 3 -PALETTE_COLOR_NONE = 0 -PALETTE_COLOR_WHITE = 1 -PALETTE_COLOR_RED = 2 -PALETTE_COLOR_GREEN = 3 -PALETTE_COLOR_BLUE = 4 -PALETTE_COLOR_YELLOW = 5 -PALETTE_COLOR_ORANGE = 6 -PALETTE_COLOR_BROWN = 7 -PALETTE_COLOR_PINK = 8 - # ------------------------------------------------------------------------------------------------------------ # Static MIDI CC list @@ -231,38 +228,40 @@ if WINDOWS: # Small integrity tests if not APPDATA: - print("APPDATA variable not set, cannot continue") + qFatal("APPDATA variable not set, cannot continue") sys.exit(1) if not PROGRAMFILES: - print("PROGRAMFILES variable not set, cannot continue") + qFatal("PROGRAMFILES variable not set, cannot continue") sys.exit(1) if not COMMONPROGRAMFILES: - print("COMMONPROGRAMFILES variable not set, cannot continue") + qFatal("COMMONPROGRAMFILES variable not set, cannot continue") sys.exit(1) DEFAULT_LADSPA_PATH = ";".join((os.path.join(APPDATA, "LADSPA"), os.path.join(PROGRAMFILES, "LADSPA"))) - DEFAULT_DSSI_PATH = ";".join((os.path.join(APPDATA, "DSSI"), - os.path.join(PROGRAMFILES, "DSSI"))) + DEFAULT_DSSI_PATH = ";".join((os.path.join(APPDATA, "DSSI"), + os.path.join(PROGRAMFILES, "DSSI"))) - DEFAULT_LV2_PATH = ";".join((os.path.join(APPDATA, "LV2"), - os.path.join(COMMONPROGRAMFILES, "LV2"))) + DEFAULT_LV2_PATH = ";".join((os.path.join(APPDATA, "LV2"), + os.path.join(COMMONPROGRAMFILES, "LV2"))) - DEFAULT_VST_PATH = ";".join((os.path.join(PROGRAMFILES, "VstPlugins"), - os.path.join(PROGRAMFILES, "Steinberg", "VstPlugins"))) + DEFAULT_VST_PATH = ";".join((os.path.join(PROGRAMFILES, "VstPlugins"), + os.path.join(PROGRAMFILES, "Steinberg", "VstPlugins"))) + # TODO + DEFAULT_CSOUND_PATH = "" - DEFAULT_GIG_PATH = ";".join((os.path.join(APPDATA, "GIG"),)) - DEFAULT_SF2_PATH = ";".join((os.path.join(APPDATA, "SF2"),)) - DEFAULT_SFZ_PATH = ";".join((os.path.join(APPDATA, "SFZ"),)) + DEFAULT_GIG_PATH = ";".join((os.path.join(APPDATA, "GIG"),)) + DEFAULT_SF2_PATH = ";".join((os.path.join(APPDATA, "SF2"),)) + DEFAULT_SFZ_PATH = ";".join((os.path.join(APPDATA, "SFZ"),)) if PROGRAMFILESx86: DEFAULT_LADSPA_PATH += ";"+os.path.join(PROGRAMFILESx86, "LADSPA") - DEFAULT_DSSI_PATH += ";"+os.path.join(PROGRAMFILESx86, "DSSI") - DEFAULT_VST_PATH += ";"+os.path.join(PROGRAMFILESx86, "VstPlugins") - DEFAULT_VST_PATH += ";"+os.path.join(PROGRAMFILESx86, "Steinberg", "VstPlugins") + DEFAULT_DSSI_PATH += ";"+os.path.join(PROGRAMFILESx86, "DSSI") + DEFAULT_VST_PATH += ";"+os.path.join(PROGRAMFILESx86, "VstPlugins") + DEFAULT_VST_PATH += ";"+os.path.join(PROGRAMFILESx86, "Steinberg", "VstPlugins") elif HAIKU: splitter = ":" @@ -270,19 +269,22 @@ elif HAIKU: DEFAULT_LADSPA_PATH = ":".join((os.path.join(HOME, ".ladspa"), os.path.join("/", "boot", "common", "add-ons", "ladspa"))) - DEFAULT_DSSI_PATH = ":".join((os.path.join(HOME, ".dssi"), - os.path.join("/", "boot", "common", "add-ons", "dssi"))) + DEFAULT_DSSI_PATH = ":".join((os.path.join(HOME, ".dssi"), + os.path.join("/", "boot", "common", "add-ons", "dssi"))) + + DEFAULT_LV2_PATH = ":".join((os.path.join(HOME, ".lv2"), + os.path.join("/", "boot", "common", "add-ons", "lv2"))) - DEFAULT_LV2_PATH = ":".join((os.path.join(HOME, ".lv2"), - os.path.join("/", "boot", "common", "add-ons", "lv2"))) + DEFAULT_VST_PATH = ":".join((os.path.join(HOME, ".vst"), + os.path.join("/", "boot", "common", "add-ons", "vst"))) - DEFAULT_VST_PATH = ":".join((os.path.join(HOME, ".vst"), - os.path.join("/", "boot", "common", "add-ons", "vst"))) + # TODO + DEFAULT_CSOUND_PATH = "" # TODO - DEFAULT_GIG_PATH = "" - DEFAULT_SF2_PATH = "" - DEFAULT_SFZ_PATH = "" + DEFAULT_GIG_PATH = "" + DEFAULT_SF2_PATH = "" + DEFAULT_SFZ_PATH = "" elif MACOS: splitter = ":" @@ -290,19 +292,22 @@ elif MACOS: DEFAULT_LADSPA_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "LADSPA"), os.path.join("/", "Library", "Audio", "Plug-Ins", "LADSPA"))) - DEFAULT_DSSI_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "DSSI"), - os.path.join("/", "Library", "Audio", "Plug-Ins", "DSSI"))) + DEFAULT_DSSI_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "DSSI"), + os.path.join("/", "Library", "Audio", "Plug-Ins", "DSSI"))) + + DEFAULT_LV2_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "LV2"), + os.path.join("/", "Library", "Audio", "Plug-Ins", "LV2"))) - DEFAULT_LV2_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "LV2"), - os.path.join("/", "Library", "Audio", "Plug-Ins", "LV2"))) + DEFAULT_VST_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "VST"), + os.path.join("/", "Library", "Audio", "Plug-Ins", "VST"))) - DEFAULT_VST_PATH = ":".join((os.path.join(HOME, "Library", "Audio", "Plug-Ins", "VST"), - os.path.join("/", "Library", "Audio", "Plug-Ins", "VST"))) + # TODO + DEFAULT_CSOUND_PATH = "" # TODO - DEFAULT_GIG_PATH = "" - DEFAULT_SF2_PATH = "" - DEFAULT_SFZ_PATH = "" + DEFAULT_GIG_PATH = "" + DEFAULT_SF2_PATH = "" + DEFAULT_SFZ_PATH = "" else: splitter = ":" @@ -311,26 +316,29 @@ else: os.path.join("/", "usr", "lib", "ladspa"), os.path.join("/", "usr", "local", "lib", "ladspa"))) - DEFAULT_DSSI_PATH = ":".join((os.path.join(HOME, ".dssi"), - os.path.join("/", "usr", "lib", "dssi"), - os.path.join("/", "usr", "local", "lib", "dssi"))) + DEFAULT_DSSI_PATH = ":".join((os.path.join(HOME, ".dssi"), + os.path.join("/", "usr", "lib", "dssi"), + os.path.join("/", "usr", "local", "lib", "dssi"))) - DEFAULT_LV2_PATH = ":".join((os.path.join(HOME, ".lv2"), - os.path.join("/", "usr", "lib", "lv2"), - os.path.join("/", "usr", "local", "lib", "lv2"))) + DEFAULT_LV2_PATH = ":".join((os.path.join(HOME, ".lv2"), + os.path.join("/", "usr", "lib", "lv2"), + os.path.join("/", "usr", "local", "lib", "lv2"))) - DEFAULT_VST_PATH = ":".join((os.path.join(HOME, ".vst"), - os.path.join("/", "usr", "lib", "vst"), - os.path.join("/", "usr", "local", "lib", "vst"))) + DEFAULT_VST_PATH = ":".join((os.path.join(HOME, ".vst"), + os.path.join("/", "usr", "lib", "vst"), + os.path.join("/", "usr", "local", "lib", "vst"))) + + # TODO + DEFAULT_CSOUND_PATH = "" - DEFAULT_GIG_PATH = ":".join((os.path.join(HOME, ".sounds"), - os.path.join("/", "usr", "share", "sounds", "gig"))) + DEFAULT_GIG_PATH = ":".join((os.path.join(HOME, ".sounds"), + os.path.join("/", "usr", "share", "sounds", "gig"))) - DEFAULT_SF2_PATH = ":".join((os.path.join(HOME, ".sounds"), - os.path.join("/", "usr", "share", "sounds", "sf2"))) + DEFAULT_SF2_PATH = ":".join((os.path.join(HOME, ".sounds"), + os.path.join("/", "usr", "share", "sounds", "sf2"))) - DEFAULT_SFZ_PATH = ":".join((os.path.join(HOME, ".sounds"), - os.path.join("/", "usr", "share", "sounds", "sfz"))) + DEFAULT_SFZ_PATH = ":".join((os.path.join(HOME, ".sounds"), + os.path.join("/", "usr", "share", "sounds", "sfz"))) # ------------------------------------------------------------------------------------------------------------ # Default Plugin Folders (set) @@ -354,12 +362,13 @@ if WINDOWS: if readEnvVars: Carla.LADSPA_PATH = os.getenv("LADSPA_PATH", DEFAULT_LADSPA_PATH).split(splitter) - Carla.DSSI_PATH = os.getenv("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter) - Carla.LV2_PATH = os.getenv("LV2_PATH", DEFAULT_LV2_PATH).split(splitter) - Carla.VST_PATH = os.getenv("VST_PATH", DEFAULT_VST_PATH).split(splitter) - Carla.GIG_PATH = os.getenv("GIG_PATH", DEFAULT_GIG_PATH).split(splitter) - Carla.SF2_PATH = os.getenv("SF2_PATH", DEFAULT_SF2_PATH).split(splitter) - Carla.SFZ_PATH = os.getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter) + Carla.DSSI_PATH = os.getenv("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter) + Carla.LV2_PATH = os.getenv("LV2_PATH", DEFAULT_LV2_PATH).split(splitter) + Carla.VST_PATH = os.getenv("VST_PATH", DEFAULT_VST_PATH).split(splitter) + Carla.CSOUND_PATH = os.getenv("CSOUND_PATH", DEFAULT_CSOUND_PATH).split(splitter) + Carla.GIG_PATH = os.getenv("GIG_PATH", DEFAULT_GIG_PATH).split(splitter) + Carla.SF2_PATH = os.getenv("SF2_PATH", DEFAULT_SF2_PATH).split(splitter) + Carla.SFZ_PATH = os.getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter) if haveLRDF: LADSPA_RDF_PATH_env = os.getenv("LADSPA_RDF_PATH") @@ -369,18 +378,20 @@ if readEnvVars: else: Carla.LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter) - Carla.DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter) - Carla.LV2_PATH = DEFAULT_LV2_PATH.split(splitter) - Carla.VST_PATH = DEFAULT_VST_PATH.split(splitter) - Carla.GIG_PATH = DEFAULT_GIG_PATH.split(splitter) - Carla.SF2_PATH = DEFAULT_SF2_PATH.split(splitter) - Carla.SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter) + Carla.DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter) + Carla.LV2_PATH = DEFAULT_LV2_PATH.split(splitter) + Carla.VST_PATH = DEFAULT_VST_PATH.split(splitter) + Carla.CSOUND_PATH = DEFAULT_CSOUND_PATH.split(splitter) + Carla.GIG_PATH = DEFAULT_GIG_PATH.split(splitter) + Carla.SF2_PATH = DEFAULT_SF2_PATH.split(splitter) + Carla.SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter) + +del readEnvVars # ------------------------------------------------------------------------------------------------------------ # Search for Carla library and tools -global carla_library_path -carla_library_path = "" +carla_library_filename = "" carla_discovery_native = "" carla_discovery_posix32 = "" @@ -394,17 +405,18 @@ carla_bridge_posix64 = "" carla_bridge_win32 = "" carla_bridge_win64 = "" -carla_bridge_lv2_gtk2 = "" -carla_bridge_lv2_gtk3 = "" -carla_bridge_lv2_qt4 = "" -carla_bridge_lv2_qt5 = "" -carla_bridge_lv2_cocoa = "" -carla_bridge_lv2_windows = "" -carla_bridge_lv2_x11 = "" +carla_bridge_lv2_external = "" +carla_bridge_lv2_gtk2 = "" +carla_bridge_lv2_gtk3 = "" +carla_bridge_lv2_qt4 = "" +carla_bridge_lv2_qt5 = "" +carla_bridge_lv2_cocoa = "" +carla_bridge_lv2_windows = "" +carla_bridge_lv2_x11 = "" -carla_bridge_vst_cocoa = "" -carla_bridge_vst_hwnd = "" -carla_bridge_vst_x11 = "" +carla_bridge_vst_mac = "" +carla_bridge_vst_hwnd = "" +carla_bridge_vst_x11 = "" if WINDOWS: carla_libname = "libcarla_standalone.dll" @@ -416,14 +428,14 @@ else: CWD = sys.path[0] # make it work with cxfreeze -if CWD.endswith("%scarla" % os.sep): - CWD = CWD.rsplit("%scarla" % os.sep, 1)[0] -elif CWD.endswith("carla.exe"): - CWD = CWD.rsplit("carla.exe", 1)[0] +if CWD.endswith("/carla"): + CWD = CWD.rsplit("/carla", 1)[0] +elif CWD.endswith("\\carla.exe"): + CWD = CWD.rsplit("\\carla.exe", 1)[0] -# find carla_library_path +# find carla_library_filename if os.path.exists(os.path.join(CWD, "backend", carla_libname)): - carla_library_path = os.path.join(CWD, "backend", carla_libname) + carla_library_filename = os.path.join(CWD, "backend", carla_libname) else: if WINDOWS: CARLA_PATH = (os.path.join(PROGRAMFILES, "Carla"),) @@ -434,17 +446,19 @@ else: for path in CARLA_PATH: if os.path.exists(os.path.join(path, "carla", carla_libname)): - carla_library_path = os.path.join(path, "carla", carla_libname) + carla_library_filename = os.path.join(path, "carla", carla_libname) break + del CARLA_PATH + # find tool -def findTool(tdir, tname): - if os.path.exists(os.path.join(CWD, tdir, tname)): - return os.path.join(CWD, tdir, tname) +def findTool(toolDir, toolName): + if os.path.exists(os.path.join(CWD, toolDir, toolName)): + return os.path.join(CWD, toolDir, toolName) for p in PATH: - if os.path.exists(os.path.join(p, tname)): - return os.path.join(p, tname) + if os.path.exists(os.path.join(p, toolName)): + return os.path.join(p, toolName) return "" @@ -463,6 +477,9 @@ if not WINDOWS: carla_bridge_posix32 = findTool("bridges", "carla-bridge-posix32") carla_bridge_posix64 = findTool("bridges", "carla-bridge-posix64") +# find generic tools +carla_bridge_lv2_external = findTool("bridges", "carla-bridge-lv2-external") + # find windows only tools if WINDOWS: carla_bridge_lv2_windows = findTool("bridges", "carla-bridge-lv2-windows.exe") @@ -471,9 +488,9 @@ if WINDOWS: # find mac os only tools elif MACOS: carla_bridge_lv2_cocoa = findTool("bridges", "carla-bridge-lv2-cocoa") - carla_bridge_vst_cocoa = findTool("bridges", "carla-bridge-vst-cocoa") + carla_bridge_vst_mac = findTool("bridges", "carla-bridge-vst-mac") -# find generic tools +# find other tools else: carla_bridge_lv2_gtk2 = findTool("bridges", "carla-bridge-lv2-gtk2") carla_bridge_lv2_gtk3 = findTool("bridges", "carla-bridge-lv2-gtk3") @@ -528,15 +545,16 @@ def signalHandler(sig, frame): if sig in (SIGINT, SIGTERM): Carla.gui.emit(SIGNAL("SIGTERM()")) - elif sig == SIGUSR1: + elif haveSIGUSR1 and sig == SIGUSR1: Carla.gui.emit(SIGNAL("SIGUSR1()")) def setUpSignals(): - if not haveSignal: - return - signal(SIGINT, signalHandler) signal(SIGTERM, signalHandler) + + if haveSIGUSR1: + return + signal(SIGUSR1, signalHandler) # ------------------------------------------------------------------------------------------------------------ @@ -564,7 +582,7 @@ def CustomMessageBox(self_, icon, title, text, extraText="", buttons=QMessageBox # ------------------------------------------------------------------------------------------------------------ # Plugin Query (helper functions) -def findBinaries(bPATH, OS): +def findBinaries(binPath, OS): binaries = [] if OS == "WINDOWS": @@ -574,25 +592,36 @@ def findBinaries(bPATH, OS): else: extensions = (".so",) - for root, dirs, files in os.walk(bPATH): + for root, dirs, files in os.walk(binPath): for name in [name for name in files if name.lower().endswith(extensions)]: binaries.append(os.path.join(root, name)) return binaries -def findLV2Bundles(bPATH): +def findLV2Bundles(bundlePath): bundles = [] - for root, dirs, files in os.walk(bPATH): + for root, dirs, files in os.walk(bundlePath): if os.path.exists(os.path.join(root, "manifest.ttl")): bundles.append(root) return bundles -def findSoundKits(bPATH, stype): - soundfonts = [] +def findMacVSTBundles(bundlePath): + bundles = [] + + for root, dirs, files in os.walk(bundlePath): + for name in [name for name in dirs if name.lower().endswith(".vst")]: + bundles.append(os.path.join(root, name)) + + return bundles + +def findFilenames(filePath, stype): + filenames = [] - if stype == "gig": + if stype == "csound": + extensions = (".csnd",) + elif stype == "gig": extensions = (".gig",) elif stype == "sf2": extensions = (".sf2",) @@ -601,12 +630,13 @@ def findSoundKits(bPATH, stype): else: return [] - for root, dirs, files in os.walk(bPATH): + for root, dirs, files in os.walk(filePath): for name in [name for name in files if name.lower().endswith(extensions)]: - soundfonts.append(os.path.join(root, name)) + filenames.append(os.path.join(root, name)) - return soundfonts + return filenames +# FIXME - put this into c++ discovery def findDSSIGUI(filename, name, label): pluginDir = filename.rsplit(".", 1)[0] shortName = os.path.basename(pluginDir) @@ -627,7 +657,7 @@ def findDSSIGUI(filename, name, label): guiFiles = [] for guiFile in guiFiles: - if guiFile.startswith(checkName) or guiFile.startswith(checkLabel) or guiFile.startswith(checkSName): + if guiFile.startswith((checkName, checkLabel, checkSName)): guiFilename = os.path.join(pluginDir, guiFile) break @@ -661,9 +691,14 @@ PyPluginInfo = { 'programs.total': 0 } +global discoveryProcess +discoveryProcess = None + def runCarlaDiscovery(itype, stype, filename, tool, isWine=False): - fakeLabel = os.path.basename(filename).rsplit(".", 1)[0] - plugins = [] + if not os.path.exists(tool): + qCritical("runCarlaDiscovery() - tool '%s' does not exist" % tool) + return + command = [] if LINUX or MACOS: @@ -676,26 +711,30 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False): command.append(stype) command.append(filename) - Ps = Popen(command, stdout=PIPE) + global discoveryProcess + discoveryProcess = Popen(command, stdout=PIPE) try: - Ps.wait() - output = Ps.stdout.read().decode("utf-8", errors="ignore").split("\n") + discoveryProcess.wait() + output = discoveryProcess.stdout.read().decode("utf-8", errors="ignore").split("\n") except: - output = "" + output = () pinfo = None + plugins = [] + fakeLabel = os.path.basename(filename).rsplit(".", 1)[0] for line in output: line = line.strip() if line == "carla-discovery::init::-----------": pinfo = deepcopy(PyPluginInfo) - pinfo['type'] = itype + pinfo['type'] = itype pinfo['binary'] = filename elif line == "carla-discovery::end::------------": if pinfo != None: plugins.append(pinfo) + del pinfo pinfo = None elif line == "Segmentation fault": @@ -711,11 +750,14 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False): if pinfo == None: continue - prop, value = line.replace("carla-discovery::", "").split("::", 1) + try: + prop, value = line.replace("carla-discovery::", "").split("::", 1) + except: + continue if prop == "name": pinfo['name'] = value if value else fakeLabel - elif prop in ("label", "uri"): + elif prop == "label": pinfo['label'] = value if value else fakeLabel elif prop == "maker": pinfo['maker'] = value @@ -747,15 +789,32 @@ def runCarlaDiscovery(itype, stype, filename, tool, isWine=False): if value.isdigit(): pinfo['programs.total'] = int(value) elif prop == "build": if value.isdigit(): pinfo['build'] = int(value) + elif prop == "uri": + if value: pinfo['label'] = value + else: + # cannot use empty URIs + del pinfo + pinfo = None + continue - # Additional checks + # FIXME - put this into c++ discovery for pinfo in plugins: if itype == PLUGIN_DSSI: if findDSSIGUI(pinfo['binary'], pinfo['name'], pinfo['label']): pinfo['hints'] |= PLUGIN_HAS_GUI + tmp = discoveryProcess + discoveryProcess = None + del discoveryProcess, tmp + return plugins +def killDiscovery(): + global discoveryProcess + + if discoveryProcess is not None: + discoveryProcess.kill() + def checkPluginInternal(desc): plugins = [] @@ -796,6 +855,12 @@ def checkPluginLV2(filename, tool, isWine=False): def checkPluginVST(filename, tool, isWine=False): return runCarlaDiscovery(PLUGIN_VST, "VST", filename, tool, isWine) +def checkPluginAU(filename, tool): + return runCarlaDiscovery(PLUGIN_AU, "AU", filename, tool) + +def checkPluginCSOUND(filename, tool): + return runCarlaDiscovery(PLUGIN_CSOUND, "CSOUND", filename, tool) + def checkPluginGIG(filename, tool): return runCarlaDiscovery(PLUGIN_GIG, "GIG", filename, tool) diff --git a/source/ladspa_rdf.py b/source/ladspa_rdf.py index 3b6a82721..510a37e1e 100644 --- a/source/ladspa_rdf.py +++ b/source/ladspa_rdf.py @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------- # C types diff --git a/source/modules/widgets/digitalpeakmeter.py b/source/modules/widgets/digitalpeakmeter.py index 02b370dd4..8f049fa32 100644 --- a/source/modules/widgets/digitalpeakmeter.py +++ b/source/modules/widgets/digitalpeakmeter.py @@ -14,13 +14,14 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) -from PyQt4.QtCore import qCritical, Qt, QTimer, QSize -from PyQt4.QtGui import QColor, QLinearGradient, QPainter, QWidget +from PyQt5.QtCore import qCritical, Qt, QTimer, QSize +from PyQt5.QtGui import QColor, QLinearGradient, QPainter +from PyQt5.QtWidgets import QWidget # ------------------------------------------------------------------------------------------------------------ # Widget Class diff --git a/source/modules/widgets/ledbutton.py b/source/modules/widgets/ledbutton.py index 0e72ff520..48acd411c 100644 --- a/source/modules/widgets/ledbutton.py +++ b/source/modules/widgets/ledbutton.py @@ -14,13 +14,14 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) -from PyQt4.QtCore import qCritical, QRectF -from PyQt4.QtGui import QPainter, QPixmap, QPushButton +from PyQt5.QtCore import qCritical, QRectF +from PyQt5.QtGui import QPainter, QPixmap +from PyQt5.QtWidgets import QPushButton # ------------------------------------------------------------------------------------------------------------ # Widget Class diff --git a/source/modules/widgets/paramspinbox.py b/source/modules/widgets/paramspinbox.py index 553191577..191a0d76f 100644 --- a/source/modules/widgets/paramspinbox.py +++ b/source/modules/widgets/paramspinbox.py @@ -14,13 +14,16 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) -from PyQt4.QtCore import pyqtSlot, Qt, QTimer, SIGNAL, SLOT -from PyQt4.QtGui import QAbstractSpinBox, QApplication, QComboBox, QCursor, QDialog, QMenu, QProgressBar +# TODO - SIGNAL, SLOT + +from PyQt5.QtCore import pyqtSlot, Qt, QTimer +from PyQt5.QtGui import QCursor +from PyQt5.QtWidgets import QAbstractSpinBox, QApplication, QComboBox, QDialog, QMenu, QProgressBar from math import isnan # ------------------------------------------------------------------------------------------------------------ @@ -451,3 +454,13 @@ class ParamSpinBox(QAbstractSpinBox): if float(self.fBox.itemText(i).split(" - ", 1)[0]) == value: self.fBox.setCurrentIndex(i) break + +# ------------------------------------------------------------------------------------------------------------ +# TESTING + +import sys +from PyQt5.QtWidgets import QApplication +app = QApplication(sys.argv) +gui = ParamSpinBox(None) +gui.show() +app.exec_() diff --git a/source/modules/widgets/pixmapbutton.py b/source/modules/widgets/pixmapbutton.py index 15c585bc1..302d77c34 100644 --- a/source/modules/widgets/pixmapbutton.py +++ b/source/modules/widgets/pixmapbutton.py @@ -14,13 +14,14 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) -from PyQt4.QtCore import QRectF -from PyQt4.QtGui import QPainter, QPixmap, QPushButton +from PyQt5.QtCore import QRectF +from PyQt5.QtGui import QPainter, QPixmap +from PyQt5.QtWidgets import QPushButton # ------------------------------------------------------------------------------------------------------------ # Widget Class diff --git a/source/modules/widgets/pixmapdial.py b/source/modules/widgets/pixmapdial.py index 7944a66b7..f8ad45485 100644 --- a/source/modules/widgets/pixmapdial.py +++ b/source/modules/widgets/pixmapdial.py @@ -14,15 +14,18 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) +# TODO - SLOTS + from math import floor -from PyQt4.QtCore import Qt, QPointF, QRectF, QTimer, QSize, SLOT -from PyQt4.QtGui import QColor, QConicalGradient, QDial, QFont, QFontMetrics -from PyQt4.QtGui import QLinearGradient, QPainter, QPainterPath, QPen, QPixmap +from PyQt5.QtCore import Qt, QPointF, QRectF, QTimer, QSize +from PyQt5.QtGui import QColor, QConicalGradient, QFont, QFontMetrics +from PyQt5.QtGui import QLinearGradient, QPainter, QPainterPath, QPen, QPixmap +from PyQt5.QtWidgets import QDial # ------------------------------------------------------------------------------------------------------------ # Widget Class diff --git a/source/modules/widgets/pixmapkeyboard.py b/source/modules/widgets/pixmapkeyboard.py index a31683622..d2e1966a0 100644 --- a/source/modules/widgets/pixmapkeyboard.py +++ b/source/modules/widgets/pixmapkeyboard.py @@ -14,13 +14,16 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # -# For a full copy of the GNU General Public License see the GPL.txt file +# For a full copy of the GNU General Public License see the doc/GPL.txt file. # ------------------------------------------------------------------------------------------------------------ # Imports (Global) -from PyQt4.QtCore import pyqtSlot, qCritical, Qt, QPointF, QRectF, QTimer, SIGNAL, SLOT -from PyQt4.QtGui import QFont, QPainter, QPixmap, QWidget +# TODO - SIGNAL, SLOT + +from PyQt5.QtCore import pyqtSlot, qCritical, Qt, QPointF, QRectF, QTimer +from PyQt5.QtGui import QFont, QPainter, QPixmap +from PyQt5.QtWidgets import QWidget # ------------------------------------------------------------------------------------------------------------