Browse Source

More python code split, add carla-mini file to quickly test things

tags/1.9.4
falkTX 12 years ago
parent
commit
e42211daab
12 changed files with 640 additions and 202 deletions
  1. +1
    -1
      source/Makefile.mk
  2. +4
    -4
      source/backend/engine/Makefile
  3. +3
    -20
      source/backend/plugin/Makefile
  4. +2
    -1
      source/backend/standalone/Makefile
  5. +255
    -0
      source/carla-mini
  6. +0
    -157
      source/carla.py
  7. +5
    -5
      source/carla_database.py
  8. +172
    -0
      source/carla_patchbay.py
  9. +183
    -0
      source/carla_rack.py
  10. +2
    -2
      source/carla_shared.py
  11. +11
    -10
      source/carla_widgets.py
  12. +2
    -2
      source/utils/CarlaDssiUtils.hpp

+ 1
- 1
source/Makefile.mk View File

@@ -52,7 +52,7 @@ endif

BUILD_C_FLAGS = $(BASE_FLAGS) -std=gnu99 $(CFLAGS)
BUILD_CXX_FLAGS = $(BASE_FLAGS) -std=gnu++0x $(CXXFLAGS)
LINK_FLAGS = $(LINK_OPTS) $(LDFLAGS)
LINK_FLAGS = $(LINK_OPTS) -Wl,--no-undefined $(LDFLAGS)

ifeq ($(MACOS),true)
# No C++11 support; force 32bit per default


+ 4
- 4
source/backend/engine/Makefile View File

@@ -16,8 +16,6 @@ ifeq ($(DEBUG),true)
BUILD_CXX_FLAGS += -D__RTAUDIO_DEBUG__ -D__RTMIDI_DEBUG__
endif

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

ifeq ($(HAVE_ALSA),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags alsa) -D__LINUX_ALSA__ -D__LINUX_ALSASEQ__
endif
@@ -84,7 +82,9 @@ HEADERS = \
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

$(TARGET): $(OBJS)
$(AR) rs $@ $^
rm -f $@
$(AR) crs $@ $^

$(TARGETp): $(OBJSp)
$(AR) rs $@ $^
rm -f $@
$(AR) crs $@ $^

+ 3
- 20
source/backend/plugin/Makefile View File

@@ -10,14 +10,6 @@ include ../Makefile.mk

BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo)

# ifeq ($(HAVE_QT4),true)
# BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore QtGui QtXml)
# else
# BUILD_CXX_FLAGS += $(shell pkg-config --cflags Qt5Core Qt5Gui Qt5Xml Qt5Widgets)
# endif

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

ifeq ($(HAVE_FLUIDSYNTH),true)
BUILD_CXX_FLAGS += $(shell pkg-config --cflags fluidsynth)
endif
@@ -30,7 +22,6 @@ endif

OBJS = \
CarlaPlugin.cpp.o \
CarlaPluginGui.cpp.o \
CarlaPluginThread.cpp.o \
BridgePlugin.cpp.o \
NativePlugin.cpp.o \
@@ -42,9 +33,6 @@ OBJS = \
FluidSynthPlugin.cpp.o \
LinuxSamplerPlugin.cpp.o

FILES = \
moc_CarlaPluginGui.cpp

TARGET = ../libcarla_plugin.a

# --------------------------------------------------------------
@@ -59,14 +47,9 @@ debug:

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

%.cpp.o: %.cpp ../CarlaBackend.hpp ../CarlaEngine.hpp ../CarlaPlugin.hpp CarlaPluginGui.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp
%.cpp.o: %.cpp ../CarlaBackend.hpp ../CarlaEngine.hpp ../CarlaPlugin.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

CarlaPluginGui.cpp.o: CarlaPluginGui.cpp moc_CarlaPluginGui.cpp CarlaPluginGui.hpp ../CarlaBackend.hpp ../CarlaEngine.hpp ../CarlaPlugin.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

moc_%.cpp: %.hpp
$(MOC) $< -DMOC_PARSING -o $@

$(TARGET): $(OBJS)
$(AR) rs $@ $^
rm -f $@
$(AR) crs $@ $^

+ 2
- 1
source/backend/standalone/Makefile View File

