root/trunk/libffado/support/mixer/ffadomixer.in

Revision 1094, 13.2 kB (checked in by arnonym, 15 years ago)

White space changes

  • Property svn:executable set to *
Line 
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2005-2007 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
25 import sys
26
27 # Add the path of the installed ffado-mixer-modules
28 sys.path.append( "$PYTHONDIR" )
29
30 from ffadomixer_config import FFADO_VERSION
31
32 import os
33 import time
34 import dbus
35 from qt import *
36
37 from ffado_registration import *
38
39 from mixer_phase88 import *
40 from mixer_phase24 import *
41 from mixer_saffirepro import *
42 from mixer_saffire import *
43 from mixer_saffirele import *
44 from mixer_af2 import *
45 from mixer_bcoaudio5 import *
46 from mixer_edirolfa66 import *
47 from mixer_mackie_generic import *
48 from mixer_quatafire import *
49 from mixer_motu import *
50 from mixer_dummy import *
51 from mixer_global import *
52
53 use_generic = False
54 try:
55     from mixer_generic import *
56     print "The generic mixer is found, seems to be a developer using ffadomixer..."
57 except ImportError:
58     pass
59 else:
60     use_generic = True
61
62 SupportedDevices=[
63     [(0x000aac, 0x00000003),'Phase88Control'],
64     [(0x000aac, 0x00000004),'PhaseX24Control'],
65     [(0x000aac, 0x00000007),'PhaseX24Control'],
66     [(0x00130e, 0x00000003),'SaffireProMixer'],
67     [(0x00130e, 0x00000006),'SaffireProMixer'],
68     [(0x00130e, 0x00000000),'SaffireMixer'],
69     [(0x001486, 0x00000af2),'AudioFire2Mixer'],
70     [(0x0007f5, 0x00010049),'BCoAudio5Control'],
71     [(0x0040AB, 0x00010049),'EdirolFa66Control'],
72     [(0x00000f, 0x00010067),'MackieGenericControl'],
73     [(0x000f1b, 0x00010064),'QuataFireMixer'],
74     [(0x0001f2, 0x00000000),'MotuMixer'],
75     ]
76
77 class ControlInterface:
78     def __init__(self, servername, basepath):
79         self.basepath=basepath
80         self.servername=servername
81         self.bus=dbus.SessionBus()
82
83     def setContignuous(self, subpath, v, idx=None):
84         try:
85             path = self.basepath + subpath
86             dev = self.bus.get_object(self.servername, path)
87             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Continuous')
88             if idx == None:
89                 dev_cont.setValue(v)
90             else:
91                 dev_cont.setValueIdx(idx,v)
92         except:
93             print "Failed to set Continuous %s on server %s" % (path, self.servername)
94
95     def getContignuous(self, subpath, idx=None):
96         try:
97             path = self.basepath + subpath
98             dev = self.bus.get_object(self.servername, path)
99             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Continuous')
100             if idx == None:
101                 return dev_cont.getValue()
102             else:
103                 return dev_cont.getValueIdx(idx)
104         except:
105             print "Failed to get Continuous %s on server %s" % (path, self.servername)
106             return 0
107
108     def setDiscrete(self, subpath, v):
109         try:
110             path = self.basepath + subpath
111             dev = self.bus.get_object(self.servername, path)
112             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Discrete')
113             dev_cont.setValue(v)
114         except:
115             print "Failed to set Discrete %s on server %s" % (path, self.servername)
116
117     def getDiscrete(self, subpath):
118         try:
119             path = self.basepath + subpath
120             dev = self.bus.get_object(self.servername, path)
121             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Discrete')
122             return dev_cont.getValue()
123         except:
124             print "Failed to get Discrete %s on server %s" % (path, self.servername)
125             return 0
126
127     def setText(self, subpath, v):
128         try:
129             path = self.basepath + subpath
130             dev = self.bus.get_object(self.servername, path)
131             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Text')
132             dev_cont.setValue(v)
133         except:
134             print "Failed to set Text %s on server %s" % (path, self.servername)
135
136     def getText(self, subpath):
137         try:
138             path = self.basepath + subpath
139             dev = self.bus.get_object(self.servername, path)
140             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Text')
141             return dev_cont.getValue()
142         except:
143             print "Failed to get Text %s on server %s" % (path, self.servername)
144             return 0
145
146     def setMatrixMixerValue(self, subpath, row, col, v):
147         try:
148             path = self.basepath + subpath
149             dev = self.bus.get_object(self.servername, path)
150             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.MatrixMixer')
151             dev_cont.setValue(row, col, v)
152         except:
153             print "Failed to set MatrixMixer %s on server %s" % (path, self.servername)
154
155     def getMatrixMixerValue(self, subpath, row, col):
156         try:
157             path = self.basepath + subpath
158             dev = self.bus.get_object(self.servername, path)
159             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.MatrixMixer')
160             return dev_cont.getValue(row, col)
161         except:
162             print "Failed to get MatrixMixer %s on server %s" % (path, self.servername)
163             return 0
164
165 class DeviceManagerInterface:
166     def __init__(self, servername, basepath):
167         self.basepath=basepath + '/DeviceManager'
168         self.servername=servername
169         self.bus=dbus.SessionBus()
170         self.dev = self.bus.get_object(self.servername, self.basepath)
171         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Container')
172
173     def getNbDevices(self):
174         return self.iface.getNbElements()
175     def getDeviceName(self, idx):
176         return self.iface.getElementName(idx) 
177
178 class ConfigRomInterface:
179     def __init__(self, servername, devicepath):
180         self.basepath=devicepath + '/ConfigRom'
181         self.servername=servername
182         self.bus=dbus.SessionBus()
183         self.dev = self.bus.get_object(self.servername, self.basepath)
184         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.ConfigRomX')
185     def getGUID(self):
186         return self.iface.getGUID()
187     def getVendorName(self):
188         return self.iface.getVendorName()
189     def getModelName(self):
190         return self.iface.getModelName()
191     def getVendorId(self):
192         return self.iface.getVendorId()
193     def getModelId(self):
194         return self.iface.getModelId()
195     def getUnitVersion(self):
196         return self.iface.getUnitVersion()
197
198 class ClockSelectInterface:
199     def __init__(self, servername, devicepath):
200         self.basepath=devicepath + '/Generic/ClockSelect'
201         self.servername=servername
202         self.bus=dbus.SessionBus()
203         self.dev = self.bus.get_object(self.servername, self.basepath)
204         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.AttributeEnum')
205     def count(self):
206         return self.iface.count()
207     def select(self, idx):
208         return self.iface.select(idx)
209     def selected(self):
210         return self.iface.selected()
211     def getEnumLabel(self, idx):
212         return self.iface.getEnumLabel(idx)
213     def attributeCount(self):
214         return self.iface.attributeCount()
215     def getAttributeValue(self, idx):
216         return self.iface.getAttributeValue(idx)
217     def getAttributeName(self, idx):
218         return self.iface.getAttributeName(idx)
219
220 class TextInterface:
221     def __init__(self, servername, basepath):
222         self.basepath=basepath
223         self.servername=servername
224         self.bus=dbus.SessionBus()
225         self.dev = self.bus.get_object( self.servername, self.basepath )
226         self.iface = dbus.Interface( self.dev, dbus_interface="org.ffado.Control.Element.Text" )
227
228     def text(self):
229         return self.iface.getValue()
230
231     def setText(self,text):
232         self.iface.setValue(text)
233
234 class HLine( QFrame ):
235     def __init__( self, parent ):
236         QFrame.__init__( self, parent )
237         self.setFrameShape( QFrame.HLine )
238         self.setLineWidth( 2 )
239         self.setMinimumHeight( 10 )
240
241 if __name__ == "__main__":
242
243     server='org.ffado.Control'
244     basepath='/org/ffado/Control'
245
246     app = QApplication(sys.argv)
247
248     msg = QMessageBox()
249
250     repeat = 1
251     while repeat > 0:
252         try:
253             devmgr=DeviceManagerInterface(server, basepath)
254             repeat -= 1
255         except dbus.DBusException, ex:
256             print "\n"
257             print "==========================================================="
258             print "ERROR: Could not communicate with the FFADO DBus service..."
259             print "==========================================================="
260             print "\n"
261             tmp = msg.question( msg, "FFADO-DBus not found", "<qt><b>The connection to FFADOs DBus service could not be established.</b><p>Probably you didn't start the ffado-dbus-server. Should I try this now?</qt>", QMessageBox.Yes, QMessageBox.No )
262             if tmp == 4:
263                 sys.exit(-1)
264             else:
265                 os.spawnlp( os.P_NOWAIT, "ffado-dbus-server" )
266                 nb_checks = 10
267                 while nb_checks > 0:
268                     nb_checks = nb_checks - 1
269                     try:
270                         devmgr=DeviceManagerInterface(server, basepath)
271                         nb_checks = 0
272                         repeat = 0
273                     except dbus.DBusException, ex:
274                         time.sleep( 1 )
275
276     nbDevices=devmgr.getNbDevices()
277
278     if nbDevices == 0:
279         print "No supported device found..."
280         msg.information( msg, "No mixer found", "Your device doesn't seem to have a supported mixer." )
281         sys.exit( -1 )
282
283     mw = QTabWidget()
284
285     for idx in range(nbDevices):
286         path=devmgr.getDeviceName(idx)
287         print "Found device %d: %s" % (idx, path)
288
289         cfgrom = ConfigRomInterface(server, basepath+'/DeviceManager/'+path)
290         vendorId = cfgrom.getVendorId()
291         modelId = cfgrom.getModelId()
292         unitVersion = cfgrom.getUnitVersion()
293         GUID = cfgrom.getGUID()
294         vendorName = cfgrom.getVendorName()
295         modelName = cfgrom.getModelName()
296         print " Found (%s, %X, %X) %s %s" % (str(GUID), vendorId, modelId, vendorName, modelName)
297
298         # check whether this has already been registered at ffado.org
299         reg = ffado_registration(FFADO_VERSION, int(GUID, 16),
300                                  vendorId, modelId,
301                                  vendorName, modelName)
302         reg.check_for_registration()
303
304         thisdev=(vendorId, modelId);
305         # The MOTU devices use unitVersion to differentiate models.  For the
306         # moment thought we don't need to know precisely which model we're
307         # using.
308         if vendorId == 0x1f2:
309             thisdev=(vendorId, 0x00000000)
310
311         dev = None
312         for d in SupportedDevices:
313             if d[0] == thisdev:
314                 dev = d
315
316         w = QWidget( mw )
317         l = QVBoxLayout( w )
318
319         #
320         # Generic elements for all mixers follow here:
321         #
322
323         tmp = GlobalMixer( w )
324         tmp.clockselect = ClockSelectInterface( server, basepath+"/DeviceManager/"+path )
325         tmp.nickname = TextInterface( server, basepath+"/DeviceManager/"+path+"/Generic/Nickname" )
326         tmp.initValues()
327         l.addWidget( tmp, 1 )
328
329         #
330         # Line to separate
331         #
332         l.addWidget( HLine( w ) )
333
334         #
335         # Specific (or dummy) mixer widgets get loaded in the following
336         #
337         if dev != None:
338             mixerapp = dev[1]
339             # hack for the focusrite devices
340             # Saffire:        0x130e010001????
341             # SaffireLE:    0x130e010004????
342             if thisdev == (0x00130e, 0x00000000):
343                 if int(GUID, 16) < 0x130e0100040000:
344                     mixerapp = "SaffireMixer"
345                 else:
346                     mixerapp = "SaffireLEMixer"
347
348             exec( "mixerwidget = "+mixerapp+"( w )" )
349
350         else:
351             mixerwidget = DummyMixer( w )
352             mixerapp = modelName+" (Dummy)"
353
354         #
355         # The same for all mixers
356         #
357         l.addWidget( mixerwidget, 10 )
358         mixerwidget.hw = ControlInterface(server, basepath+'/DeviceManager/'+path)
359         mixerwidget.configrom = cfgrom
360         mixerwidget.clockselect = ClockSelectInterface(server, basepath+'/DeviceManager/'+path)
361         mixerwidget.initValues()
362         mw.addTab( w, mixerapp )
363
364     #
365     # Show the generic (development) mixer if it is available
366     #
367     if nbDevices > 0 and use_generic:
368         mw.addTab( GenericMixer( devmgr.bus, server, mw ), "Generic Mixer" )
369
370     #
371     # Only really show the mainwindow and start the mixer when at least on mixer is shown
372     #
373     if mw.count() > 0:
374         mw.show()
375
376         QObject.connect(app,SIGNAL("lastWindowClosed()"),app,SLOT("quit()"))
377
378         app.exec_loop()
379
Note: See TracBrowser for help on using the browser.