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

Revision 994, 11.0 kB (checked in by arnonym, 16 years ago)

No more "Sorry, no supported mixer found."!

Implement a first generic mixer ui.

The layout isn't yet that good, the faders don't work (since I don't have a device with a supported mixer, I can't test that) and there is not yet special support for ConfigRom? or DiscreteValues?. More to come in the next days...

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