@@ -8,7 +8,6 @@ include ../Makefile.mk

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

BUILD_CXX_FLAGS += -I../../modules/theme
BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo)

# --------------------------------------------------------------
@@ -91,6 +90,8 @@ LIBS += ../libcarla_plugin.a
LIBS += ../../modules/carla_native.a
LIBS += ../../modules/juce_audio_basics.a
LIBS += ../../modules/juce_core.a
LIBS += ../../modules/juce_data_structures.a
LIBS += ../../modules/juce_events.a
LIBS += ../../modules/rtmempool.a

ifeq ($(CARLA_PLUGIN_SUPPORT),true)


+ 255
- 0
source/carla-mini View File

@@ -0,0 +1,255 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin host
# Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
#
# 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 GPL.txt file

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

try:
from PyQt5.QtWidgets import QApplication, QMainWindow
except:
from PyQt4.QtGui import QApplication, QMainWindow

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

from carla_database import *
from carla_rack import *

# ------------------------------------------------------------------------------------------------------------
# Main Window

class CarlaMiniW(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__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.fIdleTimerFast = self.startTimer(50)
self.fIdleTimerSlow = self.startTimer(50*2)

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)

@pyqtSlot()
def slot_pluginAdd(self):
dialog = PluginDatabaseW(self)

if not dialog.exec_():
return

btype = dialog.fRetPlugin['build']
ptype = dialog.fRetPlugin['type']
filename = dialog.fRetPlugin['binary']
label = dialog.fRetPlugin['label']

if not Carla.host.add_plugin(btype, ptype, filename, None, label, c_nullptr):
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()"))

# ------------------------------------------------------------------------------------------------------------
# --------------- main ------------------

if __name__ == '__main__':
# App initialization
app = QApplication(sys.argv)
app.setApplicationName("Carla")
app.setApplicationVersion(VERSION)
app.setOrganizationName("falkTX")
app.setWindowIcon(QIcon(":/scalable/carla.svg"))

libName = carla_library_filename
libPath = carla_library_filename.replace(carla_libname, "")

# Init backend
print("libName:", libName, ":", carla_libname)
Carla.host = Host(libName)

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()

# App-Loop
ret = app.exec_()

# Destroy GUI
tmp = Carla.gui
Carla.gui = None
del tmp

# Exit properly
sys.exit(ret)

+ 0
- 157
source/carla.py View File

@@ -28,7 +28,6 @@ from PyQt5.QtWidgets import QApplication, QDialogButtonBox, QFileSystemModel, QL
# ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff)

import patchcanvas
import ui_carla

from carla_shared import *
@@ -108,9 +107,6 @@ class CarlaMainW(QMainWindow):
self.fProjectFilename = None
self.fProjectLoading = False

self.fPluginCount = 0
self.fPluginList = []

self.fIdleTimerFast = 0
self.fIdleTimerSlow = 0

@@ -164,38 +160,6 @@ class CarlaMainW(QMainWindow):
self.ui.tabMain.setCurrentIndex(1)
self.ui.tabMain.setCurrentIndex(0)

# -------------------------------------------------------------
# Set-up Canvas

self.scene = patchcanvas.PatchScene(self, self.ui.graphicsView)
self.ui.graphicsView.setScene(self.scene)
self.ui.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.fSavedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL))
if self.fSavedSettings["Canvas/UseOpenGL"] and hasGL:
self.ui.graphicsView.setViewport(QGLWidget(self.ui.graphicsView))
self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings["Canvas/HighQualityAntialiasing"])

pOptions = patchcanvas.options_t()
pOptions.theme_name = self.fSavedSettings["Canvas/Theme"]
pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"]
pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"]
pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"]
pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"]

pFeatures = patchcanvas.features_t()
pFeatures.group_info = False
pFeatures.group_rename = False
pFeatures.port_info = False
pFeatures.port_rename = False
pFeatures.handle_group_pos = True

patchcanvas.setOptions(pOptions)
patchcanvas.setFeatures(pFeatures)
patchcanvas.init("Carla", self.scene, canvasCallback, False)

