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

Revision 1060, 12.1 kB (checked in by ppalmers, 14 years ago)

- implement (basic) user feedback (fixes #77)
- fix some small issues in the mixer code

  • 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
52 from mixer_generic import *
53
54 SupportedDevices=[
55     [(0x000aac, 0x00000003),'Phase88Control'],
56     [(0x000aac, 0x00000004),'PhaseX24Control'],
57     [(0x000aac, 0x00000007),'PhaseX24Control'],
58     [(0x00130e, 0x00000003),'SaffireProMixer'],
59     [(0x00130e, 0x00000006),'SaffireProMixer'],
60     [(0x00130e, 0x00000000),'SaffireMixer'],
61     [(0x001486, 0x00000af2),'AudioFire2Mixer'],
62     [(0x0007f5, 0x00010049),'BCoAudio5Control'],
63     [(0x0040AB, 0x00010049),'EdirolFa66Control'],
64     [(0x00000f, 0x00010067),'MackieGenericControl'],
65     [(0x000f1b, 0x00010064),'QuataFireMixer'],
66     [(0x0001f2, 0x00000000),'MotuMixer'],
67     ]
68
69 class ControlInterface:
70     def __init__(self, servername, basepath):
71         self.basepath=basepath
72         self.servername=servername
73         self.bus=dbus.SessionBus()
74
75     def setContignuous(self, subpath, v, idx=None):
76         try:
77             path = self.basepath + subpath
78             dev = self.bus.get_object(self.servername, path)
79             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Continuous')
80             if idx == None:
81                 dev_cont.setValue(v)
82             else:
83                 dev_cont.setValueIdx(idx,v)
84         except:
85             print "Failed to set Continuous %s on server %s" % (path, self.servername)
86
87     def getContignuous(self, subpath, idx=None):
88         try:
89             path = self.basepath + subpath
90             dev = self.bus.get_object(self.servername, path)
91             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Continuous')
92             if idx == None:
93                 return dev_cont.getValue()
94             else:
95                 return dev_cont.getValueIdx(idx)
96         except:
97             print "Failed to get Continuous %s on server %s" % (path, self.servername)
98             return 0
99
100     def setDiscrete(self, subpath, v):
101         try:
102             path = self.basepath + subpath
103             dev = self.bus.get_object(self.servername, path)
104             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Discrete')
105             dev_cont.setValue(v)
106         except:
107             print "Failed to set Discrete %s on server %s" % (path, self.servername)
108
109     def getDiscrete(self, subpath):
110         try:
111             path = self.basepath + subpath
112             dev = self.bus.get_object(self.servername, path)
113             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Discrete')
114             return dev_cont.getValue()
115         except:
116             print "Failed to get Discrete %s on server %s" % (path, self.servername)
117             return 0
118
119     def setText(self, subpath, v):
120         try:
121             path = self.basepath + subpath
122             dev = self.bus.get_object(self.servername, path)
123             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Text')
124             dev_cont.setValue(v)
125         except:
126             print "Failed to set Text %s on server %s" % (path, self.servername)
127
128     def getText(self, subpath):
129         try:
130             path = self.basepath + subpath
131             dev = self.bus.get_object(self.servername, path)
132             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Text')
133             return dev_cont.getValue()
134         except:
135             print "Failed to get Text %s on server %s" % (path, self.servername)
136             return 0
137
138     def setMatrixMixerValue(self, subpath, row, col, v):
139         try:
140             path = self.basepath + subpath
141             dev = self.bus.get_object(self.servername, path)
142             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.MatrixMixer')
143             dev_cont.setValue(row, col, v)
144         except:
145             print "Failed to set MatrixMixer %s on server %s" % (path, self.servername)
146
147     def getMatrixMixerValue(self, subpath, row, col):
148         try:
149             path = self.basepath + subpath
150             dev = self.bus.get_object(self.servername, path)
151             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.MatrixMixer')
152             return dev_cont.getValue(row, col)
153         except:
154             print "Failed to get MatrixMixer %s on server %s" % (path, self.servername)
155             return 0
156
157 class DeviceManagerInterface:
158     def __init__(self, servername, basepath):
159         self.basepath=basepath + '/DeviceManager'
160         self.servername=servername
161         self.bus=dbus.SessionBus()
162         self.dev = self.bus.get_object(self.servername, self.basepath)
163         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Container')
164            
165     def getNbDevices(self):
166         return self.iface.getNbElements()
167     def getDeviceName(self, idx):
168         return self.iface.getElementName(idx) 
169
170 class ConfigRomInterface:
171     def __init__(self, servername, devicepath):
172         self.basepath=devicepath + '/ConfigRom'
173         self.servername=servername
174         self.bus=dbus.SessionBus()
175         self.dev = self.bus.get_object(self.servername, self.basepath)
176         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.ConfigRomX')
177     def getGUID(self):
178         return self.iface.getGUID()
179     def getVendorName(self):
180         return self.iface.getVendorName()
181     def getModelName(self):
182         return self.iface.getModelName()
183     def getVendorId(self):
184         return self.iface.getVendorId()
185     def getModelId(self):
186         return self.iface.getModelId()
187     def getUnitVersion(self):
188         return self.iface.getUnitVersion()
189
190 class ClockSelectInterface:
191     def __init__(self, servername, devicepath):
192         self.basepath=devicepath + '/Generic/ClockSelect'
193         self.servername=servername
194         self.bus=dbus.SessionBus()
195         self.dev = self.bus.get_object(self.servername, self.basepath)
196         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.AttributeEnum')
197     def count(self):
198         return self.iface.count()
199     def select(self, idx):
200         return self.iface.select(idx)
201     def selected(self):
202         return self.iface.selected()
203     def getEnumLabel(self, idx):
204         return self.iface.getEnumLabel(idx)
205     def attributeCount(self):
206         return self.iface.attributeCount()
207     def getAttributeValue(self, idx):
208         return self.iface.getAttributeValue(idx)
209     def getAttributeName(self, idx):
210         return self.iface.getAttributeName(idx)
211
212 if __name__ == "__main__":
213    
214     server='org.ffado.Control'
215     basepath='/org/ffado/Control'
216    
217     app = QApplication(sys.argv)
218    
219     msg = QMessageBox()
220
221     repeat = 1
222     while repeat > 0:
223         try:
224             devmgr=DeviceManagerInterface(server, basepath)
225             repeat -= 1
226         except dbus.DBusException, ex:
227             print "\n"
228             print "==========================================================="
229             print "ERROR: Could not communicate with the FFADO DBus service..."
230             print "==========================================================="
231             print "\n"
232             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 )
233             if tmp == 4:
234                 sys.exit(-1)
235             else:
236                 os.spawnlp( os.P_NOWAIT, "ffado-dbus-server" )
237                 nb_checks = 10
238                 while nb_checks > 0:
239                     nb_checks = nb_checks - 1
240                     try:
241                         devmgr=DeviceManagerInterface(server, basepath)
242                         nb_checks = 0
243                         repeat = 0
244                     except dbus.DBusException, ex:
245                         time.sleep( 1 )
246    
247     nbDevices=devmgr.getNbDevices()
248    
249     forms=[];
250     for idx in range(nbDevices):
251         path=devmgr.getDeviceName(idx)
252         print "Found device %d: %s" % (idx, path)
253        
254         cfgrom = ConfigRomInterface(server, basepath+'/DeviceManager/'+path)
255         vendorId = cfgrom.getVendorId()
256         modelId = cfgrom.getModelId()
257         unitVersion = cfgrom.getUnitVersion()
258         GUID = cfgrom.getGUID()
259         vendorName = cfgrom.getVendorName()
260         modelName = cfgrom.getModelName()
261         print " Found (%s, %X, %X) %s %s" % (str(GUID), vendorId, modelId, vendorName, modelName)
262
263         # check whether this has already been registered at ffado.org
264         reg = ffado_registration(FFADO_VERSION, int(GUID, 16),
265                                  vendorId, modelId,
266                                  vendorName, modelName)
267         reg.check_for_registration()
268
269         thisdev=(vendorId, modelId);
270         # The MOTU devices use unitVersion to differentiate models.  For the
271         # moment thought we don't need to know precisely which model we're
272         # using.
273         if vendorId == 0x1f2:
274             thisdev=(vendorId, 0x00000000)
275        
276         found_panel = False
277         for dev in SupportedDevices:
278             if dev[0] == thisdev:
279                 mixerapp = dev[1]
280                
281                 # hack for the focusrite devices
282                 # Saffire:        0x130e010001????
283                 # SaffireLE:    0x130e010004????
284                 if thisdev == (0x00130e, 0x00000000):
285                     if int(GUID, 16) < 0x130e0100040000:
286                         mixerapp = "SaffireMixer"
287                     else:
288                         mixerapp = "SaffireLEMixer"
289                 print mixerapp
290                 exec('forms.append('+mixerapp+'())')
291                 forms[idx].hw = ControlInterface(server, basepath+'/DeviceManager/'+path)
292                 forms[idx].configrom = cfgrom
293                 forms[idx].clockselect = ClockSelectInterface(server, basepath+'/DeviceManager/'+path)
294                 forms[idx].initValues()
295                 forms[idx].show()
296                 found_panel = True
297
298         if not found_panel:
299             forms.append( DummyMixer( ) )
300             forms[idx].hw = ControlInterface(server, basepath+'/DeviceManager/'+path)
301             forms[idx].configrom = cfgrom
302             forms[idx].clockselect = ClockSelectInterface(server, basepath+'/DeviceManager/'+path)
303             forms[idx].initValues()
304             forms[idx].show()
305
306     # note: the generic mixer is disabled for now...
307     use_generic = False # !!! HACK !!!
308     if nbDevices > 0 and use_generic:
309         forms.append( GenericMixer( devmgr.bus, server ) )
310         forms[-1].show()
311
312     if forms:
313         # not setting this makes that the app doesn't quit when the first window is closed
314         #app.setMainWidget(forms[0])
315
316         QObject.connect(app,SIGNAL("lastWindowClosed()"),app,SLOT("quit()"))
317
318         app.exec_loop()
319     else:
320         print "No supported device found..."
321         msg.information( msg, "No mixer found", "Your device doesn't seem to have a supported mixer." )
Note: See TracBrowser for help on using the browser.