From f08a11f4f8828cbf7ae0dcf18c4798b78793a277 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 23 Sep 2013 00:09:02 +0100 Subject: [PATCH] More python code split, tweak plugin-edit window --- resources/ui/carla_driver.ui | 78 ---- resources/ui/carla_edit.ui | 839 ++++++++++++++++++++++------------- source/carla-mini | 170 +------ source/carla.py | 57 --- source/carla_host.py | 327 ++++++++++++++ source/carla_patchbay.py | 4 +- source/carla_rack.py | 15 - source/carla_settings.py | 10 +- source/carla_widgets.py | 91 ++-- 9 files changed, 923 insertions(+), 668 deletions(-) delete mode 100644 resources/ui/carla_driver.ui create mode 100644 source/carla_host.py diff --git a/resources/ui/carla_driver.ui b/resources/ui/carla_driver.ui deleted file mode 100644 index 7a553a9ea..000000000 --- a/resources/ui/carla_driver.ui +++ /dev/null @@ -1,78 +0,0 @@ - - - Dialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - 210 - 30 - 64 - 24 - - - - - - - 210 - 70 - 64 - 24 - - - - - - - 90 - 30 - 111 - 20 - - - - Preferred buffer size: - - - - - - 90 - 80 - 111 - 16 - - - - Preferred sample rate: - - - - - - 150 - 110 - 131 - 51 - - - - Show Control Panel - - - - - - diff --git a/resources/ui/carla_edit.ui b/resources/ui/carla_edit.ui index 6781c6afd..9b4d65204 100644 --- a/resources/ui/carla_edit.ui +++ b/resources/ui/carla_edit.ui @@ -6,8 +6,8 @@ 0 0 - 467 - 461 + 592 + 494 @@ -26,164 +26,28 @@ Edit - - - + + + - Settings + Control? - - - - - Force stereo (needs restart) - - - - - - - Fixed-size buffer - - - - - - - Send Control Changes - - - - - - - Send Channel Pressure - - - - - - - Send All Sound/Notes Off - - - - - - - Map Program changes - - - - - - - Use Chunks - - - - - - - Send Pitchbend - - - - - - - Send Note Aftertouch - - - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - 11 - 75 - true - - - - -Plugin Name - - - - Qt::AlignCenter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Save State - - - - :/16x16/document-save.png:/16x16/document-save.png - - - - - - - Load State - - - - :/16x16/document-open.png:/16x16/document-open.png - - - - - - - - - Setup - - + - - 0 - + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -229,96 +93,20 @@ Plugin Name - - - - 0 - 0 - - - - 0 - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Program: - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 + + + + + Qt::Horizontal - - 0 + + + 10 + 10 + - - - - - 0 - 0 - - - - MIDI Program: - - - - - - - - - - - - - - 0 - + + @@ -377,6 +165,12 @@ Plugin Name + + + 16777215 + 42 + + 0 @@ -388,16 +182,7 @@ Plugin Name 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -469,16 +254,7 @@ Plugin Name 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -521,24 +297,14 @@ Plugin Name 0 - - - - Qt::Vertical - - - - 1 - 1 - - - - Use Balance + + true + @@ -548,39 +314,504 @@ Plugin Name - - - - Qt::Vertical - - - - 1 - 1 - - - - + + + + Qt::Horizontal + + + + 10 + 10 + + + + + + + + + + + + 0 + 0 + + + + Settings + + + + + + Use Chunks + + + - + + + 0 + + + 1 + - Qt::Vertical + Qt::Horizontal + + + + + + + + 75 + true + + + + Audio: + + + + + + + Fixed-size buffer - - - 20 - 40 - + + + + + + Force stereo (needs restart) - + + + + + + 0 + + + 1 + + + Qt::Horizontal + + + + + + + + 75 + true + + + + MIDI: + + + + + + + Map Program changes + + + + + + + Send Control Changes + + + + + + + Send Channel Pressure + + + + + + + Send Note Aftertouch + + + + + + + Send Pitchbend + + + + + + + Send All Sound/Notes Off + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + 11 + 75 + true + + + + +Plugin Name + + + + Qt::AlignCenter + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + + + Qt::NoFocus + + + Save State + + + + :/16x16/document-save.png:/16x16/document-save.png + + + + + + + Qt::NoFocus + + + Load State + + + + :/16x16/document-open.png:/16x16/document-open.png + + + + + + + + 0 + 0 + + + + 0 + + + 1 + + + + + + + + 0 + 0 + + + + Program: + + + + + + + + 150 + 0 + + + + + + + + + + + + + 0 + 0 + + + + MIDI Program: + + + + + + + + 150 + 0 + + + + + + + + + + + + + + + + + 0 + 0 + + + + Information + + + + + + + + + + + + + + false + + + true + + + + + + + Label/URI: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + false + + + true + + + + + + + + + + + + + false + + + true + + + + + + + + + + + + + false + + + true + + + + + + + + + + + + + false + + + true + + + + + + + + + + + + + false + + + true + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Maker: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Copyright: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Unique ID: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -633,16 +864,7 @@ Plugin Name 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -665,6 +887,7 @@ Plugin Name 64 + tabWidget diff --git a/source/carla-mini b/source/carla-mini index 0e52b17b6..cab625de1 100644 --- a/source/carla-mini +++ b/source/carla-mini @@ -20,50 +20,39 @@ # Imports (Global) try: - from PyQt5.QtWidgets import QApplication, QMainWindow + from PyQt5.QtCore import QTimer + from PyQt5.QtWidgets import QApplication except: - from PyQt4.QtGui import QApplication, QMainWindow + from PyQt4.QtCore import QTimer + from PyQt4.QtGui import QApplication # ------------------------------------------------------------------------------------------------------------ # Imports (Custom Stuff) -from carla_database import * -from carla_rack import * +from carla_host import * +from carla_rack import CarlaRackW # ------------------------------------------------------------------------------------------------------------ # Main Window -class CarlaMiniW(QMainWindow): +class CarlaMiniW(HostWindow): def __init__(self, parent=None): - QMainWindow.__init__(self, parent) + HostWindow.__init__(self, parent) #self.ui = ui_carla.Ui_CarlaMainW() #self.ui.setupUi(self) Carla.host.engine_init("JACK", "Carla") - self.fRack = CarlaRackW(self) - self.setCentralWidget(self.fRack) + self.fContainer = CarlaRackW(self) + self.setCentralWidget(self.fContainer) - self.fIdleTimerFast = self.startTimer(50) - self.fIdleTimerSlow = self.startTimer(50*2) + self.init() QTimer.singleShot(0, self.slot_pluginAdd) def closeEvent(self, event): - self.fIdleTimerFast = 0 - self.fIdleTimerSlow = 0 Carla.host.engine_close() - QMainWindow.closeEvent(self, event) - - def timerEvent(self, event): - if event.timerId() == self.fIdleTimerFast: - Carla.host.engine_idle() - self.fRack.idleFast() - - elif event.timerId() == self.fIdleTimerSlow: - self.fRack.idleSlow() - - QMainWindow.timerEvent(self, event) + HostWindow.closeEvent(self, event) @pyqtSlot() def slot_pluginAdd(self): @@ -81,82 +70,7 @@ class CarlaMiniW(QMainWindow): CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) return - self.fRack.addPlugin(0) - -# ------------------------------------------------------------------------------------------------------------ - -def engineCallback(ptr, action, pluginId, value1, value2, value3, valueStr): - if pluginId < 0 or not Carla.gui: - return - - #if action == CALLBACK_DEBUG: - #Carla.gui.emit(SIGNAL("DebugCallback(int, int, int, double, QString)"), pluginId, value1, value2, value3, cString(valueStr)) - #elif action == CALLBACK_PLUGIN_ADDED: - #Carla.gui.emit(SIGNAL("PluginAddedCallback(int)"), pluginId) - #elif action == CALLBACK_PLUGIN_REMOVED: - #Carla.gui.emit(SIGNAL("PluginRemovedCallback(int)"), pluginId) - #elif action == CALLBACK_PLUGIN_RENAMED: - #Carla.gui.emit(SIGNAL("PluginRenamedCallback(int, QString)"), pluginId, valueStr) - #elif action == CALLBACK_PARAMETER_VALUE_CHANGED: - #Carla.gui.emit(SIGNAL("ParameterValueChangedCallback(int, int, double)"), pluginId, value1, value3) - #elif action == CALLBACK_PARAMETER_DEFAULT_CHANGED: - #Carla.gui.emit(SIGNAL("ParameterDefaultChangedCallback(int, int, double)"), pluginId, value1, value3) - #elif action == CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED: - #Carla.gui.emit(SIGNAL("ParameterMidiChannelChangedCallback(int, int, int)"), pluginId, value1, value2) - #elif action == CALLBACK_PARAMETER_MIDI_CC_CHANGED: - #Carla.gui.emit(SIGNAL("ParameterMidiCcChangedCallback(int, int, int)"), pluginId, value1, value2) - #elif action == CALLBACK_PROGRAM_CHANGED: - #Carla.gui.emit(SIGNAL("ProgramChangedCallback(int, int)"), pluginId, value1) - #elif action == CALLBACK_MIDI_PROGRAM_CHANGED: - #Carla.gui.emit(SIGNAL("MidiProgramChangedCallback(int, int)"), pluginId, value1) - #elif action == CALLBACK_NOTE_ON: - #Carla.gui.emit(SIGNAL("NoteOnCallback(int, int, int, int)"), pluginId, value1, value2, value3) - #elif action == CALLBACK_NOTE_OFF: - #Carla.gui.emit(SIGNAL("NoteOffCallback(int, int, int)"), pluginId, value1, value2) - #elif action == CALLBACK_SHOW_GUI: - #Carla.gui.emit(SIGNAL("ShowGuiCallback(int, int)"), pluginId, value1) - #elif action == CALLBACK_UPDATE: - #Carla.gui.emit(SIGNAL("UpdateCallback(int)"), pluginId) - #elif action == CALLBACK_RELOAD_INFO: - #Carla.gui.emit(SIGNAL("ReloadInfoCallback(int)"), pluginId) - #elif action == CALLBACK_RELOAD_PARAMETERS: - #Carla.gui.emit(SIGNAL("ReloadParametersCallback(int)"), pluginId) - #elif action == CALLBACK_RELOAD_PROGRAMS: - #Carla.gui.emit(SIGNAL("ReloadProgramsCallback(int)"), pluginId) - #elif action == CALLBACK_RELOAD_ALL: - #Carla.gui.emit(SIGNAL("ReloadAllCallback(int)"), pluginId) - #elif action == CALLBACK_PATCHBAY_CLIENT_ADDED: - #Carla.gui.emit(SIGNAL("PatchbayClientAddedCallback(int, int, QString)"), value1, value2, cString(valueStr)) - #elif action == CALLBACK_PATCHBAY_CLIENT_REMOVED: - #Carla.gui.emit(SIGNAL("PatchbayClientRemovedCallback(int, QString)"), value1, cString(valueStr)) - #elif action == CALLBACK_PATCHBAY_CLIENT_RENAMED: - #Carla.gui.emit(SIGNAL("PatchbayClientRenamedCallback(int, QString)"), value1, cString(valueStr)) - #elif action == CALLBACK_PATCHBAY_PORT_ADDED: - #Carla.gui.emit(SIGNAL("PatchbayPortAddedCallback(int, int, int, QString)"), value1, value2, int(value3), cString(valueStr)) - #elif action == CALLBACK_PATCHBAY_PORT_REMOVED: - #Carla.gui.emit(SIGNAL("PatchbayPortRemovedCallback(int, int, QString)"), value1, value2, cString(valueStr)) - #elif action == CALLBACK_PATCHBAY_PORT_RENAMED: - #Carla.gui.emit(SIGNAL("PatchbayPortRenamedCallback(int, int, QString)"), value1, value2, cString(valueStr)) - #elif action == CALLBACK_PATCHBAY_CONNECTION_ADDED: - #Carla.gui.emit(SIGNAL("PatchbayConnectionAddedCallback(int, int, int)"), value1, value2, value3) - #elif action == CALLBACK_PATCHBAY_CONNECTION_REMOVED: - #Carla.gui.emit(SIGNAL("PatchbayConnectionRemovedCallback(int)"), value1) - #elif action == CALLBACK_PATCHBAY_ICON_CHANGED: - #Carla.gui.emit(SIGNAL("PatchbayIconChangedCallback(int, int)"), value1, value2) - #elif action == CALLBACK_BUFFER_SIZE_CHANGED: - #Carla.gui.emit(SIGNAL("BufferSizeChangedCallback(int)"), value1) - #elif action == CALLBACK_SAMPLE_RATE_CHANGED: - #Carla.gui.emit(SIGNAL("SampleRateChangedCallback(double)"), value3) - #elif action == CALLBACK_NSM_ANNOUNCE: - #Carla.gui.emit(SIGNAL("NSM_AnnounceCallback(QString)"), cString(valueStr)) - #elif action == CALLBACK_NSM_OPEN: - #Carla.gui.emit(SIGNAL("NSM_OpenCallback(QString)"), cString(valueStr)) - #elif action == CALLBACK_NSM_SAVE: - #Carla.gui.emit(SIGNAL("NSM_SaveCallback()")) - #elif action == CALLBACK_ERROR: - #Carla.gui.emit(SIGNAL("ErrorCallback(QString)"), cString(valueStr)) - #elif action == CALLBACK_QUIT: - #Carla.gui.emit(SIGNAL("QuitCallback()")) + self.fContainer.addPlugin(0) # ------------------------------------------------------------------------------------------------------------ # --------------- main ------------------ @@ -179,67 +93,9 @@ if __name__ == '__main__': Carla.host.set_engine_option(OPTION_PROCESS_NAME, 0, "carla") Carla.host.set_engine_option(OPTION_PATH_RESOURCES, 0, libPath) - # Set bridge paths - if carla_bridge_native: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_NATIVE, 0, carla_bridge_native) - - if carla_bridge_posix32: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_POSIX32, 0, carla_bridge_posix32) - - if carla_bridge_posix64: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_POSIX64, 0, carla_bridge_posix64) - - if carla_bridge_win32: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_WIN32, 0, carla_bridge_win32) - - if carla_bridge_win64: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_WIN64, 0, carla_bridge_win64) - - if carla_bridge_lv2_external: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_EXTERNAL, 0, carla_bridge_lv2_external) - - if WINDOWS: - if carla_bridge_lv2_windows: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_WINDOWS, 0, carla_bridge_lv2_windows) - - if carla_bridge_vst_hwnd: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_VST_HWND, 0, carla_bridge_vst_hwnd) - - elif MACOS: - if carla_bridge_lv2_cocoa: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_COCOA, 0, carla_bridge_lv2_cocoa) - - if carla_bridge_vst_mac: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_VST_MAC, 0, carla_bridge_vst_mac) - - else: - if carla_bridge_lv2_gtk2: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_GTK2, 0, carla_bridge_lv2_gtk2) - - if carla_bridge_lv2_gtk3: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_GTK3, 0, carla_bridge_lv2_gtk3) - - if carla_bridge_lv2_qt4: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_QT4, 0, carla_bridge_lv2_qt4) - - if carla_bridge_lv2_qt5: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_QT5, 0, carla_bridge_lv2_qt5) - - if carla_bridge_lv2_x11: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_X11, 0, carla_bridge_lv2_x11) - - if carla_bridge_vst_x11: - Carla.host.set_engine_option(OPTION_PATH_BRIDGE_VST_X11, 0, carla_bridge_vst_x11) - # Create GUI and start engine Carla.gui = CarlaMiniW() - # Only now we're ready to handle events - Carla.host.set_engine_callback(engineCallback) - - # Set-up custom signal handling - setUpSignals() - # Show GUI Carla.gui.show() diff --git a/source/carla.py b/source/carla.py index 8b0b8c114..50c7b2d99 100755 --- a/source/carla.py +++ b/source/carla.py @@ -116,9 +116,6 @@ class CarlaMainW(QMainWindow): self.fClientName = "Carla" self.fSessionManagerName = "LADISH" if LADISH_APP_NAME else "" - self.fLadspaRdfNeedsUpdate = True - self.fLadspaRdfList = [] - # ------------------------------------------------------------- # Load Settings @@ -438,60 +435,6 @@ class CarlaMainW(QMainWindow): Carla.host.remove_all_plugins() - def getExtraStuff(self, plugin): - ptype = plugin['type'] - - if ptype == PLUGIN_LADSPA: - uniqueId = plugin['uniqueId'] - - self.loadRDFs() - - for rdfItem in self.fLadspaRdfList: - if rdfItem.UniqueID == uniqueId: - return pointer(rdfItem) - - elif ptype == PLUGIN_DSSI: - if plugin['hints'] & PLUGIN_HAS_GUI: - gui = findDSSIGUI(plugin['binary'], plugin['name'], plugin['label']) - if gui: - return gui.encode("utf-8") - - elif ptype in (PLUGIN_GIG, PLUGIN_SF2, PLUGIN_SFZ): - if plugin['name'].endswith(" (16 outputs)"): - # return a dummy non-null pointer - INTPOINTER = POINTER(c_int) - ptr = c_int(0x1) - addr = addressof(ptr) - return cast(addr, INTPOINTER) - - return c_nullptr - - def loadRDFs(self): - if not self.fLadspaRdfNeedsUpdate: - return - - self.fLadspaRdfList = [] - self.fLadspaRdfNeedsUpdate = False - - if not haveLRDF: - return - - settingsDir = os.path.join(HOME, ".config", "falkTX") - frLadspaFile = os.path.join(settingsDir, "ladspa_rdf.db") - - if os.path.exists(frLadspaFile): - frLadspa = open(frLadspaFile, 'r') - - try: - self.fLadspaRdfList = ladspa_rdf.get_c_ladspa_rdfs(json.load(frLadspa)) - except: - pass - - frLadspa.close() - - def loadRDFsNeeded(self): - self.fLadspaRdfNeedsUpdate = True - def menuTransport(self, enabled): self.ui.act_transport_play.setEnabled(enabled) self.ui.act_transport_stop.setEnabled(enabled) diff --git a/source/carla_host.py b/source/carla_host.py new file mode 100644 index 000000000..c4a18e9c1 --- /dev/null +++ b/source/carla_host.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Carla host code +# Copyright (C) 2011-2013 Filipe Coelho +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# 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 doc/GPL.txt file. + +# ------------------------------------------------------------------------------------------------------------ +# Imports (Global) + +try: + from PyQt5.QtWidgets import QMainWindow +except: + from PyQt4.QtGui import QMainWindow + +# ------------------------------------------------------------------------------------------------------------ +# Imports (Custom) + +from carla_database import * +from carla_settings import * +from carla_widgets import * + +# ------------------------------------------------------------------------------------------------------------ +# Dummy widget + +class CarlaDummyW(object): + def __init__(self, parent): + object.__init__(self) + + def addPlugin(self, pluginId): + pass + + def removePlugin(self, pluginId): + pass + + def removeAllPlugins(self): + pass + + def idleFast(self): + pass + + def idleSlow(self): + pass + +# ------------------------------------------------------------------------------------------------------------ +# Host Window + +class HostWindow(QMainWindow): + # signals + DebugCallback = pyqtSignal(int, int, int, float, str) + PluginAddedCallback = pyqtSignal(int) + PluginRemovedCallback = pyqtSignal(int) + PluginRenamedCallback = pyqtSignal(int, str) + ParameterValueChangedCallback = pyqtSignal(int, int, float) + ParameterDefaultChangedCallback = pyqtSignal(int, int, float) + ParameterMidiChannelChangedCallback = pyqtSignal(int, int, int) + ParameterMidiCcChangedCallback = pyqtSignal(int, int, int) + ProgramChangedCallback = pyqtSignal(int, int) + MidiProgramChangedCallback = pyqtSignal(int, int) + NoteOnCallback = pyqtSignal(int, int, int, int) + NoteOffCallback = pyqtSignal(int, int, int) + ShowGuiCallback = pyqtSignal(int, int) + UpdateCallback = pyqtSignal(int) + ReloadInfoCallback = pyqtSignal(int) + ReloadParametersCallback = pyqtSignal(int) + ReloadProgramsCallback = pyqtSignal(int) + ReloadAllCallback = pyqtSignal(int) + PatchbayClientAddedCallback = pyqtSignal(int, int, str) + PatchbayClientRemovedCallback = pyqtSignal(int, str) + PatchbayClientRenamedCallback = pyqtSignal(int, str) + PatchbayPortAddedCallback = pyqtSignal(int, int, int, str) + PatchbayPortRemovedCallback = pyqtSignal(int, int, str) + PatchbayPortRenamedCallback = pyqtSignal(int, int, str) + PatchbayConnectionAddedCallback = pyqtSignal(int, int, int) + PatchbayConnectionRemovedCallback = pyqtSignal(int) + PatchbayIconChangedCallback = pyqtSignal(int, int) + BufferSizeChangedCallback = pyqtSignal(int) + SampleRateChangedCallback = pyqtSignal(float) + NSM_AnnounceCallback = pyqtSignal(str) + NSM_OpenCallback = pyqtSignal(str) + NSM_SaveCallback = pyqtSignal() + ErrorCallback = pyqtSignal(str) + QuitCallback = pyqtSignal() + SIGTERM = pyqtSignal() + SIGUSR1 = pyqtSignal() + + def __init__(self, parent): + QMainWindow.__init__(self, parent) + #self.ui = ui_carla_plugin.Ui_PluginWidget() + #self.ui.setupUi(self) + + # ------------------------------------------------------------- + # Set bridge paths + + if carla_bridge_native: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_NATIVE, 0, carla_bridge_native) + + if carla_bridge_posix32: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_POSIX32, 0, carla_bridge_posix32) + + if carla_bridge_posix64: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_POSIX64, 0, carla_bridge_posix64) + + if carla_bridge_win32: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_WIN32, 0, carla_bridge_win32) + + if carla_bridge_win64: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_WIN64, 0, carla_bridge_win64) + + if carla_bridge_lv2_external: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_EXTERNAL, 0, carla_bridge_lv2_external) + + if WINDOWS: + if carla_bridge_lv2_windows: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_WINDOWS, 0, carla_bridge_lv2_windows) + + if carla_bridge_vst_hwnd: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_VST_HWND, 0, carla_bridge_vst_hwnd) + + elif MACOS: + if carla_bridge_lv2_cocoa: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_COCOA, 0, carla_bridge_lv2_cocoa) + + if carla_bridge_vst_mac: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_VST_MAC, 0, carla_bridge_vst_mac) + + else: + if carla_bridge_lv2_gtk2: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_GTK2, 0, carla_bridge_lv2_gtk2) + + if carla_bridge_lv2_gtk3: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_GTK3, 0, carla_bridge_lv2_gtk3) + + if carla_bridge_lv2_qt4: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_QT4, 0, carla_bridge_lv2_qt4) + + if carla_bridge_lv2_qt5: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_QT5, 0, carla_bridge_lv2_qt5) + + if carla_bridge_lv2_x11: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_LV2_X11, 0, carla_bridge_lv2_x11) + + if carla_bridge_vst_x11: + Carla.host.set_engine_option(OPTION_PATH_BRIDGE_VST_X11, 0, carla_bridge_vst_x11) + + # ------------------------------------------------------------- + # Set callback + + Carla.host.set_engine_callback(EngineCallback) + + # ------------------------------------------------------------- + # Set custom signal handling + + setUpSignals() + + # ------------------------------------------------------------- + # Internal stuff + + self.fIdleTimerFast = 0 + self.fIdleTimerSlow = 0 + + self.fLadspaRdfNeedsUpdate = True + self.fLadspaRdfList = [] + + self.fContainer = CarlaDummyW(self) + + # ------------------------------------------------------------- + + def getExtraStuff(self, plugin): + ptype = plugin['type'] + + if ptype == PLUGIN_LADSPA: + uniqueId = plugin['uniqueId'] + + self.maybeLoadRDFs() + + for rdfItem in self.fLadspaRdfList: + if rdfItem.UniqueID == uniqueId: + return pointer(rdfItem) + + elif ptype in (PLUGIN_GIG, PLUGIN_SF2, PLUGIN_SFZ): + if plugin['name'].lower().endswith(" (16 outputs)"): + # return a dummy non-null pointer + INTPOINTER = POINTER(c_int) + int1 = c_int(0x1) + addr = addressof(int1) + return cast(addr, INTPOINTER) + + return c_nullptr + + def maybeLoadRDFs(self): + if not self.fLadspaRdfNeedsUpdate: + return + + self.fLadspaRdfNeedsUpdate = False + self.fLadspaRdfList = [] + + if not haveLRDF: + return + + settingsDir = os.path.join(HOME, ".config", "falkTX") + frLadspaFile = os.path.join(settingsDir, "ladspa_rdf.db") + + if os.path.exists(frLadspaFile): + frLadspa = open(frLadspaFile, 'r') + + try: + self.fLadspaRdfList = ladspa_rdf.get_c_ladspa_rdfs(json.load(frLadspa)) + except: + pass + + frLadspa.close() + + def setLoadRDFsNeeded(self): + self.fLadspaRdfNeedsUpdate = True + + def init(self): + self.fIdleTimerFast = self.startTimer(50) + self.fIdleTimerSlow = self.startTimer(50*2) + + def timerEvent(self, event): + if event.timerId() == self.fIdleTimerFast: + Carla.host.engine_idle() + self.fContainer.idleFast() + + elif event.timerId() == self.fIdleTimerSlow: + self.fContainer.idleSlow() + + QMainWindow.timerEvent(self, event) + + def closeEvent(self, event): + if self.fIdleTimerFast != 0: + self.killTimer(self.fIdleTimerFast) + self.fIdleTimerFast = 0 + + if self.fIdleTimerSlow != 0: + self.killTimer(self.fIdleTimerSlow) + self.fIdleTimerSlow = 0 + + QMainWindow.closeEvent(self, event) + +# ------------------------------------------------------------------------------------------------------------ +# Engine callback + +def EngineCallback(ptr, action, pluginId, value1, value2, value3, valueStr): + if pluginId < 0 or not Carla.gui: + return + + if action == CALLBACK_DEBUG: + Carla.gui.DebugCallback.emit(pluginId, value1, value2, value3, cString(valueStr)) + elif action == CALLBACK_PLUGIN_ADDED: + Carla.gui.PluginAddedCallback.emit(pluginId) + elif action == CALLBACK_PLUGIN_REMOVED: + Carla.gui.PluginRemovedCallback.emit(pluginId) + elif action == CALLBACK_PLUGIN_RENAMED: + Carla.gui.PluginRenamedCallback.emit(pluginId, valueStr) + elif action == CALLBACK_PARAMETER_VALUE_CHANGED: + Carla.gui.ParameterValueChangedCallback.emit(pluginId, value1, value3) + elif action == CALLBACK_PARAMETER_DEFAULT_CHANGED: + Carla.gui.ParameterDefaultChangedCallback.emit(pluginId, value1, value3) + elif action == CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED: + Carla.gui.ParameterMidiChannelChangedCallback.emit(pluginId, value1, value2) + elif action == CALLBACK_PARAMETER_MIDI_CC_CHANGED: + Carla.gui.ParameterMidiCcChangedCallback.emit(pluginId, value1, value2) + elif action == CALLBACK_PROGRAM_CHANGED: + Carla.gui.ProgramChangedCallback.emit(pluginId, value1) + elif action == CALLBACK_MIDI_PROGRAM_CHANGED: + Carla.gui.MidiProgramChangedCallback.emit(pluginId, value1) + elif action == CALLBACK_NOTE_ON: + Carla.gui.NoteOnCallback.emit(pluginId, value1, value2, value3) + elif action == CALLBACK_NOTE_OFF: + Carla.gui.NoteOffCallback.emit(pluginId, value1, value2) + elif action == CALLBACK_SHOW_GUI: + Carla.gui.ShowGuiCallback.emit(pluginId, value1) + elif action == CALLBACK_UPDATE: + Carla.gui.UpdateCallback.emit(pluginId) + elif action == CALLBACK_RELOAD_INFO: + Carla.gui.ReloadInfoCallback.emit(pluginId) + elif action == CALLBACK_RELOAD_PARAMETERS: + Carla.gui.ReloadParametersCallback.emit(pluginId) + elif action == CALLBACK_RELOAD_PROGRAMS: + Carla.gui.ReloadProgramsCallback.emit(pluginId) + elif action == CALLBACK_RELOAD_ALL: + Carla.gui.ReloadAllCallback.emit(pluginId) + elif action == CALLBACK_PATCHBAY_CLIENT_ADDED: + Carla.gui.PatchbayClientAddedCallback.emit(value1, value2, cString(valueStr)) + elif action == CALLBACK_PATCHBAY_CLIENT_REMOVED: + Carla.gui.PatchbayClientRemovedCallback.emit(value1, cString(valueStr)) + elif action == CALLBACK_PATCHBAY_CLIENT_RENAMED: + Carla.gui.PatchbayClientRenamedCallback.emit(value1, cString(valueStr)) + elif action == CALLBACK_PATCHBAY_PORT_ADDED: + Carla.gui.PatchbayPortAddedCallback.emit(value1, value2, int(value3), cString(valueStr)) + elif action == CALLBACK_PATCHBAY_PORT_REMOVED: + Carla.gui.PatchbayPortRemovedCallback.emit(value1, value2, cString(valueStr)) + elif action == CALLBACK_PATCHBAY_PORT_RENAMED: + Carla.gui.PatchbayPortRenamedCallback.emit(value1, value2, cString(valueStr)) + elif action == CALLBACK_PATCHBAY_CONNECTION_ADDED: + Carla.gui.PatchbayConnectionAddedCallback.emit(value1, value2, value3) + elif action == CALLBACK_PATCHBAY_CONNECTION_REMOVED: + Carla.gui.PatchbayConnectionRemovedCallback.emit(value1) + elif action == CALLBACK_PATCHBAY_ICON_CHANGED: + Carla.gui.PatchbayIconChangedCallback.emit(value1, value2) + elif action == CALLBACK_BUFFER_SIZE_CHANGED: + Carla.gui.BufferSizeChangedCallback.emit(value1) + elif action == CALLBACK_SAMPLE_RATE_CHANGED: + Carla.gui.SampleRateChangedCallback.emit(value3) + elif action == CALLBACK_NSM_ANNOUNCE: + Carla.gui.NSM_AnnounceCallback.emit(cString(valueStr)) + elif action == CALLBACK_NSM_OPEN: + Carla.gui.NSM_OpenCallback.emit(cString(valueStr)) + elif action == CALLBACK_NSM_SAVE: + Carla.gui.NSM_SaveCallback.emit() + elif action == CALLBACK_ERROR: + Carla.gui.ErrorCallback.emit(cString(valueStr)) + elif action == CALLBACK_QUIT: + Carla.gui.QuitCallback.emit() diff --git a/source/carla_patchbay.py b/source/carla_patchbay.py index c9ec900e8..8574ed8b5 100644 --- a/source/carla_patchbay.py +++ b/source/carla_patchbay.py @@ -133,9 +133,9 @@ class CarlaPatchbayW(QWidget): painter.restore() # ------------------------------------------------------------------------------------------------ -# ... +# Canvas callback -def canvasCallback(action, value1, value2, valueStr): +def CanvasCallback(action, value1, value2, valueStr): if action == patchcanvas.ACTION_GROUP_INFO: pass diff --git a/source/carla_rack.py b/source/carla_rack.py index d11775ae5..ddca200d4 100644 --- a/source/carla_rack.py +++ b/source/carla_rack.py @@ -94,21 +94,6 @@ class CarlaRackW(QListWidget): """ % (col1, col2)) # ------------------------------------------------------------- - # TESTING - - #self.addPlugin(0) - #self.addPlugin(1) - #self.addPlugin(2) - #self.addPlugin(3) - #self.addPlugin(4) - - #self.removePlugin(3) - - #QTimer.singleShot(3000, self.testRemove) - #QTimer.singleShot(5000, self.removeAllPlugins) - - def testRemove(self): - self.removePlugin(0) def idleFast(self): for i in range(self.fPluginCount): diff --git a/source/carla_settings.py b/source/carla_settings.py index a24797c90..b9dafae7c 100644 --- a/source/carla_settings.py +++ b/source/carla_settings.py @@ -639,8 +639,8 @@ class CarlaSettingsW(QDialog): # ------------------------------------------------------------------------------------------------------------ # TESTING -from PyQt5.QtWidgets import QApplication -app = QApplication(sys.argv) -gui = CarlaSettingsW(None, True) -gui.show() -app.exec_() +#from PyQt5.QtWidgets import QApplication +#app = QApplication(sys.argv) +#gui = CarlaSettingsW(None, True) +#gui.show() +#app.exec_() diff --git a/source/carla_widgets.py b/source/carla_widgets.py index 51d5738d6..ff5d1bb18 100644 --- a/source/carla_widgets.py +++ b/source/carla_widgets.py @@ -20,11 +20,11 @@ # Imports (Global) try: - from PyQt5.QtCore import QByteArray, QSettings + from PyQt5.QtCore import pyqtSignal, pyqtSlot, QByteArray, QSettings from PyQt5.QtGui import QColor, QCursor, QFontMetrics, QPainter, QPainterPath from PyQt5.QtWidgets import QDialog, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLayout, QWidget except: - from PyQt4.QtCore import QByteArray, QSettings + from PyQt4.QtCore import pyqtSignal, pyqtSlot, QByteArray, QSettings from PyQt4.QtGui import QColor, QCursor, QFontMetrics, QPainter, QPainterPath from PyQt4.QtGui import QDialog, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLayout, QWidget @@ -424,6 +424,10 @@ class PluginEdit(QDialog): self.ui.dial_b_right.setPixmap(4) self.ui.dial_b_right.setLabel("R") + self.ui.dial_pan.setCustomPaint(self.ui.dial_b_right.CUSTOM_PAINT_CARLA_R) # FIXME + self.ui.dial_pan.setPixmap(4) + self.ui.dial_pan.setLabel("Pan") + self.ui.keyboard.setMode(self.ui.keyboard.HORIZONTAL) self.ui.keyboard.setOctaves(10) @@ -518,54 +522,47 @@ class PluginEdit(QDialog): pluginType = self.fPluginInfo['type'] pluginHints = self.fPluginInfo['hints'] - #if pluginType == PLUGIN_INTERNAL: - #self.ui.le_type.setText(self.tr("Internal")) - #elif pluginType == PLUGIN_LADSPA: - #self.ui.le_type.setText("LADSPA") - #elif pluginType == PLUGIN_DSSI: - #self.ui.le_type.setText("DSSI") - #elif pluginType == PLUGIN_LV2: - #self.ui.le_type.setText("LV2") - #elif pluginType == PLUGIN_VST: - #self.ui.le_type.setText("VST") - #elif pluginType == PLUGIN_AU: - #self.ui.le_type.setText("AU") - #elif pluginType == PLUGIN_CSOUND: - #self.ui.le_type.setText("CSOUND") - #elif pluginType == PLUGIN_GIG: - #self.ui.le_type.setText("GIG") - #elif pluginType == PLUGIN_SF2: - #self.ui.le_type.setText("SF2") - #elif pluginType == PLUGIN_SFZ: - #self.ui.le_type.setText("SFZ") - #else: - #self.ui.le_type.setText(self.tr("Unknown")) - - #self.ui.le_name.setText(pluginName) - #self.ui.le_name.setToolTip(pluginName) - #self.ui.le_label.setText(self.fPluginInfo['label']) - #self.ui.le_label.setToolTip(self.fPluginInfo['label']) - #self.ui.le_maker.setText(self.fPluginInfo['maker']) - #self.ui.le_maker.setToolTip(self.fPluginInfo['maker']) - #self.ui.le_copyright.setText(self.fPluginInfo['copyright']) - #self.ui.le_copyright.setToolTip(self.fPluginInfo['copyright']) - #self.ui.le_unique_id.setText(str(self.fPluginInfo['uniqueId'])) - #self.ui.le_unique_id.setToolTip(str(self.fPluginInfo['uniqueId'])) - #self.ui.le_ains.setText(str(audioCountInfo['ins'])) - #self.ui.le_aouts.setText(str(audioCountInfo['outs'])) - #self.ui.le_params.setText(str(paramCountInfo['ins'])) + if pluginType == PLUGIN_INTERNAL: + self.ui.le_type.setText(self.tr("Internal")) + elif pluginType == PLUGIN_LADSPA: + self.ui.le_type.setText("LADSPA") + elif pluginType == PLUGIN_DSSI: + self.ui.le_type.setText("DSSI") + elif pluginType == PLUGIN_LV2: + self.ui.le_type.setText("LV2") + elif pluginType == PLUGIN_VST: + self.ui.le_type.setText("VST") + elif pluginType == PLUGIN_AU: + self.ui.le_type.setText("AU") + elif pluginType == PLUGIN_CSOUND: + self.ui.le_type.setText("CSOUND") + elif pluginType == PLUGIN_GIG: + self.ui.le_type.setText("GIG") + elif pluginType == PLUGIN_SF2: + self.ui.le_type.setText("SF2") + elif pluginType == PLUGIN_SFZ: + self.ui.le_type.setText("SFZ") + else: + self.ui.le_type.setText(self.tr("Unknown")) + + self.ui.le_name.setText(pluginName) + self.ui.le_name.setToolTip(pluginName) + self.ui.le_label.setText(self.fPluginInfo['label']) + self.ui.le_label.setToolTip(self.fPluginInfo['label']) + self.ui.le_maker.setText(self.fPluginInfo['maker']) + self.ui.le_maker.setToolTip(self.fPluginInfo['maker']) + self.ui.le_copyright.setText(self.fPluginInfo['copyright']) + self.ui.le_copyright.setToolTip(self.fPluginInfo['copyright']) + self.ui.le_unique_id.setText(str(self.fPluginInfo['uniqueId'])) + self.ui.le_unique_id.setToolTip(str(self.fPluginInfo['uniqueId'])) self.ui.label_plugin.setText("\n%s\n" % self.fPluginInfo['name']) self.setWindowTitle(self.fPluginInfo['name']) - #if self.fPluginInfo['latency'] > 0: - #self.ui.le_latency.setText("%i samples" % self.fPluginInfo['latency']) - #else: - #self.ui.le_latency.setText(self.tr("None")) - self.ui.dial_drywet.setEnabled(pluginHints & PLUGIN_CAN_DRYWET) self.ui.dial_vol.setEnabled(pluginHints & PLUGIN_CAN_VOLUME) self.ui.dial_b_left.setEnabled(pluginHints & PLUGIN_CAN_BALANCE) self.ui.dial_b_right.setEnabled(pluginHints & PLUGIN_CAN_BALANCE) + self.ui.dial_pan.setEnabled(pluginHints & PLUGIN_CAN_PANNING) self.ui.ch_fixed_buffer.setEnabled(self.fPluginInfo['optionsAvailable'] & PLUGIN_OPTION_FIXED_BUFFERS) self.ui.ch_fixed_buffer.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_FIXED_BUFFERS) @@ -587,10 +584,10 @@ class PluginEdit(QDialog): self.ui.ch_send_all_sound_off.setChecked(self.fPluginInfo['optionsEnabled'] & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) if self.fPluginInfo['type'] != PLUGIN_VST: - self.ui.tab_programs.setCurrentIndex(1) + self.ui.sw_programs.setCurrentIndex(1) # Show/hide keyboard - showKeyboard = (self.fPluginInfo['category'] == PLUGIN_CATEGORY_SYNTH) != 0 or (midiCountInfo['ins'] > 0 < midiCountInfo['outs']) + showKeyboard = (self.fPluginInfo['category'] == PLUGIN_CATEGORY_SYNTH or midiCountInfo['ins'] > 0 < midiCountInfo['outs']) self.ui.scrollArea.setEnabled(showKeyboard) self.ui.scrollArea.setVisible(showKeyboard) @@ -807,6 +804,8 @@ class PluginEdit(QDialog): self.ui.cb_midi_programs.blockSignals(False) + self.ui.sw_programs.setEnabled(programCount > 0 or midiProgramCount > 0) + if self.fPluginInfo['type'] == PLUGIN_LV2: self.ui.b_load_state.setEnabled(programCount > 0) @@ -1264,7 +1263,7 @@ class PluginEdit(QDialog): def _updateCtrlMidiProgram(self): if self.fPluginInfo['type'] not in (PLUGIN_INTERNAL, PLUGIN_SF2): return - elif not self.fPluginInfo['hints'] & PLUGIN_IS_SYNTH: + elif self.fPluginInfo['category'] != PLUGIN_CATEGORY_SYNTH: return if self.fControlChannel < 0: