root/trunk/libffado/support/mixer-qt4/ffado/mixer/audiofire.py

Revision 2659, 17.5 kB (checked in by jwoithe, 7 years ago)

Under python3 it is necessary to explicitly typecast the result of some
divisions to integer types. Patch extracted from series by Xavier Forestier:
https://sourceforge.net/p/ffado/mailman/message/35457569/.

  • Property svn:mergeinfo set to
Line 
1 #
2 # Copyright (C) 2005-2008 by Pieter Palmers
3 #
4 # This file is part of FFADO
5 # FFADO = Free Firewire (pro-)audio drivers for linux
6 #
7 # FFADO is based upon FreeBoB.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 2 of the License, or
12 # (at your option) version 3 of the License.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 #
22
23 from PyQt4.QtCore import Qt, QTimer
24 from PyQt4.QtGui import QWidget, QHBoxLayout, QVBoxLayout, \
25                         QGroupBox, QTabWidget, QLabel, \
26                         QPushButton, QToolButton, QSpacerItem, QSizePolicy
27 from ffado.config import *
28 import logging
29 log = logging.getLogger('audiofire')
30
31 class AfMonitorWidget(QWidget):
32     def __init__(self,parent = None):
33         QWidget.__init__(self,parent)
34         uicLoad("ffado/mixer/audiofire_strip", self)
35
36 class AfSettingsWidget(QWidget):
37     def __init__(self,parent = None):
38         QWidget.__init__(self,parent)
39         uicLoad("ffado/mixer/audiofire_settings", self)
40
41 class AudioFire(QWidget):
42     def __init__(self,parent = None):
43         QWidget.__init__(self,parent)
44         log.debug("Init AudioFire mixer window")
45
46     def getDisplayTitle(self):
47         modelId = self.configrom.getModelId()
48         if modelId == 0x0AF2:
49             return "AudioFire2"
50         if modelId == 0x0AF4:
51             return "AudioFire4"
52         if modelId == 0x0AF8:
53             return "AudioFire8"
54         if modelId == 0x0AF9:
55             return "AudioFirePre8"
56         if modelId == 0x0AF12:
57             return "AudioFire12"
58         return "Generic FireWorks"
59
60     def updateMatrixButton(self,a0):
61         sender = self.sender()
62         if a0:
63             state = 1
64         else:
65             state = 0
66         log.debug("set %s %d %d to %d" % (
67                     self.MatrixButtonControls[sender][0],
68                     self.MatrixButtonControls[sender][1],
69                     self.MatrixButtonControls[sender][2],
70                     state))
71         self.hw.setMatrixMixerValue(self.MatrixButtonControls[sender][0],
72                                     self.MatrixButtonControls[sender][1],
73                                     self.MatrixButtonControls[sender][2],
74                                     state)
75
76     def updateMatrixRotary(self,a0):
77         sender = self.sender()
78         vol = a0
79         log.debug("set %s %d %d to %d" % (
80                     self.MatrixRotaryControls[sender][0],
81                     self.MatrixRotaryControls[sender][1],
82                     self.MatrixRotaryControls[sender][2],
83                     vol))
84         self.hw.setMatrixMixerValue(self.MatrixRotaryControls[sender][0],
85                                     self.MatrixRotaryControls[sender][1],
86                                     self.MatrixRotaryControls[sender][2],
87                                     vol)
88
89     def updateMatrixVolume(self,a0):
90         sender = self.sender()
91         vol = a0
92         #vol = 0x01000000-vol
93         log.debug("set %s %d %d to %d" % (
94                     self.MatrixVolumeControls[sender][0],
95                     self.MatrixVolumeControls[sender][1],
96                     self.MatrixVolumeControls[sender][2],
97                     vol))
98         self.hw.setMatrixMixerValue(self.MatrixVolumeControls[sender][0],
99                                     self.MatrixVolumeControls[sender][1],
100                                     self.MatrixVolumeControls[sender][2],
101                                     vol)
102
103     def updateVolume(self,a0):
104         sender = self.sender()
105         vol = a0
106         #vol = 0x01000000-vol
107         log.debug("set %s to %d" % (
108                     self.VolumeControls[sender][0],
109                     vol))
110         self.hw.setContignuous(self.VolumeControls[sender][0],
111                               vol)
112
113     def updateSelector(self,a0):
114         sender = self.sender()
115         if a0:
116             state = 1
117         else:
118             state = 0
119         log.debug("set %s to %d" % (
120                     self.SelectorControls[sender][0],
121                     state))
122         self.hw.setDiscrete(self.SelectorControls[sender][0], state)
123
124     def updateTrigger(self):
125         sender = self.sender()
126         log.debug("trigger %s" % (self.TriggerControls[sender][0]))
127         self.hw.setDiscrete(self.TriggerControls[sender][0], 1)
128
129     def updateSPDIFmodeControl(self,a0):
130         sender = self.sender()
131         if a0:
132             state = 1
133         else:
134             state = 0
135         if state:
136             log.debug("set %s to %d" % (
137                         self.SPDIFmodeControls[sender][0],
138                         self.SPDIFmodeControls[sender][1]))
139             self.hw.setDiscrete(self.SPDIFmodeControls[sender][0], self.SPDIFmodeControls[sender][1])
140
141     def updateDigIfaceControl(self, a0):
142         sender = self.sender()
143         state = a0
144         # 0/2/3 is available but GUI set 0/1/2
145         if a0 > 0:
146             state += 1
147         log.debug("set %s to %d" % (
148             self.DigIfaceControls[sender][0], state))
149         self.hw.setDiscrete(self.DigIfaceControls[sender][0], state)
150
151     def updatePlbkRouteControl(self, src):
152         sender = self.sender()
153         path = self.PlbkRouteControls[sender][0]
154         sink = self.PlbkRouteControls[sender][1]
155         self.hw.setDiscrete(path, sink, src)
156         self.setStreamLabel(src, sink)
157
158     def setStreamLabel(self, src, sink):
159         pos = src * 2 + 1
160         self.StreamMonitors[sink].lblName.setText("Playback %d/%d" % (pos, pos + 1))
161
162     def buildMixer(self):
163         log.debug("Building mixer")
164         self.MatrixButtonControls={}
165         self.MatrixRotaryControls={}
166         self.MatrixVolumeControls={}
167         self.VolumeControls={}
168         self.SelectorControls={}
169         self.SPDIFmodeControls={}
170         self.TriggerControls={}
171         self.DigIfaceControls={}
172         self.PlbkRouteControls={}
173         self.StreamMonitors=[]
174
175         nb_pys_out = self.hw.getDiscrete("/HwInfo/PhysicalAudioOutCount")
176         nb_pys_in = self.hw.getDiscrete("/HwInfo/PhysicalAudioInCount")
177
178         outputtabslayout = QHBoxLayout( self )
179         outputtabs = QTabWidget(self)
180         outputtabslayout.addWidget( outputtabs, 1 )
181
182         for outpair in range(int(nb_pys_out/2)):
183             tab = QWidget( outputtabs )
184             tablayout = QHBoxLayout( tab )
185            
186             grpMonitor = QGroupBox(tab)
187             tablayout.addWidget(grpMonitor)
188    
189             grpPlayback = QGroupBox(tab)
190             tablayout.addWidget(grpPlayback)
191    
192             grpOutput = QGroupBox(tab)
193             tablayout.addWidget(grpOutput)
194    
195             grpMonitor.setTitle("Monitor")
196             grpPlayback.setTitle("Playback")
197             grpOutput.setTitle("Output")
198            
199             # monitor controls
200             grpMonitorLayout = QHBoxLayout()
201             grpMonitor.setLayout(grpMonitorLayout);
202             output_id = outpair * 2
203             for inpair in range(int(nb_pys_in/2)):
204                 # create GUI elements
205                 strip = AfMonitorWidget( grpMonitor )
206                 grpMonitorLayout.addWidget( strip, 1 )
207                 input_id = inpair*2
208                 strip.lblName.setText("In %d/%d" % (input_id+1, input_id+2))
209
210                 # add the elements to the control structure
211
212                 self.MatrixButtonControls[strip.btnMute0] = ['/Mixer/MonitorMute', input_id, output_id]
213                 self.MatrixButtonControls[strip.btnMute1] = ['/Mixer/MonitorMute', input_id + 1, output_id + 1]
214                 self.MatrixButtonControls[strip.btnSolo0] = ['/Mixer/MonitorSolo', input_id, output_id]
215                 self.MatrixButtonControls[strip.btnSolo1] = ['/Mixer/MonitorSolo', input_id + 1, output_id + 1]
216                 self.MatrixRotaryControls[strip.rotPan0]  = ['/Mixer/MonitorPan', input_id, output_id]
217                 self.MatrixRotaryControls[strip.rotPan1]  = ['/Mixer/MonitorPan', input_id + 1, output_id + 1]
218                 self.MatrixVolumeControls[strip.sldGain0]  = ['/Mixer/MonitorGain', input_id, output_id]
219                 self.MatrixVolumeControls[strip.sldGain1]  = ['/Mixer/MonitorGain', input_id + 1, output_id + 1]
220
221             # playback
222             grpPlaybackLayout = QHBoxLayout()
223             grpPlayback.setLayout(grpPlaybackLayout);
224             strip = AfMonitorWidget( grpPlayback )
225             grpPlaybackLayout.addWidget(strip, 1)
226             strip.lblName.setText("Playback %d/%d" % (output_id+1, output_id+2))
227             self.StreamMonitors.append(strip)
228
229             self.VolumeControls[strip.sldGain0] = ["/Mixer/PC%dGain" % (output_id)]
230             self.VolumeControls[strip.sldGain1] = ["/Mixer/PC%dGain" % (output_id+1)]
231             self.SelectorControls[strip.btnMute0] = ["/Mixer/PC%dMute" % (output_id)]
232             self.SelectorControls[strip.btnMute1] = ["/Mixer/PC%dMute" % (output_id+1)]
233             self.SelectorControls[strip.btnSolo0] = ["/Mixer/PC%dSolo" % (output_id)]
234             self.SelectorControls[strip.btnSolo1] = ["/Mixer/PC%dSolo" % (output_id+1)]
235
236             # fix up mixer strip gui
237             strip.rotPan0.hide()
238             strip.rotPan1.hide()
239
240             # output
241             grpOutputLayout = QHBoxLayout()
242             grpOutput.setLayout(grpOutputLayout);
243             strip = AfMonitorWidget( grpOutput )
244             grpOutputLayout.addWidget(strip, 1)
245             strip.lblName.setText("Output %d/%d" % (output_id+1, output_id+2))
246
247             self.VolumeControls[strip.sldGain0] = ["/Mixer/OUT%dGain" % (output_id)]
248             self.VolumeControls[strip.sldGain1] = ["/Mixer/OUT%dGain" % (output_id+1)]
249             self.SelectorControls[strip.btnMute0] = ["/Mixer/OUT%dMute" % (output_id)]
250             self.SelectorControls[strip.btnMute1] = ["/Mixer/OUT%dMute" % (output_id+1)]
251             self.SelectorControls[strip.btnSolo0] = ["/Mixer/OUT%dNominal" % (output_id)]
252             self.SelectorControls[strip.btnSolo1] = ["/Mixer/OUT%dNominal" % (output_id+1)]
253
254             # fix up mixer strip gui
255             strip.btnSolo0.setText("Pad")
256             strip.btnSolo1.setText("Pad")
257             strip.rotPan0.hide()
258             strip.rotPan1.hide()
259
260             # add the tab
261             outputtabs.addTab( tab, "Out %d/%d" % (output_id+1, output_id+2))
262
263         # add an input config tab
264         tab = QWidget( outputtabs )
265         tablayout = QHBoxLayout( tab )
266
267         for inpair in range(nb_pys_in):
268             # create GUI elements
269             log.debug("strip")
270             grpInput = QGroupBox(tab)
271             tablayout.addWidget(grpInput)
272             grpInput.setTitle("In %d" % (inpair+1))
273
274             grpInputLayout = QVBoxLayout()
275             grpInput.setLayout(grpInputLayout);
276
277             label = QLabel( grpInput )
278             grpInputLayout.addWidget( label )
279             label.setText("In %d" % (inpair+1))
280             label.setAlignment(Qt.AlignCenter)
281
282             btn = QToolButton( grpInput )
283             grpInputLayout.addWidget( btn )
284             btn.setText("Pad")
285             btn.setCheckable(True)
286             self.SelectorControls[btn] = ["/Mixer/IN%dNominal" % (inpair)]
287
288             spacer = QSpacerItem(1,1,QSizePolicy.Minimum,QSizePolicy.Expanding)
289             grpInputLayout.addItem(spacer)
290
291         outputtabs.addTab( tab, "Input")
292
293         # add an settings tab
294         tab = QWidget( outputtabs )
295         tablayout = QHBoxLayout( tab )
296         outputtabs.addTab( tab, "Settings")
297         settings = AfSettingsWidget( tab )
298
299         has_sw_phantom = self.hw.getDiscrete("/HwInfo/PhantomPower")
300         if has_sw_phantom:
301             self.SelectorControls[settings.btnPhantom] = ["/PhantomPower"]
302         else:
303             settings.btnPhantom.hide()
304
305         has_opt_iface = self.hw.getDiscrete('/HwInfo/OpticalInterface')
306         if has_opt_iface:
307             self.DigIfaceControls[settings.cmbDigIface] = ['/DigitalInterface']
308         else:
309             settings.DigIface.hide()
310
311         has_plbk_route = self.hw.getDiscrete('/HwInfo/PlaybackRouting')
312         if has_plbk_route:
313             self.PlbkRouteControls[settings.cmbRoute1] = ['/PlaybackRouting', 0]
314             self.PlbkRouteControls[settings.cmbRoute2] = ['/PlaybackRouting', 1]
315             self.PlbkRouteControls[settings.cmbRoute3] = ['/PlaybackRouting', 2]
316             if self.configrom.getModelId() == 0x0AF2:
317                 label_route2 = 'Headphone Out 1/2'
318             else:
319                 label_route2 = 'Analog Out 3/4'
320             settings.labelRoute2.setText(label_route2)
321         else:
322             settings.PlbkRoute.hide()
323
324         self.TriggerControls[settings.btnSaveSettings] = ["/SaveSettings"]
325         self.TriggerControls[settings.btnIdentify] = ["/Identify"]
326
327         if self.configrom.getModelId() == 0x0AF12:
328             settings.spdifMode.hide()
329         else:
330             self.SPDIFmodeControls[settings.radioConsumer] = ["/SpdifMode", 0]
331             self.SPDIFmodeControls[settings.radioProfessional] = ["/SpdifMode", 1]
332
333         # Store a reference to the "save" button for later manipulation
334         self.btnSaveSettings = settings.btnSaveSettings
335
336     def polledUpdate(self):
337         ss = self.streamingstatus.selected()
338
339         # Only alter controls sensitive to the streaming state when the
340         # streaming state has changed.
341         if (ss != self.streaming_state):
342             ss_txt = self.streamingstatus.getEnumLabel(ss)
343             # The device doesn't cope very well if "save settings" is done
344             # while streaming is active
345             self.btnSaveSettings.setEnabled(ss_txt=='Idle')
346
347         self.streaming_state = ss
348
349     def initValues(self):
350         log.debug("Init values")
351
352         for ctrl, info in self.MatrixVolumeControls.items():
353             vol = self.hw.getMatrixMixerValue(self.MatrixVolumeControls[ctrl][0],
354                                                 self.MatrixVolumeControls[ctrl][1],
355                                                 self.MatrixVolumeControls[ctrl][2])
356
357             #vol = 0x01000000-vol
358             log.debug("%s volume is %d" % (ctrl.objectName() , vol))
359             ctrl.setValue(vol)
360
361             # connect the UI element
362             ctrl.valueChanged.connect(self.updateMatrixVolume)
363
364         for ctrl, info in self.MatrixButtonControls.items():
365             state = self.hw.getMatrixMixerValue(self.MatrixButtonControls[ctrl][0],
366                                                 self.MatrixButtonControls[ctrl][1],
367                                                 self.MatrixButtonControls[ctrl][2])
368
369             log.debug("%s state is %d" % (ctrl.objectName() , state))
370             if state:
371                 ctrl.setChecked(True)
372             else:
373                 ctrl.setChecked(False)
374
375             # connect the UI element
376             ctrl.clicked.connect(self.updateMatrixButton)
377
378         for ctrl, info in self.MatrixRotaryControls.items():
379             vol = self.hw.getMatrixMixerValue(self.MatrixRotaryControls[ctrl][0],
380                                                 self.MatrixRotaryControls[ctrl][1],
381                                                 self.MatrixRotaryControls[ctrl][2])
382
383             log.debug("%s value is %d" % (ctrl.objectName(), vol))
384             ctrl.setValue(vol)
385
386             # connect the UI element
387             ctrl.valueChanged.connect(self.updateMatrixRotary)
388
389         for ctrl, info in self.VolumeControls.items():
390             vol = self.hw.getContignuous(self.VolumeControls[ctrl][0])
391
392             #vol = 0x01000000-vol
393             log.debug("%s volume is %d" % (ctrl.objectName() , vol))
394             ctrl.setValue(vol)
395
396             # connect the UI element
397             ctrl.valueChanged.connect(self.updateVolume)
398
399         for ctrl, info in self.SelectorControls.items():
400             state = self.hw.getDiscrete(self.SelectorControls[ctrl][0])
401             log.debug("%s state is %d" % (ctrl.objectName() , state))
402             if state:
403                 ctrl.setChecked(True)
404             else:
405                 ctrl.setChecked(False)
406
407             # connect the UI element
408             ctrl.clicked.connect(self.updateSelector)
409
410         for ctrl, info in self.TriggerControls.items():
411             # connect the UI element
412             ctrl.clicked.connect(self.updateTrigger)
413
414         for ctrl, info in self.SPDIFmodeControls.items():
415             state = self.hw.getDiscrete(self.SPDIFmodeControls[ctrl][0])
416             log.debug("%s state is %d" % (ctrl.objectName() , state))
417             if state == self.SPDIFmodeControls[ctrl][1]:
418                 ctrl.setChecked(True)
419             else:
420                 ctrl.setChecked(False)
421
422             # connect the UI element
423             ctrl.toggled.connect(self.updateSPDIFmodeControl)
424
425         for ctrl, info in self.DigIfaceControls.items():
426             state = self.hw.getDiscrete(self.DigIfaceControls[ctrl][0])
427             # 0/2/3 is available but GUI set 0/1/2
428             if state > 0:
429                 state -= 1
430             ctrl.setCurrentIndex(state)
431             ctrl.activated.connect(self.updateDigIfaceControl)
432
433         for ctrl, info in self.PlbkRouteControls.items():
434             sink = self.PlbkRouteControls[ctrl][1]
435             src = self.hw.getDiscrete(self.PlbkRouteControls[ctrl][0], sink)
436             ctrl.setCurrentIndex(src)
437             self.setStreamLabel(src, sink)
438             ctrl.activated.connect(self.updatePlbkRouteControl)
439
440         self.update_timer = QTimer(self)
441         self.update_timer.timeout.connect(self.polledUpdate)
442         self.update_timer.start(1000)
443         self.streaming_state = -1
444
445 # vim: et
Note: See TracBrowser for help on using the browser.