patchcanvas.setCanvasSize(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
patchcanvas.setInitialPos(DEFAULT_CANVAS_WIDTH / 2, DEFAULT_CANVAS_HEIGHT / 2)
self.ui.graphicsView.setSceneRect(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)

# -------------------------------------------------------------
# Set-up Canvas Preview

@@ -880,73 +844,6 @@ class CarlaMainW(QMainWindow):
newFrame = Carla.host.get_current_transport_frame() + 100000
Carla.host.transport_relocate(newFrame)

@pyqtSlot()
def slot_canvasArrange(self):
patchcanvas.arrange()

@pyqtSlot()
def slot_canvasRefresh(self):
patchcanvas.clear()
if Carla.host.is_engine_running():
Carla.host.patchbay_refresh()
QTimer.singleShot(1000 if self.fSavedSettings['Canvas/EyeCandy'] else 0, self.ui.miniCanvasPreview, SLOT("update()"))

@pyqtSlot()
def slot_canvasZoomFit(self):
self.scene.zoom_fit()

@pyqtSlot()
def slot_canvasZoomIn(self):
self.scene.zoom_in()

@pyqtSlot()
def slot_canvasZoomOut(self):
self.scene.zoom_out()

@pyqtSlot()
def slot_canvasZoomReset(self):
self.scene.zoom_reset()

@pyqtSlot()
def slot_canvasPrint(self):
self.scene.clearSelection()
self.fExportPrinter = QPrinter()
dialog = QPrintDialog(self.fExportPrinter, self)

if dialog.exec_():
painter = QPainter(self.fExportPrinter)
painter.save()
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
painter.restore()

@pyqtSlot()
def slot_canvasSaveImage(self):
newPath = QFileDialog.getSaveFileName(self, self.tr("Save Image"), filter=self.tr("PNG Image (*.png);;JPEG Image (*.jpg)"))

if newPath:
self.scene.clearSelection()

# FIXME - must be a better way...
if newPath.endswith((".jpg", ".jpG", ".jPG", ".JPG", ".JPg", ".Jpg")):
imgFormat = "JPG"
elif newPath.endswith((".png", ".pnG", ".pNG", ".PNG", ".PNg", ".Png")):
imgFormat = "PNG"
else:
# File-dialog may not auto-add the extension
imgFormat = "PNG"
newPath += ".png"

self.fExportImage = QImage(self.scene.sceneRect().width(), self.scene.sceneRect().height(), QImage.Format_RGB32)
painter = QPainter(self.fExportImage)
painter.save()
painter.setRenderHint(QPainter.Antialiasing) # TODO - set true, cleanup this
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
self.fExportImage.save(newPath, imgFormat, 100)
painter.restore()

@pyqtSlot()
def slot_toolbarShown(self):
self.updateInfoLabelPos()
@@ -1473,22 +1370,6 @@ class CarlaMainW(QMainWindow):
folder = diskFolders[i]
self.ui.cb_disk.addItem(os.path.basename(folder), folder)

pal1 = app.palette().base().color()
pal2 = app.palette().button().color()
col1 = "stop:0 rgb(%i, %i, %i)" % (pal1.red(), pal1.green(), pal1.blue())
col2 = "stop:1 rgb(%i, %i, %i)" % (pal2.red(), pal2.green(), pal2.blue())

self.setStyleSheet("""
QWidget#w_plugins {
background-color: qlineargradient(spread:pad,
x1:0.0, y1:0.0,
x2:0.2, y2:1.0,
%s,
%s
);
}
""" % (col1, col2))

if MACOS and not settings.value("Main/UseProTheme", True, type=bool):
self.setUnifiedTitleAndToolBarOnMac(True)

@@ -1620,44 +1501,6 @@ class CarlaMainW(QMainWindow):

QMainWindow.closeEvent(self, event)

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

def canvasCallback(action, value1, value2, valueStr):
if action == patchcanvas.ACTION_GROUP_INFO:
pass

elif action == patchcanvas.ACTION_GROUP_RENAME:
pass

elif action == patchcanvas.ACTION_GROUP_SPLIT:
groupId = value1
patchcanvas.splitGroup(groupId)
Carla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_GROUP_JOIN:
groupId = value1
patchcanvas.joinGroup(groupId)
Carla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_PORT_INFO:
pass

elif action == patchcanvas.ACTION_PORT_RENAME:
pass

elif action == patchcanvas.ACTION_PORTS_CONNECT:
portIdA = value1
portIdB = value2

if not Carla.host.patchbay_connect(portIdA, portIdB):
print("Connection failed:", cString(Carla.host.get_last_error()))

elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
connectionId = value1

if not Carla.host.patchbay_disconnect(connectionId):
print("Disconnect failed:", cString(Carla.host.get_last_error()))

def engineCallback(ptr, action, pluginId, value1, value2, value3, valueStr):
if pluginId < 0 or not Carla.gui:
return


+ 5
- 5
source/carla_database.py View File

@@ -1664,8 +1664,8 @@ class PluginDatabaseW(QDialog):
# ------------------------------------------------------------------------------------------------------------
# TESTING

from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
gui = PluginDatabaseW(None)
gui.show()
app.exec_()
#from PyQt5.QtWidgets import QApplication
#app = QApplication(sys.argv)
#gui = PluginDatabaseW(None)
#gui.show()
#app.exec_()

+ 172
- 0
source/carla_patchbay.py View File

@@ -0,0 +1,172 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla patchbay widget code
# Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
#
# 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)

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

import patchcanvas

from carla_widgets import *

# ------------------------------------------------------------------------------------------------
# Patchbay widget

class CarlaPatchbayW(QWidget):
def __init__(self, parent):
QWidget.__init__(self, parent)

# -------------------------------------------------------------
# Set-up Canvas

self.scene = patchcanvas.PatchScene(self, self.ui.graphicsView)
self.ui.graphicsView.setScene(self.scene)
self.ui.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.fSavedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL))
if self.fSavedSettings["Canvas/UseOpenGL"] and hasGL:
self.ui.graphicsView.setViewport(QGLWidget(self.ui.graphicsView))
self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings["Canvas/HighQualityAntialiasing"])

