| @@ -0,0 +1,761 @@ | |||||
| #!/usr/bin/env python3 | |||||
| # -*- coding: utf-8 -*- | |||||
| # JACK Settings Dialog | |||||
| # Copyright (C) 2012 Filipe Coelho <falktx@gmail.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 COPYING file | |||||
| # Imports (Global) | |||||
| from PyQt4.QtCore import pyqtSlot, Qt, QTimer, SIGNAL, SLOT | |||||
| from PyQt4.QtGui import QDialog, QDialogButtonBox, QMessageBox | |||||
| from sys import platform | |||||
| # Imports (Custom Stuff) | |||||
| import ui_settings_jack | |||||
| # Imports (DBus) | |||||
| try: | |||||
| import dbus | |||||
| except: | |||||
| dbus = None | |||||
| # ------------------------------------------------------------- | |||||
| # global object | |||||
| global jackctl | |||||
| jackctl = None | |||||
| # enum jack_timer_type_t | |||||
| JACK_TIMER_SYSTEM_CLOCK = 0 | |||||
| JACK_TIMER_CYCLE_COUNTER = 1 | |||||
| JACK_TIMER_HPET = 2 | |||||
| # Set Platform | |||||
| if ("linux" in platform): | |||||
| LINUX = True | |||||
| else: | |||||
| LINUX = False | |||||
| # Init DBus | |||||
| def initBus(bus): | |||||
| global jackctl | |||||
| try: | |||||
| jackctl = dbus.Interface(bus.get_object("org.jackaudio.service", "/org/jackaudio/Controller"), "org.jackaudio.Configure") | |||||
| return 0 | |||||
| except: | |||||
| jackctl = None | |||||
| return 1 | |||||
| # ------------------------------------------------------------- | |||||
| # Helper functions | |||||
| def bool2str(yesno): | |||||
| return "True" if yesno else "False" | |||||
| def getBufferSize(): | |||||
| return getDriverParameter("period", -1) | |||||
| def getSampleRate(): | |||||
| return getDriverParameter("rate", -1) | |||||
| def isRealtime(): | |||||
| return getEngineParameter("realtime", False) | |||||
| def setBufferSize(bsize): | |||||
| return setDriverParameter("period", dbus.UInt32(bsize)) | |||||
| def setSampleRate(srate): | |||||
| return setDriverParameter("rate", dbus.UInt32(srate)) | |||||
| # ------------------------------------------------------------- | |||||
| # Helper functions (engine) | |||||
| def engineHasFeature(feature): | |||||
| feature_list = jackctl.ReadContainer(["engine"])[1] | |||||
| return bool(dbus.String(feature) in feature_list) | |||||
| def getEngineParameter(parameter, error): | |||||
| if (engineHasFeature(parameter) == False): | |||||
| return error | |||||
| else: | |||||
| return jackctl.GetParameterValue(["engine",parameter])[2] | |||||
| def setEngineParameter(parameter, value, optional=True): | |||||
| if (engineHasFeature(parameter) == False): | |||||
| return False | |||||
| elif (optional): | |||||
| if (value != jackctl.GetParameterValue(["engine",parameter])[2]): | |||||
| return bool(jackctl.SetParameterValue(["engine",parameter],value)) | |||||
| else: | |||||
| return False | |||||
| else: | |||||
| return bool(jackctl.SetParameterValue(["engine",parameter],value)) | |||||
| # ------------------------------------------------------------- | |||||
| # Helper functions (driver) | |||||
| def driverHasFeature(feature): | |||||
| feature_list = jackctl.ReadContainer(["driver"])[1] | |||||
| return bool(dbus.String(feature) in feature_list) | |||||
| def getDriverParameter(parameter, error): | |||||
| if (driverHasFeature(parameter) == False): | |||||
| return error | |||||
| else: | |||||
| return jackctl.GetParameterValue(["driver",parameter])[2] | |||||
| def setDriverParameter(parameter, value, optional=True): | |||||
| if (driverHasFeature(parameter) == False): | |||||
| return False | |||||
| elif (optional): | |||||
| if (value != jackctl.GetParameterValue(["driver",parameter])[2]): | |||||
| return bool(jackctl.SetParameterValue(["driver",parameter],value)) | |||||
| else: | |||||
| return False | |||||
| else: | |||||
| return bool(jackctl.SetParameterValue(["driver",parameter],value)) | |||||
| # ------------------------------------------------------------- | |||||
| # JACK Settings Dialog | |||||
| class JackSettingsW(QDialog, ui_settings_jack.Ui_JackSettingsW): | |||||
| def __init__(self, parent): | |||||
| QDialog.__init__(self, parent) | |||||
| self.setupUi(self) | |||||
| # ------------------------------------------------------------- | |||||
| # Check if we've got valid control interface | |||||
| if not jackctl: | |||||
| QTimer.singleShot(0, self, SLOT("slot_closeWithError()")) | |||||
| return | |||||
| # ------------------------------------------------------------- | |||||
| # Align driver text and hide non available ones | |||||
| driver_list = jackctl.ReadContainer(["drivers"])[1] | |||||
| for i in range(self.obj_server_driver.rowCount()): | |||||
| self.obj_server_driver.item(0, i).setTextAlignment(Qt.AlignCenter) | |||||
| if (dbus.String(self.obj_server_driver.item(0, i).text().lower()) not in driver_list): | |||||
| self.obj_server_driver.hideRow(i) | |||||
| # ------------------------------------------------------------- | |||||
| # Set-up connections | |||||
| self.connect(self, SIGNAL("accepted()"), SLOT("slot_saveJackSettings()")) | |||||
| self.connect(self.buttonBox.button(QDialogButtonBox.Reset), SIGNAL("clicked()"), SLOT("slot_resetJackSettings()")) | |||||
| self.connect(self.obj_driver_duplex, SIGNAL("clicked(bool)"), SLOT("slot_checkDuplexSelection(bool)")) | |||||
| self.connect(self.obj_server_driver, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkDriverSelection(int, int, int, int)")) | |||||
| self.connect(self.obj_driver_capture, SIGNAL("currentIndexChanged(int)"), SLOT("slot_checkALSASelection()")) | |||||
| self.connect(self.obj_driver_playback, SIGNAL("currentIndexChanged(int)"), SLOT("slot_checkALSASelection()")) | |||||
| # ------------------------------------------------------------- | |||||
| # Load initial settings | |||||
| self.m_driver = "" | |||||
| self.m_server_clock_source_broken = False | |||||
| self.checkEngine() | |||||
| self.loadServerSettings() | |||||
| self.loadDriverSettings(True) # reset because we'll change it below | |||||
| # ------------------------------------------------------------- | |||||
| # Load selected JACK driver | |||||
| self.m_driver = str(jackctl.GetParameterValue(["engine","driver"])[2]) | |||||
| for i in range(self.obj_server_driver.rowCount()): | |||||
| if (self.obj_server_driver.item(i, 0).text().lower() == self.m_driver): | |||||
| self.obj_server_driver.setCurrentCell(i, 0) | |||||
| break | |||||
| # Special ALSA check | |||||
| self.slot_checkALSASelection() | |||||
| # ------------------------------------------------------------- | |||||
| # Engine calls | |||||
| def checkEngine(self): | |||||
| self.obj_server_name.setEnabled(engineHasFeature("name")) | |||||
| self.obj_server_realtime.setEnabled(engineHasFeature("realtime")) | |||||
| self.obj_server_realtime_priority.setEnabled(engineHasFeature("realtime-priority")) | |||||
| self.obj_server_temporary.setEnabled(engineHasFeature("temporary")) | |||||
| self.obj_server_verbose.setEnabled(engineHasFeature("verbose")) | |||||
| self.obj_server_client_timeout.setEnabled(engineHasFeature("client-timeout")) | |||||
| self.obj_server_clock_source.setEnabled(engineHasFeature("clock-source")) | |||||
| self.obj_server_port_max.setEnabled(engineHasFeature("port-max")) | |||||
| self.obj_server_replace_registry.setEnabled(engineHasFeature("replace-registry")) | |||||
| self.obj_server_sync.setEnabled(engineHasFeature("sync")) | |||||
| self.obj_server_self_connect_mode.setEnabled(engineHasFeature("self-connect-mode")) | |||||
| # Disable clock-source if not on Linux | |||||
| if (LINUX == False): | |||||
| self.obj_server_clock_source.setEnabled(False) | |||||
| # ------------------------------------------------------------- | |||||
| # Server calls | |||||
| def saveServerSettings(self): | |||||
| if (self.obj_server_name.isEnabled()): | |||||
| value = dbus.String(self.obj_server_name.text()) | |||||
| setEngineParameter("name", value, True) | |||||
| if (self.obj_server_realtime.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_server_realtime.isChecked()) | |||||
| setEngineParameter("realtime", value, True) | |||||
| if (self.obj_server_realtime_priority.isEnabled()): | |||||
| value = dbus.Int32(self.obj_server_realtime_priority.value()) | |||||
| setEngineParameter("realtime-priority", value, True) | |||||
| if (self.obj_server_temporary.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_server_temporary.isChecked()) | |||||
| setEngineParameter("temporary", value, True) | |||||
| if (self.obj_server_verbose.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_server_verbose.isChecked()) | |||||
| setEngineParameter("verbose", value, True) | |||||
| if (self.obj_server_client_timeout.isEnabled()): | |||||
| value = dbus.Int32(int(self.obj_server_client_timeout.currentText())) | |||||
| setEngineParameter("client-timeout", value, True) | |||||
| if (self.obj_server_clock_source.isEnabled() or 1): | |||||
| value = None | |||||
| if (self.obj_server_clock_source_system.isChecked()): | |||||
| if (self.m_server_clock_source_broken): | |||||
| value = dbus.UInt32(JACK_TIMER_SYSTEM_CLOCK) | |||||
| else: | |||||
| value = dbus.Byte("s".encode("ascii")) | |||||
| elif (self.obj_server_clock_source_cycle.isChecked()): | |||||
| if (self.m_server_clock_source_broken): | |||||
| value = dbus.UInt32(JACK_TIMER_CYCLE_COUNTER) | |||||
| else: | |||||
| value = dbus.Byte("c".encode("ascii")) | |||||
| elif (self.obj_server_clock_source_hpet.isChecked()): | |||||
| if (self.m_server_clock_source_broken): | |||||
| value = dbus.UInt32(JACK_TIMER_HPET) | |||||
| else: | |||||
| value = dbus.Byte("h".encode("ascii")) | |||||
| else: | |||||
| value = None | |||||
| print("JackSettings::saveServerSettings() - Cannot save clock-source value") | |||||
| if (value != None): | |||||
| setEngineParameter("clock-source", value, True) | |||||
| if (self.obj_server_port_max.isEnabled()): | |||||
| value = dbus.UInt32(int(self.obj_server_port_max.currentText())) | |||||
| setEngineParameter("port-max", value, True) | |||||
| if (self.obj_server_replace_registry.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_server_replace_registry.isChecked()) | |||||
| setEngineParameter("replace-registry", value, True) | |||||
| if (self.obj_server_sync.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_server_sync.isChecked()) | |||||
| setEngineParameter("sync", value, True) | |||||
| if (self.obj_server_self_connect_mode.isEnabled()): | |||||
| if (self.obj_server_self_connect_mode_0.isChecked()): | |||||
| value = dbus.Byte(" ".encode("ascii")) | |||||
| elif (self.obj_server_self_connect_mode_1.isChecked()): | |||||
| value = dbus.Byte("E".encode("ascii")) | |||||
| elif (self.obj_server_self_connect_mode_2.isChecked()): | |||||
| value = dbus.Byte("e".encode("ascii")) | |||||
| elif (self.obj_server_self_connect_mode_3.isChecked()): | |||||
| value = dbus.Byte("A".encode("ascii")) | |||||
| elif (self.obj_server_self_connect_mode_4.isChecked()): | |||||
| value = dbus.Byte("a".encode("ascii")) | |||||
| else: | |||||
| value = None | |||||
| print("JackSettings::saveServerSettings() - Cannot save self-connect-mode value") | |||||
| if (value != None): | |||||
| setEngineParameter("self-connect-mode", value, True) | |||||
| def loadServerSettings(self, reset=False, forceReset=False): | |||||
| settings = jackctl.ReadContainer(["engine"]) | |||||
| for i in range(len(settings[1])): | |||||
| attribute = str(settings[1][i]) | |||||
| if (reset): | |||||
| value = jackctl.GetParameterValue(["engine",attribute])[1] | |||||
| if (forceReset and attribute != "driver"): | |||||
| jackctl.ResetParameterValue(["engine",attribute]) | |||||
| else: | |||||
| value = jackctl.GetParameterValue(["engine",attribute])[2] | |||||
| if (attribute == "name"): | |||||
| self.obj_server_name.setText(str(value)) | |||||
| elif (attribute == "realtime"): | |||||
| self.obj_server_realtime.setChecked(bool(value)) | |||||
| elif (attribute == "realtime-priority"): | |||||
| self.obj_server_realtime_priority.setValue(int(value)) | |||||
| elif (attribute == "temporary"): | |||||
| self.obj_server_temporary.setChecked(bool(value)) | |||||
| elif (attribute == "verbose"): | |||||
| self.obj_server_verbose.setChecked(bool(value)) | |||||
| elif (attribute == "client-timeout"): | |||||
| self.setComboBoxValue(self.obj_server_client_timeout, str(value)) | |||||
| elif (attribute == "clock-source"): | |||||
| value = str(value) | |||||
| if (value == "c"): | |||||
| self.obj_server_clock_source_cycle.setChecked(True) | |||||
| elif (value == "h"): | |||||
| self.obj_server_clock_source_hpet.setChecked(True) | |||||
| elif (value == "s"): | |||||
| self.obj_server_clock_source_system.setChecked(True) | |||||
| else: | |||||
| self.m_server_clock_source_broken = True | |||||
| if (value == str(JACK_TIMER_SYSTEM_CLOCK)): | |||||
| self.obj_server_clock_source_system.setChecked(True) | |||||
| elif (value == str(JACK_TIMER_CYCLE_COUNTER)): | |||||
| self.obj_server_clock_source_cycle.setChecked(True) | |||||
| elif (value == str(JACK_TIMER_HPET)): | |||||
| self.obj_server_clock_source_hpet.setChecked(True) | |||||
| else: | |||||
| self.obj_server_clock_source.setEnabled(False) | |||||
| print("JackSettings::saveServerSettings() - Invalid clock-source value '%s'" % (value)) | |||||
| elif (attribute == "port-max"): | |||||
| self.setComboBoxValue(self.obj_server_port_max, str(value)) | |||||
| elif (attribute == "replace-registry"): | |||||
| self.obj_server_replace_registry.setChecked(bool(value)) | |||||
| elif (attribute == "sync"): | |||||
| self.obj_server_sync.setChecked(bool(value)) | |||||
| elif (attribute == "self-connect-mode"): | |||||
| value = str(value) | |||||
| if (value == " "): | |||||
| self.obj_server_self_connect_mode_0.setChecked(True) | |||||
| elif (value == "E"): | |||||
| self.obj_server_self_connect_mode_1.setChecked(True) | |||||
| elif (value == "e"): | |||||
| self.obj_server_self_connect_mode_2.setChecked(True) | |||||
| elif (value == "A"): | |||||
| self.obj_server_self_connect_mode_3.setChecked(True) | |||||
| elif (value == "a"): | |||||
| self.obj_server_self_connect_mode_4.setChecked(True) | |||||
| else: | |||||
| self.obj_server_self_connect_mode.setEnabled(False) | |||||
| print("JackSettings::loadServerSettings() - Invalid self-connect-mode value '%s'" % (value)) | |||||
| elif (attribute in ("driver", "slave-drivers")): | |||||
| pass | |||||
| else: | |||||
| print("JackSettings::loadServerSettings() - Unimplemented server attribute '%s', value: '%s'" % (attribute, str(value))) | |||||
| # ------------------------------------------------------------- | |||||
| # Driver calls | |||||
| def saveDriverSettings(self): | |||||
| if (self.obj_driver_device.isEnabled()): | |||||
| value = dbus.String(self.obj_driver_device.currentText().split(" ")[0]) | |||||
| if (value != jackctl.GetParameterValue(["driver", "device"])[2]): | |||||
| jackctl.SetParameterValue(["driver", "device"], value) | |||||
| if (self.obj_driver_capture.isEnabled()): | |||||
| if (self.m_driver == "alsa"): | |||||
| value = dbus.String(self.obj_driver_capture.currentText().split(" ")[0]) | |||||
| elif (self.m_driver == "dummy"): | |||||
| value = dbus.UInt32(int(self.obj_driver_capture.currentText())) | |||||
| elif (self.m_driver == "firewire"): | |||||
| value = dbus.Boolean(self.obj_driver_capture.currentIndex() == 1) | |||||
| else: | |||||
| value = None | |||||
| print("JackSettings::saveDriverSettings() - Cannot save capture value") | |||||
| if (value != None): | |||||
| setDriverParameter("capture", value, True) | |||||
| if (self.obj_driver_playback.isEnabled()): | |||||
| if (self.m_driver == "alsa"): | |||||
| value = dbus.String(self.obj_driver_playback.currentText().split(" ")[0]) | |||||
| elif (self.m_driver == "dummy"): | |||||
| value = dbus.UInt32(int(self.obj_driver_playback.currentText())) | |||||
| elif (self.m_driver == "firewire"): | |||||
| value = dbus.Boolean(self.obj_driver_playback.currentIndex() == 1) | |||||
| else: | |||||
| value = None | |||||
| print("JackSettings::saveDriverSettings() - Cannot save playback value") | |||||
| if (value != None): | |||||
| setDriverParameter("playback", value, True) | |||||
| if (self.obj_driver_rate.isEnabled()): | |||||
| value = dbus.UInt32(int(self.obj_driver_rate.currentText())) | |||||
| setDriverParameter("rate", value, True) | |||||
| if (self.obj_driver_period.isEnabled()): | |||||
| value = dbus.UInt32(int(self.obj_driver_period.currentText())) | |||||
| setDriverParameter("period", value, True) | |||||
| if (self.obj_driver_nperiods.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_nperiods.value()) | |||||
| setDriverParameter("nperiods", value, True) | |||||
| if (self.obj_driver_hwmon.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_hwmon.isChecked()) | |||||
| setDriverParameter("hwmon", value, True) | |||||
| if (self.obj_driver_hwmeter.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_hwmeter.isChecked()) | |||||
| setDriverParameter("hwmeter", value, True) | |||||
| if (self.obj_driver_duplex.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_duplex.isChecked()) | |||||
| setDriverParameter("duplex", value, True) | |||||
| if (self.obj_driver_softmode.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_softmode.isChecked()) | |||||
| setDriverParameter("softmode", value, True) | |||||
| if (self.obj_driver_monitor.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_monitor.isChecked()) | |||||
| setDriverParameter("monitor", value, True) | |||||
| if (self.obj_driver_dither.isEnabled()): | |||||
| if (self.obj_driver_dither.currentIndex() == 0): | |||||
| value = dbus.Byte("n".encode("ascii")) | |||||
| elif (self.obj_driver_dither.currentIndex() == 1): | |||||
| value = dbus.Byte("r".encode("ascii")) | |||||
| elif (self.obj_driver_dither.currentIndex() == 2): | |||||
| value = dbus.Byte("s".encode("ascii")) | |||||
| elif (self.obj_driver_dither.currentIndex() == 3): | |||||
| value = dbus.Byte("t".encode("ascii")) | |||||
| else: | |||||
| value = None | |||||
| print("JackSettings::saveDriverSettings() - Cannot save dither value") | |||||
| if (value != None): | |||||
| setDriverParameter("dither", value, True) | |||||
| if (self.obj_driver_inchannels.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_inchannels.value()) | |||||
| setDriverParameter("inchannels", value, True) | |||||
| if (self.obj_driver_outchannels.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_outchannels.value()) | |||||
| setDriverParameter("outchannels", value, True) | |||||
| if (self.obj_driver_shorts.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_shorts.isChecked()) | |||||
| setDriverParameter("shorts", value, True) | |||||
| if (self.obj_driver_input_latency.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_input_latency.value()) | |||||
| setDriverParameter("input-latency", value, True) | |||||
| if (self.obj_driver_output_latency.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_output_latency.value()) | |||||
| setDriverParameter("output-latency", value, True) | |||||
| if (self.obj_driver_midi_driver.isEnabled()): | |||||
| if (self.obj_driver_midi_driver.currentIndex() == 0): | |||||
| value = dbus.String("none") | |||||
| elif (self.obj_driver_midi_driver.currentIndex() == 1): | |||||
| value = dbus.String("seq") | |||||
| elif (self.obj_driver_midi_driver.currentIndex() == 2): | |||||
| value = dbus.String("raw") | |||||
| else: | |||||
| value = None | |||||
| print("JackSettings::saveDriverSettings() - Cannot save midi-driver value") | |||||
| if (value != None): | |||||
| setDriverParameter("midi-driver", value, True) | |||||
| if (self.obj_driver_wait.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_wait.value()) | |||||
| setDriverParameter("wait", value, True) | |||||
| if (self.obj_driver_verbose.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_verbose.value()) | |||||
| setDriverParameter("verbose", value, True) | |||||
| if (self.obj_driver_snoop.isEnabled()): | |||||
| value = dbus.Boolean(self.obj_driver_snoop.isChecked()) | |||||
| setDriverParameter("snoop", value, True) | |||||
| if (self.obj_driver_channels.isEnabled()): | |||||
| value = dbus.UInt32(self.obj_driver_channels.value()) | |||||
| setDriverParameter("channels", value, True) | |||||
| def loadDriverSettings(self, reset=False, forceReset=False): | |||||
| settings = jackctl.ReadContainer(["driver"]) | |||||
| for i in range(len(settings[1])): | |||||
| attribute = str(settings[1][i]) | |||||
| if (reset): | |||||
| value = jackctl.GetParameterValue(["driver",attribute])[1] | |||||
| if (forceReset): | |||||
| jackctl.ResetParameterValue(["driver",attribute]) | |||||
| else: | |||||
| value = jackctl.GetParameterValue(["driver",attribute])[2] | |||||
| if (attribute == "device"): | |||||
| self.setComboBoxValue(self.obj_driver_device, str(value), True) | |||||
| elif (attribute == "capture"): | |||||
| if (self.m_driver == "firewire"): | |||||
| self.obj_driver_capture.setCurrentIndex(1 if bool(value) else 0) | |||||
| else: | |||||
| self.setComboBoxValue(self.obj_driver_capture, str(value), True) | |||||
| elif (attribute == "playback"): | |||||
| if (self.m_driver == "firewire"): | |||||
| self.obj_driver_playback.setCurrentIndex(1 if bool(value) else 0) | |||||
| else: | |||||
| self.setComboBoxValue(self.obj_driver_playback, str(value), True) | |||||
| elif (attribute == "rate"): | |||||
| self.setComboBoxValue(self.obj_driver_rate, str(value)) | |||||
| elif (attribute == "period"): | |||||
| self.setComboBoxValue(self.obj_driver_period, str(value)) | |||||
| elif (attribute == "nperiods"): | |||||
| self.obj_driver_nperiods.setValue(int(value)) | |||||
| elif (attribute == "hwmon"): | |||||
| self.obj_driver_hwmon.setChecked(bool(value)) | |||||
| elif (attribute == "hwmeter"): | |||||
| self.obj_driver_hwmeter.setChecked(bool(value)) | |||||
| elif (attribute == "duplex"): | |||||
| self.obj_driver_duplex.setChecked(bool(value)) | |||||
| elif (attribute == "softmode"): | |||||
| self.obj_driver_softmode.setChecked(bool(value)) | |||||
| elif (attribute == "monitor"): | |||||
| self.obj_driver_monitor.setChecked(bool(value)) | |||||
| elif (attribute == "dither"): | |||||
| value = str(value) | |||||
| if (value == "n"): | |||||
| self.obj_driver_dither.setCurrentIndex(0) | |||||
| elif (value == "r"): | |||||
| self.obj_driver_dither.setCurrentIndex(1) | |||||
| elif (value == "s"): | |||||
| self.obj_driver_dither.setCurrentIndex(2) | |||||
| elif (value == "t"): | |||||
| self.obj_driver_dither.setCurrentIndex(3) | |||||
| else: | |||||
| self.obj_driver_dither.setEnabled(False) | |||||
| print("JackSettings::loadDriverSettings() - Invalid dither value '%s'" % (value)) | |||||
| elif (attribute == "inchannels"): | |||||
| self.obj_driver_inchannels.setValue(int(value)) | |||||
| elif (attribute == "outchannels"): | |||||
| self.obj_driver_outchannels.setValue(int(value)) | |||||
| elif (attribute == "shorts"): | |||||
| self.obj_driver_shorts.setChecked(bool(value)) | |||||
| elif (attribute == "input-latency"): | |||||
| self.obj_driver_input_latency.setValue(int(value)) | |||||
| elif (attribute == "output-latency"): | |||||
| self.obj_driver_output_latency.setValue(int(value)) | |||||
| elif (attribute == "midi-driver"): | |||||
| value = str(value) | |||||
| if (value == "none"): | |||||
| self.obj_driver_midi_driver.setCurrentIndex(0) | |||||
| elif (value == "seq"): | |||||
| self.obj_driver_midi_driver.setCurrentIndex(1) | |||||
| elif (value == "raw"): | |||||
| self.obj_driver_midi_driver.setCurrentIndex(2) | |||||
| else: | |||||
| self.obj_driver_midi_driver.setEnabled(False) | |||||
| print("JackSettings::loadDriverSettings() - Invalid midi-driver value '%s'" % (value)) | |||||
| elif (attribute == "wait"): | |||||
| self.obj_driver_wait.setValue(int(value)) | |||||
| elif (attribute == "verbose"): | |||||
| self.obj_driver_verbose.setValue(int(value)) | |||||
| elif (attribute == "snoop"): | |||||
| self.obj_driver_snoop.setChecked(bool(value)) | |||||
| elif (attribute == "channels"): | |||||
| self.obj_driver_channels.setValue(int(value)) | |||||
| else: | |||||
| print("JackSettings::loadDriverSettings() - Unimplemented driver attribute '%s', value: '%s'" % (attribute, str(value))) | |||||
| # ------------------------------------------------------------- | |||||
| # Helper functions | |||||
| def setComboBoxValue(self, box, text, split=False): | |||||
| for i in range(box.count()): | |||||
| if (box.itemText(i) == text or (box.itemText(i).split(" ")[0] == text and split)): | |||||
| box.setCurrentIndex(i) | |||||
| break | |||||
| else: | |||||
| if (text): | |||||
| box.addItem(text) | |||||
| box.setCurrentIndex(box.count()-1) | |||||
| # ------------------------------------------------------------- | |||||
| # Qt SLOT calls | |||||
| @pyqtSlot() | |||||
| def slot_checkALSASelection(self): | |||||
| if (self.m_driver == "alsa"): | |||||
| check = (self.obj_driver_duplex.isChecked() and self.obj_driver_capture.currentIndex() > 0 and self.obj_driver_playback.currentIndex() > 0) | |||||
| self.obj_driver_device.setEnabled(not check) | |||||
| @pyqtSlot(bool) | |||||
| def slot_checkDuplexSelection(self, active): | |||||
| if (driverHasFeature("duplex")): | |||||
| self.obj_driver_capture.setEnabled(active) | |||||
| self.obj_driver_capture_label.setEnabled(active) | |||||
| #self.obj_driver_playback.setEnabled(active) | |||||
| #self.obj_driver_playback_label.setEnabled(active) | |||||
| self.obj_driver_inchannels.setEnabled(active) | |||||
| self.obj_driver_inchannels_label.setEnabled(active) | |||||
| self.obj_driver_input_latency.setEnabled(active) | |||||
| self.obj_driver_input_latency_label.setEnabled(active) | |||||
| self.slot_checkALSASelection() | |||||
| @pyqtSlot(int, int, int, int) | |||||
| def slot_checkDriverSelection(self, row, column, prev_row, prev_column): | |||||
| # Save previous settings | |||||
| self.saveDriverSettings() | |||||
| # Set new Jack driver | |||||
| self.m_driver = dbus.String(self.obj_server_driver.item(row, 0).text().lower()) | |||||
| jackctl.SetParameterValue(["engine","driver"],self.m_driver) | |||||
| # Add device list | |||||
| self.obj_driver_device.clear() | |||||
| if (driverHasFeature("device")): | |||||
| dev_list = jackctl.GetParameterConstraint(["driver","device"])[3] | |||||
| for i in range(len(dev_list)): | |||||
| self.obj_driver_device.addItem(dev_list[i][0]+" [%s]" % (str(dev_list[i][1]))) | |||||
| # Custom 'playback' and 'capture' values | |||||
| self.obj_driver_capture.clear() | |||||
| self.obj_driver_playback.clear() | |||||
| if (self.m_driver == "alsa"): | |||||
| self.obj_driver_capture.addItem("none") | |||||
| self.obj_driver_playback.addItem("none") | |||||
| dev_list = jackctl.GetParameterConstraint(["driver","device"])[3] | |||||
| for i in range(len(dev_list)): | |||||
| self.obj_driver_capture.addItem(dev_list[i][0]+" ["+dev_list[i][1]+"]") | |||||
| self.obj_driver_playback.addItem(dev_list[i][0]+" ["+dev_list[i][1]+"]") | |||||
| elif (self.m_driver == "dummy"): | |||||
| for i in range(16): | |||||
| self.obj_driver_capture.addItem("%i" % ((i*2)+2)) | |||||
| self.obj_driver_playback.addItem("%i" % ((i*2)+2)) | |||||
| elif (self.m_driver == "firewire"): | |||||
| self.obj_driver_capture.addItem("no") | |||||
| self.obj_driver_capture.addItem("yes") | |||||
| self.obj_driver_playback.addItem("no") | |||||
| self.obj_driver_playback.addItem("yes") | |||||
| elif (driverHasFeature("playback") or driverHasFeature("capture")): | |||||
| print("JackSettings::slot_checkDriverSelection() - Custom playback/capture for driver '%s' not implemented yet" % (self.m_driver)) | |||||
| # Load Driver Settings | |||||
| self.loadDriverSettings() | |||||
| # Enable widgets according to driver | |||||
| self.obj_driver_capture.setEnabled(driverHasFeature("capture")) | |||||
| self.obj_driver_capture_label.setEnabled(driverHasFeature("capture")) | |||||
| self.obj_driver_playback.setEnabled(driverHasFeature("playback")) | |||||
| self.obj_driver_playback_label.setEnabled(driverHasFeature("playback")) | |||||
| self.obj_driver_device.setEnabled(driverHasFeature("device")) | |||||
| self.obj_driver_device_label.setEnabled(driverHasFeature("device")) | |||||
| self.obj_driver_rate.setEnabled(driverHasFeature("rate")) | |||||
| self.obj_driver_rate_label.setEnabled(driverHasFeature("rate")) | |||||
| self.obj_driver_period.setEnabled(driverHasFeature("period")) | |||||
| self.obj_driver_period_label.setEnabled(driverHasFeature("period")) | |||||
| self.obj_driver_nperiods.setEnabled(driverHasFeature("nperiods")) | |||||
| self.obj_driver_nperiods_label.setEnabled(driverHasFeature("nperiods")) | |||||
| self.obj_driver_hwmon.setEnabled(driverHasFeature("hwmon")) | |||||
| self.obj_driver_hwmeter.setEnabled(driverHasFeature("hwmeter")) | |||||
| self.obj_driver_duplex.setEnabled(driverHasFeature("duplex")) | |||||
| self.obj_driver_softmode.setEnabled(driverHasFeature("softmode")) | |||||
| self.obj_driver_monitor.setEnabled(driverHasFeature("monitor")) | |||||
| self.obj_driver_dither.setEnabled(driverHasFeature("dither")) | |||||
| self.obj_driver_dither_label.setEnabled(driverHasFeature("dither")) | |||||
| self.obj_driver_inchannels.setEnabled(driverHasFeature("inchannels")) | |||||
| self.obj_driver_inchannels_label.setEnabled(driverHasFeature("inchannels")) | |||||
| self.obj_driver_outchannels.setEnabled(driverHasFeature("outchannels")) | |||||
| self.obj_driver_outchannels_label.setEnabled(driverHasFeature("outchannels")) | |||||
| self.obj_driver_shorts.setEnabled(driverHasFeature("shorts")) | |||||
| self.obj_driver_input_latency.setEnabled(driverHasFeature("input-latency")) | |||||
| self.obj_driver_input_latency_label.setEnabled(driverHasFeature("input-latency")) | |||||
| self.obj_driver_output_latency.setEnabled(driverHasFeature("output-latency")) | |||||
| self.obj_driver_output_latency_label.setEnabled(driverHasFeature("output-latency")) | |||||
| self.obj_driver_midi_driver.setEnabled(driverHasFeature("midi-driver")) | |||||
| self.obj_driver_midi_driver_label.setEnabled(driverHasFeature("midi-driver")) | |||||
| self.obj_driver_wait.setEnabled(driverHasFeature("wait")) | |||||
| self.obj_driver_wait_label.setEnabled(driverHasFeature("wait")) | |||||
| self.obj_driver_verbose.setEnabled(driverHasFeature("verbose")) | |||||
| self.obj_driver_verbose_label.setEnabled(driverHasFeature("verbose")) | |||||
| self.obj_driver_snoop.setEnabled(driverHasFeature("snoop")) | |||||
| self.obj_driver_channels.setEnabled(driverHasFeature("channels")) | |||||
| self.obj_driver_channels_label.setEnabled(driverHasFeature("channels")) | |||||
| # Misc stuff | |||||
| if (self.obj_server_driver.item(0, row).text() == "ALSA"): | |||||
| self.toolbox_driver_misc.setCurrentIndex(1) | |||||
| self.obj_driver_capture_label.setText(self.tr("Input Device:")) | |||||
| self.obj_driver_playback_label.setText(self.tr("Output Device:")) | |||||
| elif (self.obj_server_driver.item(0, row).text() == "Dummy"): | |||||
| self.toolbox_driver_misc.setCurrentIndex(2) | |||||
| self.obj_driver_capture_label.setText(self.tr("Input Ports:")) | |||||
| self.obj_driver_playback_label.setText(self.tr("Output Ports:")) | |||||
| elif (self.obj_server_driver.item(0, row).text() == "FireWire"): | |||||
| self.toolbox_driver_misc.setCurrentIndex(3) | |||||
| self.obj_driver_capture_label.setText(self.tr("Capture Ports:")) | |||||
| self.obj_driver_playback_label.setText(self.tr("Playback Ports:")) | |||||
| elif (self.obj_server_driver.item(0, row).text() == "Loopback"): | |||||
| self.toolbox_driver_misc.setCurrentIndex(4) | |||||
| else: | |||||
| self.toolbox_driver_misc.setCurrentIndex(0) | |||||
| self.slot_checkDuplexSelection(self.obj_driver_duplex.isChecked()) | |||||
| @pyqtSlot() | |||||
| def slot_saveJackSettings(self): | |||||
| self.saveServerSettings() | |||||
| self.saveDriverSettings() | |||||
| @pyqtSlot() | |||||
| def slot_resetJackSettings(self): | |||||
| if (self.tabWidget.currentIndex() == 0): | |||||
| self.loadServerSettings(True, True) | |||||
| elif (self.tabWidget.currentIndex() == 1): | |||||
| self.loadDriverSettings(True, True) | |||||
| @pyqtSlot() | |||||
| def slot_closeWithError(self): | |||||
| QMessageBox.critical(self, self.tr("Error"), self.tr("jackdbus is not available!\nIt's not possible to configure JACK at this point.")) | |||||
| self.close() | |||||
| # ------------------------------------------------------------- | |||||
| # Allow to use this as a standalone app | |||||
| if __name__ == '__main__': | |||||
| # Additional imports | |||||
| import sys, icons_rc | |||||
| from PyQt4.QtGui import QApplication, QIcon | |||||
| # App initialization | |||||
| app = QApplication(sys.argv) | |||||
| # Connect to DBus | |||||
| if (dbus): | |||||
| if (initBus(dbus.SessionBus())): | |||||
| QMessageBox.critical(None, app.translate("JackSettingsW", "Error"), app.translate("JackSettingsW", "jackdbus is not available!\nIs not possible to configure JACK at this point.")) | |||||
| sys.exit(1) | |||||
| else: | |||||
| QMessageBox.critical(None, app.translate("JackSettingsW", "Error"), app.translate("JackSettingsW", "DBus is not available, cannot continue.")) | |||||
| sys.exit(1) | |||||
| # Show GUI | |||||
| gui = JackSettingsW(None) | |||||
| gui.setWindowIcon(QIcon(":/scalable/jack.svg")) | |||||
| gui.show() | |||||
| # App-Loop | |||||
| sys.exit(app.exec_()) | |||||