root/branches/libffado-2.0/support/mixer-qt4/ffado_panelmanager.py

Revision 1364, 11.1 kB (checked in by ppalmers, 12 years ago)

port mixer UI's to Qt4. Make Qt4 the first option to be checked in scons.

Line 
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2005-2008 by Pieter Palmers
4 #               2007-2008 by Arnold Krille
5 #
6 # This file is part of FFADO
7 # FFADO = Free Firewire (pro-)audio drivers for linux
8 #
9 # FFADO is based upon FreeBoB.
10 #
11 # This program is free software: you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation, either version 3 of the License, or
14 # (at your option) any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20 #
21 # You should have received a copy of the GNU General Public License
22 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 #
24 from ffadomixer_config import FFADO_VERSION, FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH
25
26 from PyQt4.QtGui import QFrame, QWidget, QTabWidget, QVBoxLayout
27 from PyQt4.QtCore import QTimer
28
29 from ffado_panelmanagerstatusui import Ui_PanelManagerStatusUI
30
31 from ffado_dbus_util import *
32 from ffado_registration import *
33
34 from mixer_phase88 import *
35 from mixer_phase24 import *
36 from mixer_saffire import SaffireMixer
37 from mixer_saffirepro import SaffireProMixer
38 from mixer_audiofire import AudioFireMixer
39 from mixer_bcoaudio5 import *
40 from mixer_edirolfa66 import *
41 from mixer_edirolfa101 import *
42 from mixer_mackie_onyxmixer import *
43 from mixer_quatafire import *
44 from mixer_motu import *
45 from mixer_dummy import *
46 from mixer_global import GlobalMixer
47
48 use_generic = False
49 try:
50     from mixer_generic import *
51     print "The generic mixer is found, seems to be a developer using ffadomixer..."
52 except ImportError:
53     pass
54 else:
55     use_generic = True
56
57 SupportedDevices=[
58     [(0x000aac, 0x00000003),'Phase88Control'],
59     [(0x000aac, 0x00000004),'Phase24Control'],
60     [(0x000aac, 0x00000007),'Phase24Control'],
61     [(0x00130e, 0x00000003),'SaffireProMixer'],
62     [(0x00130e, 0x00000006),'SaffireProMixer'],
63     [(0x00130e, 0x00000000),'SaffireMixer'],
64     [(0x001486, 0x00000af2),'AudioFireMixer'],
65     [(0x001486, 0x00000af4),'AudioFireMixer'],
66     [(0x001486, 0x00000af8),'AudioFireMixer'],
67     [(0x001486, 0x0000af12),'AudioFireMixer'],
68     [(0x0007f5, 0x00010049),'BCoAudio5Control'],
69     [(0x0040AB, 0x00010049),'EdirolFa66Control'],
70     [(0x0040AB, 0x00010048),'EdirolFa101Control'],
71     [(0x00000f, 0x00010067),'MackieOnyxMixer'],
72     [(0x000f1b, 0x00010064),'QuataFireMixer'],
73     [(0x0001f2, 0x00000000),'MotuMixer'],
74     ]
75
76 # pseudo-guid
77 GUID_GENERIC_MIXER = 0
78
79
80 class HLine( QFrame ):
81     def __init__( self, parent ):
82         QFrame.__init__( self, parent )
83         self.setFrameShape( QFrame.HLine )
84         self.setLineWidth( 2 )
85         self.setMinimumHeight( 10 )
86
87 class PanelManagerStatus(QWidget, Ui_PanelManagerStatusUI):
88     def __init__(self, parent):
89         QWidget.__init__(self,parent)
90         self.setupUi(self)
91
92 class PanelManager(QWidget):
93     def __init__(self, parent, devmgr):
94         QWidget.__init__(self, parent)
95         self.devmgr = devmgr
96         self.devmgr.registerPreUpdateCallback(self.devlistPreUpdate)
97         self.devmgr.registerPostUpdateCallback(self.devlistPostUpdate)
98         self.devmgr.registerUpdateCallback(self.devlistUpdate)
99         self.devmgr.registerDestroyedCallback(self.devmgrDestroyed)
100
101         # maps a device GUID to a QT panel
102         self.panels = {}
103
104         # a layout for ourselves
105         self.layout = QVBoxLayout( self )
106
107         # the tabs
108         self.tabs = QTabWidget(self)
109         self.tabs.hide()
110         self.layout.addWidget(self.tabs)
111
112         # a dialog that is shown during update
113         self.status = PanelManagerStatus(self)
114         self.status.lblMessage.setText("Initializing...")
115         self.layout.addWidget(self.status)
116         self.status.show()
117
118         # live check timer
119         self.alivetimer = QTimer()
120         QObject.connect( self.alivetimer, SIGNAL('timeout()'), self.commCheck )
121         self.alivetimer.start( 2000 )
122
123     def count(self):
124         return self.tabs.count()
125
126     def pollPanels(self):
127         # only when not modifying the tabs
128         if self.tabs.isEnabled():
129             for guid in self.panels.keys():
130                 w = self.panels[guid]
131                 if 'polledUpdate' in dir(w):
132                     try:
133                         w.polledUpdate()
134                     except:
135                         print "error in polled update"
136
137     def devlistPreUpdate(self):
138         print "devlistPreUpdate"
139         self.tabs.setEnabled(False)
140         self.tabs.hide()
141         self.status.lblMessage.setText("Bus reconfiguration in progress, please wait...")
142         self.status.show()
143
144     def devlistPostUpdate(self):
145         print "devlistPostUpdate"
146         self.updatePanels()
147
148     def devlistUpdate(self):
149         print "devlistUpdate"
150
151     def devmgrDestroyed(self):
152         print "devmgrDestroyed"
153         self.alivetimer.stop()
154         self.tabs.setEnabled(False)
155         self.tabs.hide()
156         self.status.lblMessage.setText("DBUS server was shut down, please restart it and restart ffadomixer...")
157         self.status.show()
158
159     def commCheck(self):
160         try:
161             nbDevices = self.devmgr.getNbDevices()
162         except:
163             print "comms lost"
164             self.tabs.setEnabled(False)
165             self.tabs.hide()
166             self.status.lblMessage.setText("Failed to communicate with DBUS server. Please restart it and restart ffadomixer...")
167             self.status.show()
168             self.alivetimer.stop()
169
170     def updatePanels(self):
171         nbDevices = self.devmgr.getNbDevices()
172
173         # list of panels present
174         guids_with_tabs = self.panels.keys()
175
176         # build list of guids on the bus now
177         guids_present = []
178         guid_indexes = {}
179         for idx in range(nbDevices):
180             path = self.devmgr.getDeviceName(idx)
181             cfgrom = ConfigRomInterface(FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH+'/DeviceManager/'+path)
182             guid = cfgrom.getGUID()
183             guids_present.append(guid)
184             guid_indexes[guid] = idx
185
186         # figure out what to remove
187         # the special panel (generic)
188         # that has (pseudo-)GUID 0
189         # is also automatically removed
190         to_remove = []
191         for guid in guids_with_tabs:
192             if not guid in guids_present:
193                 to_remove.append(guid)
194                 print "going to remove %s" % str(guid)
195             else:
196                 print "going to keep %s" % str(guid)
197
198         # figure out what to add
199         to_add = []
200         for guid in guids_present:
201             if not guid in guids_with_tabs:
202                 to_add.append(guid)
203                 print "going to add %s" % str(guid)
204
205         # update the widget
206         for guid in to_remove:
207             w = self.panels[guid]
208             del self.panels[guid] # remove from the list
209             idx = self.tabs.indexOf(w)
210             self.tabs.removeTab(idx)
211             del w # GC might also take care of that
212
213         for guid in to_add:
214             # retrieve the device manager index
215             idx = guid_indexes[guid]
216             path = self.devmgr.getDeviceName(idx)
217             print "Adding device %d: %s" % (idx, path)
218
219             cfgrom = ConfigRomInterface(FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH+'/DeviceManager/'+path)
220             vendorId = cfgrom.getVendorId()
221             modelId = cfgrom.getModelId()
222             unitVersion = cfgrom.getUnitVersion()
223             guid = cfgrom.getGUID()
224             vendorName = cfgrom.getVendorName()
225             modelName = cfgrom.getModelName()
226             print " Found (%s, %X, %X) %s %s" % (str(guid), vendorId, modelId, vendorName, modelName)
227
228             # check whether this has already been registered at ffado.org
229             reg = ffado_registration(FFADO_VERSION, int(guid, 16),
230                                      vendorId, modelId,
231                                      vendorName, modelName)
232             reg.check_for_registration()
233
234             thisdev = (vendorId, modelId);
235             # The MOTU devices use unitVersion to differentiate models.  For the
236             # moment thought we don't need to know precisely which model we're
237             # using.
238             if vendorId == 0x1f2:
239                 thisdev = (vendorId, 0x00000000)
240
241             dev = None
242             for d in SupportedDevices:
243                 if d[0] == thisdev:
244                     dev = d
245
246             w = QWidget( self.tabs )
247             l = QVBoxLayout( w )
248
249             # create a control object
250             hw = ControlInterface(FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH+'/DeviceManager/'+path)
251             clockselect = ClockSelectInterface( FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH+"/DeviceManager/"+path )
252             samplerateselect = SamplerateSelectInterface( FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH+"/DeviceManager/"+path )
253             nickname = TextInterface( FFADO_DBUS_SERVER, FFADO_DBUS_BASEPATH+"/DeviceManager/"+path+"/Generic/Nickname" )
254
255             #
256             # Generic elements for all mixers follow here:
257             #
258             tmp = GlobalMixer( w )
259             tmp.configrom = cfgrom
260             tmp.clockselect = clockselect
261             tmp.samplerateselect = samplerateselect
262             tmp.nickname = nickname
263             tmp.hw = hw
264             tmp.initValues()
265             l.addWidget( tmp, 1 )
266
267             #
268             # Line to separate
269             #
270             l.addWidget( HLine( w ) )
271
272             #
273             # Specific (or dummy) mixer widgets get loaded in the following
274             #
275             if dev != None:
276                 mixerapp = dev[1]
277                 exec( "mixerwidget = "+mixerapp+"( w )" )
278             else:
279                 mixerwidget = DummyMixer( w )
280                 mixerapp = modelName+" (Dummy)"
281
282             #
283             # The same for all mixers
284             #
285             l.addWidget( mixerwidget, 10 )
286             mixerwidget.configrom = cfgrom
287             mixerwidget.clockselect = clockselect
288             mixerwidget.samplerateselect = samplerateselect
289             mixerwidget.nickname = nickname
290             mixerwidget.hw = hw
291             if 'buildMixer' in dir(mixerwidget):
292                 mixerwidget.buildMixer()
293             if 'initValues' in dir(mixerwidget):
294                 mixerwidget.initValues()
295             if 'getDisplayTitle' in dir(mixerwidget):
296                 title = mixerwidget.getDisplayTitle()
297             else:
298                 title = mixerapp
299
300             self.tabs.addTab( w, title )
301             self.panels[guid] = w
302
303         # if there is no panel, add the no-device message
304         # else make sure it is not present
305         if self.count() == 0:
306             self.tabs.hide()
307             self.tabs.setEnabled(False)
308             self.status.lblMessage.setText("No supported device found.")
309             self.status.show()
310         else:
311             self.tabs.show()
312             self.tabs.setEnabled(True)
313             self.status.hide()
314             if use_generic:
315                 #
316                 # Show the generic (development) mixer if it is available
317                 #
318                 w = GenericMixer( devmgr.bus, FFADO_DBUS_SERVER, mw )
319                 self.tabs.addTab( w, "Generic Mixer" )
320                 self.panels[GUID_GENERIC_MIXER] = w
Note: See TracBrowser for help on using the browser.