pOptions = patchcanvas.options_t()
pOptions.theme_name = self.fSavedSettings["Canvas/Theme"]
pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"]
pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"]
pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"]
pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"]

pFeatures = patchcanvas.features_t()
pFeatures.group_info = False
pFeatures.group_rename = False
pFeatures.port_info = False
pFeatures.port_rename = False
pFeatures.handle_group_pos = True

patchcanvas.setOptions(pOptions)
patchcanvas.setFeatures(pFeatures)
patchcanvas.init("Carla", self.scene, canvasCallback, False)

patchcanvas.setCanvasSize(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
patchcanvas.setInitialPos(DEFAULT_CANVAS_WIDTH / 2, DEFAULT_CANVAS_HEIGHT / 2)
self.ui.graphicsView.setSceneRect(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)

@pyqtSlot()
def slot_canvasArrange(self):
patchcanvas.arrange()

@pyqtSlot()
def slot_canvasRefresh(self):
patchcanvas.clear()
if Carla.host.is_engine_running():
Carla.host.patchbay_refresh()
QTimer.singleShot(1000 if self.fSavedSettings['Canvas/EyeCandy'] else 0, self.ui.miniCanvasPreview, SLOT("update()"))

@pyqtSlot()
def slot_canvasZoomFit(self):
self.scene.zoom_fit()

@pyqtSlot()
def slot_canvasZoomIn(self):
self.scene.zoom_in()

@pyqtSlot()
def slot_canvasZoomOut(self):
self.scene.zoom_out()

@pyqtSlot()
def slot_canvasZoomReset(self):
self.scene.zoom_reset()

@pyqtSlot()
def slot_canvasPrint(self):
self.scene.clearSelection()
self.fExportPrinter = QPrinter()
dialog = QPrintDialog(self.fExportPrinter, self)

if dialog.exec_():
painter = QPainter(self.fExportPrinter)
painter.save()
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
painter.restore()

@pyqtSlot()
def slot_canvasSaveImage(self):
newPath = QFileDialog.getSaveFileName(self, self.tr("Save Image"), filter=self.tr("PNG Image (*.png);;JPEG Image (*.jpg)"))

if newPath:
self.scene.clearSelection()

# FIXME - must be a better way...
if newPath.endswith((".jpg", ".jpG", ".jPG", ".JPG", ".JPg", ".Jpg")):
imgFormat = "JPG"
elif newPath.endswith((".png", ".pnG", ".pNG", ".PNG", ".PNg", ".Png")):
imgFormat = "PNG"
else:
# File-dialog may not auto-add the extension
imgFormat = "PNG"
newPath += ".png"

self.fExportImage = QImage(self.scene.sceneRect().width(), self.scene.sceneRect().height(), QImage.Format_RGB32)
painter = QPainter(self.fExportImage)
painter.save()
painter.setRenderHint(QPainter.Antialiasing) # TODO - set true, cleanup this
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
self.fExportImage.save(newPath, imgFormat, 100)
painter.restore()

# ------------------------------------------------------------------------------------------------
# ...

def canvasCallback(action, value1, value2, valueStr):
if action == patchcanvas.ACTION_GROUP_INFO:
pass

elif action == patchcanvas.ACTION_GROUP_RENAME:
pass

elif action == patchcanvas.ACTION_GROUP_SPLIT:
groupId = value1
patchcanvas.splitGroup(groupId)
Carla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_GROUP_JOIN:
groupId = value1
patchcanvas.joinGroup(groupId)
Carla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_PORT_INFO:
pass

elif action == patchcanvas.ACTION_PORT_RENAME:
pass

elif action == patchcanvas.ACTION_PORTS_CONNECT:
portIdA = value1
portIdB = value2

if not Carla.host.patchbay_connect(portIdA, portIdB):
print("Connection failed:", cString(Carla.host.get_last_error()))

elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
connectionId = value1

if not Carla.host.patchbay_disconnect(connectionId):
print("Disconnect failed:", cString(Carla.host.get_last_error()))

+ 183
- 0
source/carla_rack.py View File

@@ -0,0 +1,183 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla rack widget code
# Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
#
# 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.QtCore import QSize, QTimer
from PyQt5.QtWidgets import QApplication, QListWidget, QListWidgetItem
except:
from PyQt4.QtCore import QSize, QTimer
from PyQt4.QtGui import QApplication, QListWidget, QListWidgetItem

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

from carla_widgets import *

# ------------------------------------------------------------------------------------------------------------
# Rack widget item

class CarlaRackItem(QListWidgetItem):
RackItemType = QListWidgetItem.UserType + 1
StaticHeight = 32

def __init__(self, parent, pluginId):
QListWidgetItem.__init__(self, parent, self.RackItemType)

self.fWidget = PluginWidget(parent, pluginId)
self.fWidget.setFixedHeight(self.StaticHeight)

self.setSizeHint(QSize(300, self.StaticHeight))

parent.setItemWidget(self, self.fWidget)

def close(self):
self.fWidget.ui.edit_dialog.close()

def getWidget(self):
return self.fWidget

def setId(self, idx):
self.fWidget.setId(idx)

# ------------------------------------------------------------------------------------------------------------
# Rack widget

class CarlaRackW(QListWidget):
def __init__(self, parent):
QListWidget.__init__(self, parent)

# -------------------------------------------------------------
# Internal stuff

self.fPluginCount = 0
self.fPluginList = []

# -------------------------------------------------------------
# Set-up GUI stuff

self.setFixedWidth(800)
self.setSortingEnabled(False)

app = QApplication.instance()
pal1 = app.palette().base().color()
pal2 = app.palette().button().color()
col1 = "stop:0 rgb(%i, %i, %i)" % (pal1.red(), pal1.green(), pal1.blue())
col2 = "stop:1 rgb(%i, %i, %i)" % (pal2.red(), pal2.green(), pal2.blue())

self.setStyleSheet("""
QListWidget {
background-color: qlineargradient(spread:pad,
x1:0.0, y1:0.0,
x2:0.2, y2:1.0,
%s,
%s
);
}
""" % (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):
pitem = self.fPluginList[i]

if pitem is None:
break

pitem.fWidget.idleFast()

def idleSlow(self):
for i in range(self.fPluginCount):
pitem = self.fPluginList[i]

if pitem is None:
break

pitem.fWidget.idleSlow()

def addPlugin(self, pluginId):
pitem = CarlaRackItem(self, pluginId)

self.fPluginList.append(pitem)
self.fPluginCount += 1

#if not self.fProjectLoading:
#pwidget.setActive(True, True, True)

def removePlugin(self, pluginId):
if pluginId >= self.fPluginCount:
return

pitem = self.fPluginList[pluginId]
if pitem is None:
return

self.fPluginCount -= 1
self.fPluginList.pop(pluginId)

self.takeItem(pluginId)

pitem.close()
del pitem

# push all plugins 1 slot back
for i in range(pluginId, self.fPluginCount):
self.fPluginList[i].setId(i)

def removeAllPlugins(self):
while (self.takeItem(0)):
pass

for i in range(self.fPluginCount):
pitem = self.fPluginList[i]

if pitem is None:
break

pitem.close()
del pitem

self.fPluginCount = 0
self.fPluginList = []

# ------------------------------------------------------------------------------------------------------------
# TESTING

#from PyQt5.QtWidgets import QApplication
#app = QApplication(sys.argv)
#gui = CarlaRackW(None)
#gui.show()
#app.exec_()

+ 2
- 2
source/carla_shared.py View File

@@ -326,7 +326,7 @@ Carla = CarlaObject()
Carla.host = None
Carla.gui = None
Carla.isControl = False
Carla.isLocal = False
Carla.isLocal = True
Carla.processMode = PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else PROCESS_MODE_CONTINUOUS_RACK
Carla.maxParameters = MAX_DEFAULT_PARAMETERS

@@ -402,7 +402,7 @@ carla_bridge_vst_mac = ""
carla_bridge_vst_hwnd = ""
carla_bridge_vst_x11 = ""

carla_libname = "libcarla_%s" % "control" if Carla.isControl else "standalone"
carla_libname = "libcarla_%s" % ("control" if Carla.isControl else "standalone")

if WINDOWS:
carla_libname += ".dll"


+ 11
- 10
source/carla_widgets.py View File

@@ -373,6 +373,8 @@ class PluginParameter(QWidget):
# Plugin Editor (Built-in)

class PluginEdit(QDialog):
ParamsPerPage = 8

def __init__(self, parent, pluginId):
QDialog.__init__(self, Carla.gui)
self.ui = ui_carla_edit.Ui_PluginEdit()
@@ -685,7 +687,7 @@ class PluginEdit(QDialog):

paramInputList.append(parameter)

if len(paramInputList) == 10:
if len(paramInputList) == self.ParamsPerPage:
paramInputListFull.append((paramInputList, paramInputWidth))
paramInputList = []
paramInputWidth = 0
@@ -698,7 +700,7 @@ class PluginEdit(QDialog):

paramOutputList.append(parameter)

if len(paramOutputList) == 10:
if len(paramOutputList) == self.ParamsPerPage:
paramOutputListFull.append((paramOutputList, paramOutputWidth))
paramOutputList = []
paramOutputWidth = 0
@@ -1407,8 +1409,7 @@ class PluginWidget(QFrame):
self.ui.edit_dialog = PluginEdit(self, self.fPluginId)
self.ui.edit_dialog.hide()

self.setMinimumHeight(32)
self.setMaximumHeight(32)
self.setFixedHeight(32)

# -------------------------------------------------------------
# Set-up connections
@@ -1643,12 +1644,12 @@ class PluginWidget(QFrame):
# ------------------------------------------------------------------------------------------------------------
# TESTING

hasGL = True
#hasGL = True

from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
#from PyQt5.QtWidgets import QApplication
#app = QApplication(sys.argv)
#gui = PluginParameter(None, pInfo, 0, 0)
#gui = PluginEdit(None, 0)
gui = PluginWidget(None, 0)
gui.show()
app.exec_()
#gui = PluginWidget(None, 0)
#gui.show()
#app.exec_()

+ 2
- 2
source/utils/CarlaDssiUtils.hpp View File

@@ -23,8 +23,6 @@

#include "juce_core.h"

using namespace juce;

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

static inline
@@ -34,6 +32,8 @@ const char* find_dssi_ui(const char* const filename, const char* const label)
CARLA_SAFE_ASSERT_RETURN(label != nullptr, nullptr);
carla_debug("find_dssi_ui(\"%s\", \"%s\")", filename, label);

using namespace juce;

File pluginFile(filename);
File pluginDir(pluginFile.getParentDirectory().getFullPathName() + File::separatorString + pluginFile.getFileNameWithoutExtension());



Loading…
Cancel
Save