#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Carla plugin/slot skin code # Copyright (C) 2013-2014 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) from PyQt4.QtGui import QFont, QFrame, QPushButton # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) import ui_carla_plugin_default import ui_carla_plugin_calf import ui_carla_plugin_zita import ui_carla_plugin_zynfx from carla_widgets import * from pixmapdial import PixmapDial # ------------------------------------------------------------------------------------------------------------ # Abstract plugin slot class AbstractPluginSlot(QFrame): def __init__(self, parent, pluginId): QFrame.__init__(self, parent) # ------------------------------------------------------------- # Get plugin info self.fPluginId = pluginId self.fPluginInfo = Carla.host.get_plugin_info(self.fPluginId) if Carla.host is not None else gFakePluginInfo self.fPluginInfo['filename'] = charPtrToString(self.fPluginInfo['filename']) self.fPluginInfo['name'] = charPtrToString(self.fPluginInfo['name']) self.fPluginInfo['label'] = charPtrToString(self.fPluginInfo['label']) self.fPluginInfo['maker'] = charPtrToString(self.fPluginInfo['maker']) self.fPluginInfo['copyright'] = charPtrToString(self.fPluginInfo['copyright']) self.fPluginInfo['iconName'] = charPtrToString(self.fPluginInfo['iconName']) if not Carla.isLocal: self.fPluginInfo['hints'] &= ~PLUGIN_HAS_CUSTOM_UI # ------------------------------------------------------------- # Internal stuff self.fIsActive = False self.fLastGreenLedState = False self.fLastBlueLedState = False self.fParameterIconTimer = ICON_STATE_NULL self.fParameterList = [] # index, widget if Carla.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK or Carla.host is None: self.fPeaksInputCount = 2 self.fPeaksOutputCount = 2 else: audioCountInfo = Carla.host.get_audio_port_count_info(self.fPluginId) self.fPeaksInputCount = int(audioCountInfo['ins']) self.fPeaksOutputCount = int(audioCountInfo['outs']) if self.fPeaksInputCount > 2: self.fPeaksInputCount = 2 if self.fPeaksOutputCount > 2: self.fPeaksOutputCount = 2 # ------------------------------------------------------------- # Set-up GUI self.fEditDialog = PluginEdit(self, self.fPluginId) self.fEditDialog.hide() # ------------------------------------------------------------- # Set-up common widgets (as none) self.b_enable = None self.b_gui = None self.b_edit = None self.b_remove = None self.cb_presets = None self.label_name = None self.led_control = None self.led_midi = None self.led_audio_in = None self.led_audio_out = None self.peak_in = None self.peak_out = None #------------------------------------------------------------------ def ready(self): if self.b_enable is not None: self.b_enable.clicked.connect(self.slot_enableClicked) if self.b_gui is not None: self.b_gui.clicked.connect(self.slot_showCustomUi) self.b_gui.setEnabled(bool(self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI)) if self.b_edit is None: # Edit dialog *must* be available self.b_edit = QPushButton(self) self.b_edit.setCheckable(True) self.b_edit.hide() self.b_edit.clicked.connect(self.slot_showEditDialog) if self.b_remove is not None: self.b_remove.clicked.connect(self.slot_removePlugin) if self.label_name is not None: self.label_name.setText(self.fPluginInfo['name']) if self.led_control is not None: self.led_control.setColor(self.led_control.YELLOW) self.led_control.setEnabled(False) if self.led_midi is not None: self.led_midi.setColor(self.led_midi.RED) self.led_midi.setEnabled(False) if self.led_audio_in is not None: self.led_audio_in.setColor(self.led_audio_in.GREEN) self.led_audio_in.setEnabled(False) if self.led_audio_out is not None: self.led_audio_out.setColor(self.led_audio_out.BLUE) self.led_audio_out.setEnabled(False) if self.peak_in is not None: self.peak_in.setColor(self.peak_in.GREEN) self.peak_in.setChannels(self.fPeaksInputCount) self.peak_in.setOrientation(self.peak_in.HORIZONTAL) if self.peak_out is not None: self.peak_out.setColor(self.peak_in.BLUE) self.peak_out.setChannels(self.fPeaksOutputCount) self.peak_out.setOrientation(self.peak_out.HORIZONTAL) for paramIndex, paramWidget in self.fParameterList: paramWidget.valueChanged.connect(self.slot_parameterValueChanged) paramWidget.setValue(Carla.host.get_current_parameter_value(self.fPluginId, paramIndex) * 1000) #------------------------------------------------------------------ def getFixedHeight(self): return 32 def getHints(self): return self.fPluginInfo['hints'] #------------------------------------------------------------------ def recheckPluginHints(self, hints): self.fPluginInfo['hints'] = hints if self.b_gui is not None: self.b_gui.setEnabled(bool(hints & PLUGIN_HAS_CUSTOM_UI)) def setId(self, idx): self.fPluginId = idx self.fEditDialog.setId(idx) def setName(self, name): self.fEditDialog.setName(name) if self.label_name is not None: self.label_name.setText(name) #------------------------------------------------------------------ def setActive(self, active, sendGui=False, sendCallback=True): self.fIsActive = active if sendGui: self.activeChanged(active) if sendCallback: Carla.host.set_active(self.fPluginId, active) if active: self.fEditDialog.clearNotes() self.midiActivityChanged(False) # called from rack, checks if param is possible first def setInternalParameter(self, parameterId, value): if parameterId <= PARAMETER_MAX or parameterId >= PARAMETER_NULL: return elif parameterId == PARAMETER_ACTIVE: return self.setActive(bool(value), True, True) elif parameterId == PARAMETER_DRYWET: if (self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET) == 0: return Carla.host.set_drywet(self.fPluginId, value) elif parameterId == PARAMETER_VOLUME: if (self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME) == 0: return Carla.host.set_volume(self.fPluginId, value) elif parameterId == PARAMETER_BALANCE_LEFT: if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return Carla.host.set_balance_left(self.fPluginId, value) elif parameterId == PARAMETER_BALANCE_RIGHT: if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return Carla.host.set_balance_right(self.fPluginId, value) elif parameterId == PARAMETER_PANNING: if (self.fPluginInfo['hints'] & PLUGIN_CAN_PANNING) == 0: return Carla.host.set_panning(self.fPluginId, value) elif parameterId == PARAMETER_CTRL_CHANNEL: Carla.host.set_ctrl_channel(self.fPluginId, value) self.fEditDialog.setParameterValue(parameterId, value) #------------------------------------------------------------------ def setParameterValue(self, parameterId, value, sendCallback): self.fParameterIconTimer = ICON_STATE_ON if parameterId == PARAMETER_ACTIVE: return self.setActive(bool(value), True, False) self.fEditDialog.setParameterValue(parameterId, value) if sendCallback: self.parameterValueChanged(parameterId, value) def setParameterDefault(self, parameterId, value): self.fEditDialog.setParameterDefault(parameterId, value) def setParameterMidiControl(self, parameterId, control): self.fEditDialog.setParameterMidiControl(parameterId, control) def setParameterMidiChannel(self, parameterId, channel): self.fEditDialog.setParameterMidiChannel(parameterId, channel) #------------------------------------------------------------------ def setProgram(self, index, sendCallback): self.fParameterIconTimer = ICON_STATE_ON self.fEditDialog.setProgram(index) if sendCallback: self.programChanged(index) def setMidiProgram(self, index, sendCallback): self.fParameterIconTimer = ICON_STATE_ON self.fEditDialog.setMidiProgram(index) if sendCallback: self.midiProgramChanged(index) #------------------------------------------------------------------ def sendNoteOn(self, channel, note): if self.fEditDialog.sendNoteOn(channel, note): self.midiActivityChanged(True) def sendNoteOff(self, channel, note): if self.fEditDialog.sendNoteOff(channel, note): self.midiActivityChanged(False) #------------------------------------------------------------------ def activeChanged(self, onOff): self.fIsActive = onOff if self.b_enable is None: return self.b_enable.blockSignals(True) self.b_enable.setChecked(onOff) self.b_enable.blockSignals(False) def editDialogChanged(self, visible): if self.b_edit is None: return self.b_edit.blockSignals(True) self.b_edit.setChecked(visible) self.b_edit.blockSignals(False) def customUiStateChanged(self, state): if self.b_gui is None: return self.b_gui.blockSignals(True) if state == 0: self.b_gui.setChecked(False) self.b_gui.setEnabled(True) elif state == 1: self.b_gui.setChecked(True) self.b_gui.setEnabled(True) elif state == -1: self.b_gui.setChecked(False) self.b_gui.setEnabled(False) self.b_gui.blockSignals(False) def parameterActivityChanged(self, onOff): if self.led_control is None: return self.led_control.setChecked(onOff) def midiActivityChanged(self, onOff): if self.led_midi is None: return self.led_midi.setChecked(onOff) def parameterValueChanged(self, parameterId, value): for paramIndex, paramWidget in self.fParameterList: if paramIndex != parameterId: continue paramWidget.blockSignals(True) paramWidget.setValue(value*1000) paramWidget.blockSignals(False) break def programChanged(self, index): if self.cb_presets is None: return self.cb_presets.blockSignals(True) self.cb_presets.setCurrentIndex(index) self.cb_presets.blockSignals(False) def midiProgramChanged(self, index): if self.cb_presets is None: return self.cb_presets.blockSignals(True) self.cb_presets.setCurrentIndex(index) self.cb_presets.blockSignals(False) def notePressed(self, note): pass def noteReleased(self, note): pass #------------------------------------------------------------------ def idleFast(self): # Input peaks if self.fPeaksInputCount > 0: if self.fPeaksInputCount > 1: peak1 = Carla.host.get_input_peak_value(self.fPluginId, True) peak2 = Carla.host.get_input_peak_value(self.fPluginId, False) ledState = bool(peak1 != 0.0 or peak2 != 0.0) if self.peak_in is not None: self.peak_in.displayMeter(1, peak1) self.peak_in.displayMeter(2, peak2) else: peak = Carla.host.get_input_peak_value(self.fPluginId, True) ledState = bool(peak != 0.0) if self.peak_in is not None: self.peak_in.displayMeter(1, peak) if self.fLastGreenLedState != ledState and self.led_audio_in is not None: self.fLastGreenLedState = ledState self.led_audio_in.setChecked(ledState) # Output peaks if self.fPeaksOutputCount > 0: if self.fPeaksOutputCount > 1: peak1 = Carla.host.get_output_peak_value(self.fPluginId, True) peak2 = Carla.host.get_output_peak_value(self.fPluginId, False) ledState = bool(peak1 != 0.0 or peak2 != 0.0) if self.peak_out is not None: self.peak_out.displayMeter(1, peak1) self.peak_out.displayMeter(2, peak2) else: peak = Carla.host.get_output_peak_value(self.fPluginId, True) ledState = bool(peak != 0.0) if self.peak_out is not None: self.peak_out.displayMeter(1, peak) if self.fLastBlueLedState != ledState and self.led_audio_out is not None: self.fLastBlueLedState = ledState self.led_audio_out.setChecked(ledState) def idleSlow(self): if self.fParameterIconTimer == ICON_STATE_ON: self.fParameterIconTimer = ICON_STATE_WAIT self.parameterActivityChanged(True) elif self.fParameterIconTimer == ICON_STATE_WAIT: self.fParameterIconTimer = ICON_STATE_OFF elif self.fParameterIconTimer == ICON_STATE_OFF: self.fParameterIconTimer = ICON_STATE_NULL self.parameterActivityChanged(False) self.fEditDialog.idleSlow() #------------------------------------------------------------------ def showDefaultCustomMenu(self, isEnabled, bEdit = None, bGui = None): menu = QMenu(self) actActive = menu.addAction(self.tr("Disable") if isEnabled else self.tr("Enable")) menu.addSeparator() if bEdit is not None: actEdit = menu.addAction(self.tr("Edit")) actEdit.setCheckable(True) actEdit.setChecked(bEdit.isChecked()) else: actEdit = None if bGui is not None: actGui = menu.addAction(self.tr("Show Custom UI")) actGui.setCheckable(True) actGui.setChecked(bGui.isChecked()) actGui.setEnabled(bGui.isEnabled()) else: actGui = None menu.addSeparator() actClone = menu.addAction(self.tr("Clone")) actRename = menu.addAction(self.tr("Rename...")) actRemove = menu.addAction(self.tr("Remove")) actSel = menu.exec_(QCursor.pos()) if not actSel: return if actSel == actActive: self.setActive(not isEnabled, True, True) elif actSel == actGui: bGui.click() elif actSel == actEdit: bEdit.click() elif actSel == actClone: if Carla.host is not None and not Carla.host.clone_plugin(self.fPluginId): CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"), Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) elif actSel == actRename: oldName = self.fPluginInfo['name'] newNameTry = QInputDialog.getText(self, self.tr("Rename Plugin"), self.tr("New plugin name:"), QLineEdit.Normal, oldName) if not (newNameTry[1] and newNameTry[0] and oldName != newNameTry[0]): return newName = newNameTry[0] if Carla.host is None or Carla.host.rename_plugin(self.fPluginId, newName): self.setName(newName) else: CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"), Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) elif actSel == actRemove: if Carla.host is not None and not Carla.host.remove_plugin(self.fPluginId): CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"), Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) #------------------------------------------------------------------ @pyqtSlot(bool) def slot_enableClicked(self, yesNo): self.setActive(yesNo, False, True) @pyqtSlot() def slot_showDefaultCustomMenu(self): self.showDefaultCustomMenu(self.fIsActive, self.b_edit, self.b_gui) #------------------------------------------------------------------ @pyqtSlot(bool) def slot_showCustomUi(self, show): Carla.host.show_custom_ui(self.fPluginId, show) @pyqtSlot(bool) def slot_showEditDialog(self, show): self.fEditDialog.setVisible(show) @pyqtSlot() def slot_removePlugin(self): Carla.host.remove_plugin(self.fPluginId) #------------------------------------------------------------------ @pyqtSlot(int) def slot_parameterValueChanged(self, value): index = self.sender().getIndex() value = float(value)/1000.0 Carla.host.set_parameter_value(self.fPluginId, index, value) self.setParameterValue(index, value, False) @pyqtSlot(int) def slot_programChanged(self, index): Carla.host.set_program(self.fPluginId, index) self.setProgram(index, False) @pyqtSlot(int) def slot_midiProgramChanged(self, index): Carla.host.set_midi_program(self.fPluginId, index) self.setMidiProgram(index, False) # ------------------------------------------------------------------------------------------------------------ class PluginSlot_Default(AbstractPluginSlot): def __init__(self, parent, pluginId): AbstractPluginSlot.__init__(self, parent, pluginId) self.ui = ui_carla_plugin_default.Ui_PluginWidget() self.ui.setupUi(self) # ------------------------------------------------------------- # Internal stuff if self.palette().window().color().lightness() > 100: # Light background labelColor = "333" isLight = True self.fColorTop = QColor(60, 60, 60) self.fColorBottom = QColor(47, 47, 47) self.fColorSeprtr = QColor(70, 70, 70) else: # Dark background labelColor = "BBB" isLight = False self.fColorTop = QColor(60, 60, 60) self.fColorBottom = QColor(47, 47, 47) self.fColorSeprtr = QColor(70, 70, 70) # ------------------------------------------------------------- # Set-up GUI self.setStyleSheet(""" QLabel#label_name { color: #%s; }""" % labelColor) if isLight: self.ui.b_enable.setPixmaps(":/bitmaps/button_off2.png", ":/bitmaps/button_on2.png", ":/bitmaps/button_off2.png") self.ui.b_edit.setPixmaps(":/bitmaps/button_edit2.png", ":/bitmaps/button_edit_down2.png", ":/bitmaps/button_edit_hover2.png") if self.fPluginInfo['iconName'] == "distrho": self.ui.b_gui.setPixmaps(":/bitmaps/button_distrho2.png", ":/bitmaps/button_distrho_down2.png", ":/bitmaps/button_distrho_hover2.png") elif self.fPluginInfo['iconName'] == "file": self.ui.b_gui.setPixmaps(":/bitmaps/button_file2.png", ":/bitmaps/button_file_down2.png", ":/bitmaps/button_file_hover2.png") else: self.ui.b_gui.setPixmaps(":/bitmaps/button_gui2.png", ":/bitmaps/button_gui_down2.png", ":/bitmaps/button_gui_hover2.png") else: self.ui.b_enable.setPixmaps(":/bitmaps/button_off.png", ":/bitmaps/button_on.png", ":/bitmaps/button_off.png") self.ui.b_edit.setPixmaps(":/bitmaps/button_edit.png", ":/bitmaps/button_edit_down.png", ":/bitmaps/button_edit_hover.png") if self.fPluginInfo['iconName'] == "distrho": self.ui.b_gui.setPixmaps(":/bitmaps/button_distrho.png", ":/bitmaps/button_distrho_down.png", ":/bitmaps/button_distrho_hover.png") elif self.fPluginInfo['iconName'] == "file": self.ui.b_gui.setPixmaps(":/bitmaps/button_file.png", ":/bitmaps/button_file_down.png", ":/bitmaps/button_file_hover.png") else: self.ui.b_gui.setPixmaps(":/bitmaps/button_gui.png", ":/bitmaps/button_gui_down.png", ":/bitmaps/button_gui_hover.png") # ------------------------------------------------------------- self.b_enable = self.ui.b_enable self.b_gui = self.ui.b_gui self.b_edit = self.ui.b_edit self.label_name = self.ui.label_name self.led_control = self.ui.led_control self.led_midi = self.ui.led_midi self.led_audio_in = self.ui.led_audio_in self.led_audio_out = self.ui.led_audio_out self.peak_in = self.ui.peak_in self.peak_out = self.ui.peak_out self.ready() self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) #------------------------------------------------------------------ def getFixedHeight(self): return 48 #------------------------------------------------------------------ def paintEvent(self, event): painter = QPainter(self) painter.save() areaX = self.ui.area_right.x()+7 width = self.width() height = self.height() painter.setPen(self.fColorSeprtr.lighter(110)) painter.setBrush(self.fColorBottom) painter.setRenderHint(QPainter.Antialiasing, True) # name -> leds arc path = QPainterPath() path.moveTo(areaX-20, height-4) path.cubicTo(areaX, height-5, areaX-20, 4.75, areaX, 4.75) path.lineTo(areaX, height-5) painter.drawPath(path) painter.setPen(self.fColorSeprtr) painter.setRenderHint(QPainter.Antialiasing, False) # separator lines painter.drawLine(0, height-5, areaX-20, height-5) painter.drawLine(areaX, 4, width, 4) painter.setPen(self.fColorBottom) painter.setBrush(self.fColorBottom) # top, bottom and left lines painter.drawLine(0, 0, width, 0) painter.drawRect(0, height-4, areaX, 4) painter.drawRoundedRect(areaX-20, height-5, areaX, 5, 22, 22) painter.drawLine(0, 0, 0, height) # fill the rest painter.drawRect(areaX-1, 5, width, height) # bottom 1px line painter.setPen(self.fColorSeprtr) painter.drawLine(0, height-1, width, height-1) painter.restore() AbstractPluginSlot.paintEvent(self, event) # ------------------------------------------------------------------------------------------------------------ class PluginSlot_Calf(AbstractPluginSlot): def __init__(self, parent, pluginId): AbstractPluginSlot.__init__(self, parent, pluginId) self.ui = ui_carla_plugin_calf.Ui_PluginWidget() self.ui.setupUi(self) # ------------------------------------------------------------- # Internal stuff self.fButtonFont = QFont() self.fButtonFont.setBold(False) self.fButtonFont.setPointSize(9) self.fButtonColorOn = QColor( 18, 41, 87) self.fButtonColorOff = QColor(150, 150, 150) # ------------------------------------------------------------- # Set-up GUI self.setStyleSheet(""" QLabel#label_name, QLabel#label_audio_in, QLabel#label_audio_out, QLabel#label_midi { color: black; } QFrame#PluginWidget { background-image: url(:/bitmaps/background_calf.png); background-repeat: repeat-xy; }""") self.ui.b_gui.setPixmaps(":/bitmaps/button_calf2.png", ":/bitmaps/button_calf2_down.png", ":/bitmaps/button_calf2_hover.png") self.ui.b_edit.setPixmaps(":/bitmaps/button_calf2.png", ":/bitmaps/button_calf2_down.png", ":/bitmaps/button_calf2_hover.png") self.ui.b_remove.setPixmaps(":/bitmaps/button_calf1.png", ":/bitmaps/button_calf1_down.png", ":/bitmaps/button_calf1_hover.png") self.ui.b_edit.setTopText(self.tr("Edit"), self.fButtonColorOn, self.fButtonFont) self.ui.b_remove.setTopText(self.tr("Remove"), self.fButtonColorOn, self.fButtonFont) if self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI: self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont) else: self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont) labelFont = self.ui.label_name.font() labelFont.setBold(True) labelFont.setPointSize(labelFont.pointSize()+3) self.ui.label_name.setFont(labelFont) audioCount = Carla.host.get_audio_port_count_info(self.fPluginId) if Carla.host is not None else {'ins': 2, 'outs': 2 } midiCount = Carla.host.get_midi_port_count_info(self.fPluginId) if Carla.host is not None else {'ins': 1, 'outs': 0 } if audioCount['ins'] == 0: self.ui.label_audio_in.hide() self.ui.peak_in.hide() if audioCount['outs'] > 0: self.ui.peak_out.setMinimumWidth(200) if audioCount['outs'] == 0: self.ui.label_audio_out.hide() self.ui.peak_out.hide() if midiCount['ins'] == 0: self.ui.label_midi.hide() self.ui.led_midi.hide() # ------------------------------------------------------------- self.b_gui = self.ui.b_gui self.b_edit = self.ui.b_edit self.b_remove = self.ui.b_remove self.label_name = self.ui.label_name self.led_midi = self.ui.led_midi self.peak_in = self.ui.peak_in self.peak_out = self.ui.peak_out self.ready() self.ui.led_midi.setColor(self.ui.led_midi.CALF) self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) #------------------------------------------------------------------ def getFixedHeight(self): return 75 #------------------------------------------------------------------ def recheckPluginHints(self, hints): if hints & PLUGIN_HAS_CUSTOM_UI: self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont) else: self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont) AbstractPluginSlot.recheckPluginHints(self, hints) # ------------------------------------------------------------------------------------------------------------ class PluginSlot_Zita(AbstractPluginSlot): def __init__(self, parent, pluginId): AbstractPluginSlot.__init__(self, parent, pluginId) self.ui = ui_carla_plugin_zita.Ui_PluginWidget() self.ui.setupUi(self) # ------------------------------------------------------------- # Internal stuff audioCount = Carla.host.get_audio_port_count_info(self.fPluginId) if Carla.host is not None else {'ins': 2, 'outs': 2 } # ------------------------------------------------------------- # Set-up GUI self.setMinimumWidth(640) self.setStyleSheet(""" QFrame#PluginWidget { background-color: #404040; } QWidget#w_revsect { background-image: url(:/bitmaps/zita/revsect.png); } QWidget#w_eq1sect { background-image: url(:/bitmaps/zita/eq1sect.png); } QWidget#w_eq2sect { background-image: url(:/bitmaps/zita/eq2sect.png); } QWidget#w_ambmixsect { background-image: url(:/bitmaps/zita/%s.png); } QWidget#w_redzita { background-image: url(:/bitmaps/zita/redzita.png); } """ % ("mixsect" if audioCount['outs'] == 2 else "ambsect")) # ------------------------------------------------------------- # Set-up Knobs self.fKnobDelay = PixmapDial(self, 0) self.fKnobDelay.setPixmap(6) self.fKnobDelay.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobDelay.setMinimum(0.02*1000) self.fKnobDelay.setMaximum(0.10*1000) self.fKnobXover = PixmapDial(self, 1) self.fKnobXover.setPixmap(6) self.fKnobXover.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobXover.setMinimum(50*1000) self.fKnobXover.setMaximum(1000*1000) self.fKnobRtLow = PixmapDial(self, 2) self.fKnobRtLow.setPixmap(6) self.fKnobRtLow.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobRtLow.setMinimum(1*1000) self.fKnobRtLow.setMaximum(8*1000) self.fKnobRtMid = PixmapDial(self, 3) self.fKnobRtMid.setPixmap(6) self.fKnobRtMid.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobRtMid.setMinimum(1*1000) self.fKnobRtMid.setMaximum(8*1000) self.fKnobDamping = PixmapDial(self, 4) self.fKnobDamping.setPixmap(6) self.fKnobDamping.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobDamping.setMinimum(1500*1000) self.fKnobDamping.setMaximum(24000*1000) self.fKnobEq1Freq = PixmapDial(self, 5) self.fKnobEq1Freq.setPixmap(6) self.fKnobEq1Freq.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobEq1Freq.setMinimum(40*1000) self.fKnobEq1Freq.setMaximum(10000*1000) self.fKnobEq1Gain = PixmapDial(self, 6) self.fKnobEq1Gain.setPixmap(6) self.fKnobEq1Gain.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobEq1Gain.setMinimum(-20*1000) self.fKnobEq1Gain.setMaximum(20*1000) self.fKnobEq2Freq = PixmapDial(self, 7) self.fKnobEq2Freq.setPixmap(6) self.fKnobEq2Freq.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobEq2Freq.setMinimum(40*1000) self.fKnobEq2Freq.setMaximum(10000*1000) self.fKnobEq2Gain = PixmapDial(self, 8) self.fKnobEq2Gain.setPixmap(6) self.fKnobEq2Gain.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobEq2Gain.setMinimum(-20*1000) self.fKnobEq2Gain.setMaximum(20*1000) self.fKnobMix = PixmapDial(self, 9) self.fKnobMix.setPixmap(6) self.fKnobMix.setCustomPaint(PixmapDial.CUSTOM_PAINT_ZITA) self.fKnobMix.setMinimum(0.0*1000) self.fKnobMix.setMaximum(1.0*1000) self.fParameterList.append([0, self.fKnobDelay]) self.fParameterList.append([1, self.fKnobXover]) self.fParameterList.append([2, self.fKnobRtLow]) self.fParameterList.append([3, self.fKnobRtMid]) self.fParameterList.append([4, self.fKnobDamping]) self.fParameterList.append([5, self.fKnobEq1Freq]) self.fParameterList.append([6, self.fKnobEq1Gain]) self.fParameterList.append([7, self.fKnobEq2Freq]) self.fParameterList.append([8, self.fKnobEq2Gain]) self.fParameterList.append([9, self.fKnobMix]) # ------------------------------------------------------------- self.ready() self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) #------------------------------------------------------------------ def getFixedHeight(self): return 75 def resizeEvent(self, event): self.fKnobDelay.move(self.ui.w_revsect.x()+31, 33) self.fKnobXover.move(self.ui.w_revsect.x()+93, 18) self.fKnobRtLow.move(self.ui.w_revsect.x()+148, 18) self.fKnobRtMid.move(self.ui.w_revsect.x()+208, 18) self.fKnobDamping.move(self.ui.w_revsect.x()+268, 18) self.fKnobEq1Freq.move(self.ui.w_eq1sect.x()+20, 33) self.fKnobEq1Gain.move(self.ui.w_eq1sect.x()+69, 18) self.fKnobEq2Freq.move(self.ui.w_eq2sect.x()+20, 33) self.fKnobEq2Gain.move(self.ui.w_eq2sect.x()+69, 18) self.fKnobMix.move(self.ui.w_ambmixsect.x()+24, 33) AbstractPluginSlot.resizeEvent(self, event) # ------------------------------------------------------------------------------------------------------------ class PluginSlot_ZynFX(AbstractPluginSlot): def __init__(self, parent, pluginId): AbstractPluginSlot.__init__(self, parent, pluginId) self.ui = ui_carla_plugin_zynfx.Ui_PluginWidget() self.ui.setupUi(self) # ------------------------------------------------------------- # Set-up GUI self.setStyleSheet(""" QFrame#PluginWidget { background-image: url(:/bitmaps/background_zynfx.png); background-repeat: repeat-xy; }""") self.ui.b_enable.setPixmaps(":/bitmaps/button_off.png", ":/bitmaps/button_on.png", ":/bitmaps/button_off.png") self.ui.b_edit.setPixmaps(":/bitmaps/button_edit.png", ":/bitmaps/button_edit_down.png", ":/bitmaps/button_edit_hover.png") # ------------------------------------------------------------- # Set-up parameters parameterCount = Carla.host.get_parameter_count(self.fPluginId) if Carla.host is not None else 0 index = 0 for i in range(parameterCount): paramInfo = Carla.host.get_parameter_info(self.fPluginId, i) paramData = Carla.host.get_parameter_data(self.fPluginId, i) paramRanges = Carla.host.get_parameter_ranges(self.fPluginId, i) if paramData['type'] != PARAMETER_INPUT: continue paramName = charPtrToString(paramInfo['name']) paramLow = paramName.lower() # real zyn fx plugins if self.fPluginInfo['label'] == "zynAlienWah": if i == 0: paramName = "Freq" elif i == 1: paramName = "Rnd" elif i == 2: paramName = "L type" # combobox elif i == 3: paramName = "St.df" elif i == 5: paramName = "Fb" elif i == 7: paramName = "L/R" if self.fPluginInfo['label'] == "zynChorus": if i == 0: paramName = "Freq" elif i == 1: paramName = "Rnd" elif i == 2: paramName = "L type" # combobox elif i == 3: paramName = "St.df" elif i == 6: paramName = "Fb" elif i == 7: paramName = "L/R" elif i == 8: paramName = "Flngr" # button elif i == 9: paramName = "Subst" # button elif self.fPluginInfo['label'] == "zynDistortion": if i == 0: paramName = "LRc." elif i == 4: paramName = "Neg." # button elif i == 5: paramName = "LPF" elif i == 6: paramName = "HPF" elif i == 7: paramName = "St." # button elif i == 8: paramName = "PF" # button elif self.fPluginInfo['label'] == "zynDynamicFilter": if i == 0: paramName = "Freq" elif i == 1: paramName = "Rnd" elif i == 2: paramName = "L type" # combobox elif i == 3: paramName = "St.df" elif i == 4: paramName = "LfoD" elif i == 5: paramName = "A.S." elif i == 6: paramName = "A.Inv." # button elif i == 7: paramName = "A.M." elif self.fPluginInfo['label'] == "zynEcho": if i == 1: paramName = "LRdl." elif i == 2: paramName = "LRc." elif i == 3: paramName = "Fb." elif i == 4: paramName = "Damp" elif self.fPluginInfo['label'] == "zynPhaser": if i == 0: paramName = "Freq" elif i == 1: paramName = "Rnd" elif i == 2: paramName = "L type" # combobox elif i == 3: paramName = "St.df" elif i == 5: paramName = "Fb" elif i == 7: paramName = "L/R" elif i == 8: paramName = "Subst" # button elif i == 9: paramName = "Phase" elif i == 11: paramName = "Dist" elif self.fPluginInfo['label'] == "zynReverb": if i == 2: paramName = "I.delfb" elif i == 5: paramName = "LPF" elif i == 6: paramName = "HPF" elif i == 9: paramName = "R.S." elif i == 10: paramName = "I.del" #elif paramLow.find("damp"): #paramName = "Damp" #elif paramLow.find("frequency"): #paramName = "Freq" # Cut generic names #elif paramName == "Depth": paramName = "Dpth" #elif paramName == "Feedback": paramName = "Fb" #elif paramName == "L/R Cross": #paramName = "L/R" #elif paramName == "Random": paramName = "Rnd" widget = PixmapDial(self, i) widget.setPixmap(5) widget.setLabel(paramName) widget.setCustomPaint(PixmapDial.CUSTOM_PAINT_NO_GRADIENT) widget.setSingleStep(paramRanges['step']*1000) widget.setMinimum(paramRanges['min']*1000) widget.setMaximum(paramRanges['max']*1000) if (paramData['hints'] & PARAMETER_IS_ENABLED) == 0: widget.setEnabled(False) self.ui.container.layout().insertWidget(index, widget) index += 1 self.fParameterList.append([i, widget]) # ------------------------------------------------------------- # Set-up MIDI programs midiProgramCount = Carla.host.get_midi_program_count(self.fPluginId) if Carla.host is not None else 0 if midiProgramCount > 0: self.ui.cb_presets.setEnabled(True) self.ui.label_presets.setEnabled(True) for i in range(midiProgramCount): mpData = Carla.host.get_midi_program_data(self.fPluginId, i) mpName = charPtrToString(mpData['name']) self.ui.cb_presets.addItem(mpName) self.fCurrentMidiProgram = Carla.host.get_current_midi_program_index(self.fPluginId) self.ui.cb_presets.setCurrentIndex(self.fCurrentMidiProgram) else: self.fCurrentMidiProgram = -1 self.ui.cb_presets.setEnabled(False) self.ui.cb_presets.setVisible(False) self.ui.label_presets.setEnabled(False) self.ui.label_presets.setVisible(False) # ------------------------------------------------------------- self.b_enable = self.ui.b_enable self.b_edit = self.ui.b_edit self.cb_presets = self.ui.cb_presets self.label_name = self.ui.label_name self.peak_in = self.ui.peak_in self.peak_out = self.ui.peak_out self.ready() self.peak_in.setOrientation(self.peak_in.VERTICAL) self.peak_out.setOrientation(self.peak_out.VERTICAL) self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) self.ui.cb_presets.currentIndexChanged.connect(self.slot_midiProgramChanged) #------------------------------------------------------------------ def getFixedHeight(self): return 70 # ------------------------------------------------------------------------------------------------------------ def createPluginSlot(parent, pluginId): pluginInfo = Carla.host.get_plugin_info(pluginId) pluginName = Carla.host.get_real_plugin_name(pluginId) pluginLabel = charPtrToString(pluginInfo['label']) uniqueId = int(pluginInfo['uniqueId']) #pluginMaker = charPtrToString(pluginInfo['maker']) #pluginIcon = charPtrToString(pluginInfo['iconName']) if pluginInfo['type'] == PLUGIN_INTERNAL: if pluginLabel.startswith("zyn") and pluginInfo['category'] != PLUGIN_CATEGORY_SYNTH: return PluginSlot_ZynFX(parent, pluginId) if pluginInfo['type'] == PLUGIN_LADSPA: if (pluginLabel == "zita-reverb" and uniqueId == 3701) or (pluginLabel == "zita-reverb-amb" and uniqueId == 3702): return PluginSlot_Zita(parent, pluginId) if pluginName.split(" ", 1)[0].lower() == "calf": return PluginSlot_Calf(parent, pluginId) #return PluginSlot_Pixmap(parent, pluginId) return PluginSlot_Default(parent, pluginId) # ------------------------------------------------------------------------------------------------------------ # Main Testing if __name__ == '__main__': from carla_style import CarlaApplication import resources_rc app = CarlaApplication("Carla-Skins") gui = PluginSlot_Pixmap(None, 0) #gui = PluginSlot_Calf(None, 0) #gui = PluginSlot_ZynFX(None, 0) gui.show() app.exec_() #if (self.pinfo['category'] == PLUGIN_CATEGORY_SYNTH): #self.set_plugin_widget_color(PALETTE_COLOR_WHITE) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_DELAY): #self.set_plugin_widget_color(PALETTE_COLOR_ORANGE) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_EQ): #self.set_plugin_widget_color(PALETTE_COLOR_GREEN) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_FILTER): #self.set_plugin_widget_color(PALETTE_COLOR_BLUE) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_DYNAMICS): #self.set_plugin_widget_color(PALETTE_COLOR_PINK) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_MODULATOR): #self.set_plugin_widget_color(PALETTE_COLOR_RED) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_UTILITY): #self.set_plugin_widget_color(PALETTE_COLOR_YELLOW) #elif (self.pinfo['category'] == PLUGIN_CATEGORY_OUTRO): #self.set_plugin_widget_color(PALETTE_COLOR_BROWN) #else: #self.set_plugin_widget_color(PALETTE_COLOR_NONE)