1 |
# |
---|
2 |
# Copyright (C) 2009 by Arnold Krille |
---|
3 |
# |
---|
4 |
# This file is part of FFADO |
---|
5 |
# FFADO = Free Firewire (pro-)audio drivers for linux |
---|
6 |
# |
---|
7 |
# This program is free software: you can redistribute it and/or modify |
---|
8 |
# it under the terms of the GNU General Public License as published by |
---|
9 |
# the Free Software Foundation, either version 2 of the License, or |
---|
10 |
# (at your option) version 3 of the License. |
---|
11 |
# |
---|
12 |
# This program is distributed in the hope that it will be useful, |
---|
13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
15 |
# GNU General Public License for more details. |
---|
16 |
# |
---|
17 |
# You should have received a copy of the GNU General Public License |
---|
18 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
19 |
# |
---|
20 |
|
---|
21 |
from PyQt4 import QtGui, QtCore, Qt |
---|
22 |
import dbus |
---|
23 |
|
---|
24 |
from ffado.widgets.matrixmixer import MatrixMixer |
---|
25 |
from ffado.widgets.crossbarrouter import * |
---|
26 |
|
---|
27 |
from ffado.config import * |
---|
28 |
|
---|
29 |
class BooleanControl: |
---|
30 |
def __init__(self, hw, path): |
---|
31 |
self.iface = dbus.Interface( |
---|
32 |
hw.bus.get_object(hw.servername, path), |
---|
33 |
dbus_interface="org.ffado.Control.Element.Boolean") |
---|
34 |
self.value = self.iface.selected() |
---|
35 |
|
---|
36 |
def selected(self): |
---|
37 |
return self.value |
---|
38 |
|
---|
39 |
def select(self, n): |
---|
40 |
if self.iface.select(n): |
---|
41 |
self.value = n |
---|
42 |
return True |
---|
43 |
return False |
---|
44 |
|
---|
45 |
class DiscreteControl: |
---|
46 |
def __init__(self, hw, path): |
---|
47 |
self.iface = dbus.Interface( |
---|
48 |
hw.bus.get_object(hw.servername, path), |
---|
49 |
dbus_interface="org.ffado.Control.Element.Discrete") |
---|
50 |
self.value = self.iface.getValue() |
---|
51 |
|
---|
52 |
def getvalue(self): |
---|
53 |
return self.value |
---|
54 |
|
---|
55 |
def setvalue(self, v): |
---|
56 |
if v != self.value: |
---|
57 |
self.iface.setValue(v) |
---|
58 |
self.value = v |
---|
59 |
|
---|
60 |
class MonitoringModel(QtCore.QAbstractTableModel): |
---|
61 |
def __init__(self, hw, parent): |
---|
62 |
QtCore.QAbstractTableModel.__init__(self, parent) |
---|
63 |
|
---|
64 |
self.hw = hw |
---|
65 |
|
---|
66 |
self.mutestates = ("Global", "True", "False") |
---|
67 |
|
---|
68 |
self.globaldims = [] |
---|
69 |
self.globalmutes = [] |
---|
70 |
self.perchannelmutes = [] |
---|
71 |
self.globalvolumes = [] |
---|
72 |
self.perchannelvolumes = [] |
---|
73 |
for i in range(10): |
---|
74 |
self.globaldims.append(BooleanControl(self.hw, self.hw.basepath + ("/EAP/Monitoring/GlobalDim/AffectsCh%i" % i))) |
---|
75 |
self.globalmutes.append(BooleanControl(self.hw, self.hw.basepath + ("/EAP/Monitoring/GlobalMute/AffectsCh%i" % i))) |
---|
76 |
self.perchannelmutes.append(BooleanControl(self.hw, self.hw.basepath + ("/EAP/Monitoring/PerChannel/Mute%i" % i))) |
---|
77 |
self.globalvolumes.append(BooleanControl(self.hw, self.hw.basepath + ("/EAP/Monitoring/GlobalVolume/AffectsCh%i" % i))) |
---|
78 |
self.perchannelvolumes.append(DiscreteControl(self.hw, self.hw.basepath + ("/EAP/Monitoring/PerChannel/Volume%i" % i))) |
---|
79 |
|
---|
80 |
def rowCount(self, parent): |
---|
81 |
return 3 |
---|
82 |
|
---|
83 |
def columnCount(self, parent): |
---|
84 |
return 10 |
---|
85 |
|
---|
86 |
def headerData(self, section, orientation, role=Qt.Qt.DisplayRole): |
---|
87 |
if role != Qt.Qt.DisplayRole: |
---|
88 |
#print "headerData will return nothing" |
---|
89 |
return None |
---|
90 |
#print "headerData() Will return a label" |
---|
91 |
if orientation == Qt.Qt.Horizontal: |
---|
92 |
return "Ch. %i" % section |
---|
93 |
if orientation == Qt.Qt.Vertical: |
---|
94 |
return ("Mute", "Dim", "Volume")[section] |
---|
95 |
return None |
---|
96 |
|
---|
97 |
def data(self, index, role): |
---|
98 |
if not role in (Qt.Qt.DisplayRole, Qt.Qt.EditRole): |
---|
99 |
return None |
---|
100 |
row = index.row() |
---|
101 |
col = index.column() |
---|
102 |
if role == Qt.Qt.DisplayRole: |
---|
103 |
if row is 0: |
---|
104 |
if self.perchannelmutes[col].selected(): |
---|
105 |
return self.mutestates[1] |
---|
106 |
else: |
---|
107 |
if self.globalmutes[col].selected(): |
---|
108 |
return self.mutestates[0] |
---|
109 |
return self.mutestates[2] |
---|
110 |
if row is 1: |
---|
111 |
if self.globaldims[col].selected(): |
---|
112 |
return "Enabled" |
---|
113 |
else: |
---|
114 |
return "Disabled" |
---|
115 |
if row is 2: |
---|
116 |
if self.globalvolumes[col].selected(): |
---|
117 |
return "Global" |
---|
118 |
else: |
---|
119 |
return self.perchannelvolumes[col].getvalue() |
---|
120 |
if role == Qt.Qt.EditRole: |
---|
121 |
if row is 0: |
---|
122 |
return QtCore.QStringList(self.mutestates) |
---|
123 |
if row is 1: |
---|
124 |
return QtCore.QStringList(("Enabled","Disabled")) |
---|
125 |
if row is 2: |
---|
126 |
if self.globalvolumes[col].selected(): |
---|
127 |
return 1 |
---|
128 |
return self.perchannelvolumes[col].getvalue() |
---|
129 |
return "%i,%i" % (row,col) |
---|
130 |
|
---|
131 |
def setData(self, index, value, role=Qt.Qt.EditRole): |
---|
132 |
col = index.column() |
---|
133 |
row = index.row() |
---|
134 |
if row == 0: |
---|
135 |
if value == "Global": |
---|
136 |
self.globalmutes[col].select(True) |
---|
137 |
self.perchannelmutes[col].select(False) |
---|
138 |
else: |
---|
139 |
self.globalmutes[col].select(False) |
---|
140 |
if value == "True": value = True |
---|
141 |
if value == "False": value = False |
---|
142 |
self.perchannelmutes[col].select(value) |
---|
143 |
return True |
---|
144 |
if row == 1: |
---|
145 |
if value == "Enabled": value = True |
---|
146 |
if value == "Disabled": value = False |
---|
147 |
return self.globaldims[col].select(value) |
---|
148 |
if row == 2: |
---|
149 |
#print "setData() value=%s" % value.toString() |
---|
150 |
v = int(value.toString()) |
---|
151 |
#print " integer is %i" % v |
---|
152 |
if v > 0: |
---|
153 |
return self.globalvolumes[col].select(True) |
---|
154 |
else: |
---|
155 |
self.globalvolumes[col].select(False) |
---|
156 |
self.perchannelvolumes[col].setvalue(v) |
---|
157 |
return False |
---|
158 |
|
---|
159 |
def flags(self, index): |
---|
160 |
ret = QtCore.QAbstractTableModel.flags(self, index) |
---|
161 |
if index.row() in (0,1,2): |
---|
162 |
ret |= Qt.Qt.ItemIsEditable |
---|
163 |
return ret |
---|
164 |
|
---|
165 |
|
---|
166 |
|
---|
167 |
class MonitoringDelegate(QtGui.QStyledItemDelegate): |
---|
168 |
def __init__(self, parent): |
---|
169 |
QtGui.QStyledItemDelegate.__init__(self, parent) |
---|
170 |
|
---|
171 |
def createEditor(self, parent, option, index): |
---|
172 |
if index.data(Qt.Qt.EditRole).type() == QtCore.QVariant.StringList: |
---|
173 |
combo = QtGui.QComboBox(parent) |
---|
174 |
self.connect(combo, QtCore.SIGNAL("activated(int)"), self.currentChanged) |
---|
175 |
return combo |
---|
176 |
else: |
---|
177 |
return QtGui.QStyledItemDelegate.createEditor(self, parent, option, index) |
---|
178 |
|
---|
179 |
def setEditorData(self, editor, index): |
---|
180 |
if isinstance(editor, QtGui.QComboBox): |
---|
181 |
list = index.data(Qt.Qt.EditRole).toStringList() |
---|
182 |
editor.addItems(list) |
---|
183 |
editor.setCurrentIndex(list.indexOf(index.data(Qt.Qt.DisplayRole).toString())) |
---|
184 |
else: |
---|
185 |
QtGui.QStyledItemDelegate.setEditorData(self, editor, index) |
---|
186 |
|
---|
187 |
def setModelData(self, editor, model, index): |
---|
188 |
if isinstance(editor, QtGui.QComboBox): |
---|
189 |
model.setData(index, editor.currentText(), Qt.Qt.EditRole) |
---|
190 |
else: |
---|
191 |
QtGui.QStyledItemDelegate.setModelData(self, editor, model, index) |
---|
192 |
|
---|
193 |
def currentChanged(self): |
---|
194 |
#print "currentChanged() sender=%s" % (str(self.sender())) |
---|
195 |
editor = self.sender() |
---|
196 |
self.emit(QtCore.SIGNAL("commitData(QWidget*)"), editor) |
---|
197 |
self.emit(QtCore.SIGNAL("closeEditor(QWidget*)"), editor) |
---|
198 |
|
---|
199 |
class Saffire_Dice(QtGui.QWidget): |
---|
200 |
def __init__(self, parent=None): |
---|
201 |
QtGui.QWidget.__init__(self, parent) |
---|
202 |
self.layout = QtGui.QGridLayout(self) |
---|
203 |
self.setLayout(self.layout) |
---|
204 |
self.tabs = QtGui.QTabWidget(self) |
---|
205 |
self.layout.addWidget(self.tabs) |
---|
206 |
|
---|
207 |
def buildMixer(self): |
---|
208 |
#print self.hw |
---|
209 |
#print self.hw.getText("/Generic/Nickname") |
---|
210 |
self.matrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/EAP/MatrixMixer", self) |
---|
211 |
scrollarea = QtGui.QScrollArea(self.tabs) |
---|
212 |
scrollarea.setWidgetResizable(True) |
---|
213 |
scrollarea.setWidget(self.matrix) |
---|
214 |
self.tabs.addTab(scrollarea, "Matrix") |
---|
215 |
|
---|
216 |
self.router = CrossbarRouter(self.hw.servername, self.hw.basepath+"/EAP/Router", self) |
---|
217 |
scrollarea = QtGui.QScrollArea(self.tabs) |
---|
218 |
scrollarea.setWidgetResizable(True) |
---|
219 |
scrollarea.setWidget(self.router) |
---|
220 |
self.tabs.addTab(scrollarea, "Routing") |
---|
221 |
|
---|
222 |
model = MonitoringModel(self.hw, self) |
---|
223 |
|
---|
224 |
widget = QtGui.QWidget() |
---|
225 |
uicLoad("ffado/mixer/saffire_dice_monitoring.ui", widget) |
---|
226 |
widget.monitoringView.setModel(model) |
---|
227 |
widget.monitoringView.setItemDelegate(MonitoringDelegate(self)) |
---|
228 |
self.tabs.addTab(widget, "Monitoring") |
---|
229 |
|
---|
230 |
self.muteInterface = BooleanControl(self.hw, self.hw.basepath+"/EAP/Monitoring/GlobalMute/State") |
---|
231 |
widget.btnMute.setChecked(self.muteInterface.selected()) |
---|
232 |
self.connect(widget.btnMute, QtCore.SIGNAL("toggled(bool)"), self.muteToggle) |
---|
233 |
self.dimInterface = BooleanControl(self.hw, self.hw.basepath+"/EAP/Monitoring/GlobalDim/State") |
---|
234 |
widget.btnDim.setChecked(self.dimInterface.selected()) |
---|
235 |
self.connect(widget.btnDim, QtCore.SIGNAL("toggled(bool)"), self.dimToggle) |
---|
236 |
|
---|
237 |
self.dimLevelInterface = DiscreteControl(self.hw, self.hw.basepath+"/EAP/Monitoring/GlobalDim/Level") |
---|
238 |
widget.dimLevel.setValue(self.dimLevelInterface.getvalue()) |
---|
239 |
self.connect(widget.dimLevel, QtCore.SIGNAL("valueChanged(int)"), self.dimLevelChanged) |
---|
240 |
self.volumeInterface = DiscreteControl(self.hw, self.hw.basepath+"/EAP/Monitoring/GlobalVolume/Level") |
---|
241 |
widget.volumeKnob.setValue(self.volumeInterface.getvalue()) |
---|
242 |
self.connect(widget.volumeKnob, QtCore.SIGNAL("valueChanged(int)"), self.volumeChanged) |
---|
243 |
|
---|
244 |
if self.configrom.getModelName() == "SAFFIRE_PRO_24": |
---|
245 |
self.ch1inst = BooleanControl(self.hw, self.hw.basepath + "/EAP/Ch1LineInst") |
---|
246 |
widget.chkInst1.setChecked(self.ch1inst.selected()) |
---|
247 |
self.connect(widget.chkInst1, QtCore.SIGNAL("toggled(bool)"), self.ch1inst.select) |
---|
248 |
self.ch2inst = BooleanControl(self.hw, self.hw.basepath + "/EAP/Ch2LineInst") |
---|
249 |
widget.chkInst2.setChecked(self.ch2inst.selected()) |
---|
250 |
self.connect(widget.chkInst2, QtCore.SIGNAL("toggled(bool)"), self.ch2inst.select) |
---|
251 |
self.ch3level = BooleanControl(self.hw, self.hw.basepath + "/EAP/Ch3Level") |
---|
252 |
widget.chkLevel3.setChecked(self.ch3level.selected()) |
---|
253 |
self.connect(widget.chkLevel3, QtCore.SIGNAL("toggled(bool)"), self.ch3level.select) |
---|
254 |
self.ch4level = BooleanControl(self.hw, self.hw.basepath + "/EAP/Ch4Level") |
---|
255 |
widget.chkLevel4.setChecked(self.ch4level.selected()) |
---|
256 |
self.connect(widget.chkLevel4, QtCore.SIGNAL("toggled(bool)"), self.ch4level.select) |
---|
257 |
widget.chkSpdif.deleteLater() |
---|
258 |
widget.btnPad.deleteLater() |
---|
259 |
else: |
---|
260 |
widget.chkInst1.deleteLater() |
---|
261 |
widget.chkInst2.deleteLater() |
---|
262 |
widget.chkLevel3.deleteLater() |
---|
263 |
widget.chkLevel4.deleteLater() |
---|
264 |
|
---|
265 |
|
---|
266 |
def muteToggle(self, mute): |
---|
267 |
self.muteInterface.select(mute) |
---|
268 |
def dimToggle(self, mute): |
---|
269 |
self.dimInterface.select(mute) |
---|
270 |
|
---|
271 |
def dimLevelChanged(self, value): |
---|
272 |
self.dimLevelInterface.setvalue(value) |
---|
273 |
def volumeChanged(self, value): |
---|
274 |
self.volumeInterface.setvalue(value) |
---|
275 |
|
---|
276 |
def getDisplayTitle(self): |
---|
277 |
return "Saffire PRO40/PRO24 Mixer" |
---|
278 |
|
---|
279 |
# |
---|
280 |
# vim: et ts=4 sw=4 |
---|