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

Revision 2428, 14.5 kB (checked in by philippe, 10 years ago)

ffado-dbus: some devices (DICE EAP) update their internal configuration on samplerate modification. When samplerate is changed by another client (jackd), ffado-dbus is unaware of this update. Here is introduced additional controls to check the need for ffado-dbus to update its view of the device configuration.

  • Property svn:mergeinfo set to
Line 
1 #
2 # Copyright (C) 2005-2008 by Pieter Palmers
3 #               2007-2008 by Arnold Krille
4 #
5 # This file is part of FFADO
6 # FFADO = Free Firewire (pro-)audio drivers for linux
7 #
8 # FFADO is based upon FreeBoB.
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 #
23
24 import dbus
25 import dbus.mainloop.qt
26 dbus.mainloop.qt.DBusQtMainLoop(set_as_default=True)
27
28 import logging
29 log = logging.getLogger('dbus')
30
31 class ControlInterface:
32     def __init__(self, servername, basepath):
33         self.basepath=basepath
34         self.servername=servername
35         self.bus=dbus.SessionBus()
36
37     def setContignuous(self, subpath, v, idx=None):
38         try:
39             path = self.basepath + subpath
40             dev = self.bus.get_object(self.servername, path)
41             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Continuous')
42             if idx == None:
43                 dev_cont.setValue(v)
44             else:
45                 dev_cont.setValueIdx(idx,v)
46         except:
47             log.error("Failed to set Continuous %s on server %s" % (path, self.servername))
48
49     def getContignuous(self, subpath, idx=None):
50         try:
51             path = self.basepath + subpath
52             dev = self.bus.get_object(self.servername, path)
53             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Continuous')
54             if idx == None:
55                 return dev_cont.getValue()
56             else:
57                 return dev_cont.getValueIdx(idx)
58         except:
59             log.error("Failed to get Continuous %s on server %s" % (path, self.servername))
60             return 0
61
62     def setDiscrete(self, subpath, v, idx=None):
63         try:
64             path = self.basepath + subpath
65             dev = self.bus.get_object(self.servername, path)
66             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Discrete')
67             if idx == None:
68                 dev_cont.setValue(v)
69             else:
70                 dev_cont.setValueIdx(v, idx)
71         except:
72             log.error("Failed to set Discrete %s on server %s" % (path, self.servername))
73
74     def getDiscrete(self, subpath, idx=None):
75         try:
76             path = self.basepath + subpath
77             dev = self.bus.get_object(self.servername, path)
78             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Discrete')
79             if idx == None:
80                 return dev_cont.getValue()
81             else:
82                 return dev_cont.getValueIdx(idx)
83         except:
84             log.error("Failed to get Discrete %s on server %s" % (path, self.servername))
85             return 0
86
87     def setText(self, subpath, v):
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.Text')
92             dev_cont.setValue(v)
93         except:
94             log.error("Failed to set Text %s on server %s" % (path, self.servername))
95
96     def getText(self, subpath):
97         try:
98             path = self.basepath + subpath
99             dev = self.bus.get_object(self.servername, path)
100             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Text')
101             return dev_cont.getValue()
102         except:
103             log.error("Failed to get Text %s on server %s" % (path, self.servername))
104             return 0
105
106     def setMatrixMixerValue(self, subpath, row, col, v):
107         try:
108             path = self.basepath + subpath
109             dev = self.bus.get_object(self.servername, path)
110             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.MatrixMixer')
111             dev_cont.setValue(row, col, v)
112         except:
113             log.error("Failed to set MatrixMixer %s on server %s" % (path, self.servername))
114
115     def getMatrixMixerValue(self, subpath, row, col):
116         try:
117             path = self.basepath + subpath
118             dev = self.bus.get_object(self.servername, path)
119             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.MatrixMixer')
120             return dev_cont.getValue(row, col)
121         except:
122             log.error("Failed to get MatrixMixer %s on server %s" % (path, self.servername))
123             return 0
124
125     def enumSelect(self, subpath, v):
126         try:
127             path = self.basepath + subpath
128             dev = self.bus.get_object(self.servername, path)
129             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Enum')
130             dev_cont.select(v)
131         except:
132             log.error("Failed to select %s on server %s" % (path, self.servername))
133
134     def enumSelected(self, subpath):
135         try:
136             path = self.basepath + subpath
137             dev = self.bus.get_object(self.servername, path)
138             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Enum')
139             return dev_cont.selected()
140         except:
141             log.error("Failed to get selected enum %s on server %s" % (path, self.servername))
142             return 0
143
144     def enumGetLabel(self, subpath, v):
145         try:
146             path = self.basepath + subpath
147             dev = self.bus.get_object(self.servername, path)
148             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Enum')
149             return dev_cont.getEnumLabel(v)
150         except:
151             log.error("Failed to get enum label %s on server %s" % (path, self.servername))
152             return 0
153
154     def enumCount(self, subpath):
155         try:
156             path = self.basepath + subpath
157             dev = self.bus.get_object(self.servername, path)
158             dev_cont = dbus.Interface(dev, dbus_interface='org.ffado.Control.Element.Enum')
159             return dev_cont.count()
160         except:
161             log.error("Failed to get enum count %s on server %s" % (path, self.servername))
162             return 0
163
164 class DeviceManagerInterface:
165     """ Implementation of the singleton """
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         self.updateSignalHandlers = []
174         self.updateSignalHandlerArgs = {}
175         self.preUpdateSignalHandlers = []
176         self.preUpdateSignalHandlerArgs = {}
177         self.postUpdateSignalHandlers = []
178         self.postUpdateSignalHandlerArgs = {}
179         self.destroyedSignalHandlers = []
180         self.destroyedSignalHandlerArgs = {}
181
182         # signal reception does not work yet since we need a mainloop for that
183         # and qt3 doesn't provide one for python/dbus
184         try:
185             log.debug("connecting to: Updated on %s (server: %s)" % (self.basepath, self.servername))
186             self.dev.connect_to_signal("Updated", self.updateSignal, \
187                                     dbus_interface="org.ffado.Control.Element.Container")
188             self.dev.connect_to_signal("PreUpdate", self.preUpdateSignal, \
189                                     dbus_interface="org.ffado.Control.Element.Container")
190             self.dev.connect_to_signal("PostUpdate", self.postUpdateSignal, \
191                                     dbus_interface="org.ffado.Control.Element.Container")
192             self.dev.connect_to_signal("Destroyed", self.destroyedSignal, \
193                                     dbus_interface="org.ffado.Control.Element.Container")
194
195         except dbus.DBusException:
196             traceback.print_exc()
197
198     def registerPreUpdateCallback(self, callback, arg=None):
199         if not callback in self.preUpdateSignalHandlers:
200             self.preUpdateSignalHandlers.append(callback)
201         # always update the argument
202         self.preUpdateSignalHandlerArgs[callback] = arg
203
204     def registerPostUpdateCallback(self, callback, arg=None):
205         if not callback in self.postUpdateSignalHandlers:
206             self.postUpdateSignalHandlers.append(callback)
207         # always update the argument
208         self.postUpdateSignalHandlerArgs[callback] = arg
209
210     def registerUpdateCallback(self, callback, arg=None):
211         if not callback in self.updateSignalHandlers:
212             self.updateSignalHandlers.append(callback)
213         # always update the argument
214         self.updateSignalHandlerArgs[callback] = arg
215
216     def registerDestroyedCallback(self, callback, arg=None):
217         if not callback in self.destroyedSignalHandlers:
218             self.destroyedSignalHandlers.append(callback)
219         # always update the argument
220         self.destroyedSignalHandlerArgs[callback] = arg
221
222     def updateSignal(self):
223         log.debug("Received update signal")
224         for handler in self.updateSignalHandlers:
225             arg = self.updateSignalHandlerArgs[handler]
226             try:
227                 if arg:
228                     handler(arg)
229                 else:
230                     handler()
231             except:
232                 log.error("Failed to execute handler %s" % handler)
233
234     def preUpdateSignal(self):
235         log.debug("Received pre-update signal")
236         for handler in self.preUpdateSignalHandlers:
237             arg = self.preUpdateSignalHandlerArgs[handler]
238             try:
239                 if arg:
240                     handler(arg)
241                 else:
242                     handler()
243             except:
244                 log.error("Failed to execute handler %s" % handler)
245
246     def postUpdateSignal(self):
247         log.debug("Received post-update signal")
248         for handler in self.postUpdateSignalHandlers:
249             arg = self.postUpdateSignalHandlerArgs[handler]
250             try:
251                 if arg:
252                     handler(arg)
253                 else:
254                     handler()
255             except:
256                 log.error("Failed to execute handler %s" % handler)
257
258     def destroyedSignal(self):
259         log.debug("Received destroyed signal")
260         for handler in self.destroyedSignalHandlers:
261             arg = self.destroyedSignalHandlerArgs[handler]
262             try:
263                 if arg:
264                     handler(arg)
265                 else:
266                     handler()
267             except:
268                 log.error("Failed to execute handler %s" % handler)
269
270     def getNbDevices(self):
271         return self.iface.getNbElements()
272     def getDeviceName(self, idx):
273         return self.iface.getElementName(idx)
274
275 class ConfigRomInterface:
276     def __init__(self, servername, devicepath):
277         self.basepath=devicepath + '/ConfigRom'
278         self.servername=servername
279         self.bus=dbus.SessionBus()
280         self.dev = self.bus.get_object(self.servername, self.basepath)
281         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.ConfigRomX')
282     def getGUID(self):
283         return self.iface.getGUID()
284     def getVendorName(self):
285         return self.iface.getVendorName()
286     def getModelName(self):
287         return self.iface.getModelName()
288     def getVendorId(self):
289         return self.iface.getVendorId()
290     def getModelId(self):
291         return self.iface.getModelId()
292     def getUnitVersion(self):
293         return self.iface.getUnitVersion()
294
295 class ClockSelectInterface:
296     def __init__(self, servername, devicepath):
297         self.basepath=devicepath + '/Generic/ClockSelect'
298         self.servername=servername
299         self.bus=dbus.SessionBus()
300         self.dev = self.bus.get_object(self.servername, self.basepath)
301         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.AttributeEnum')
302         self.iface_element = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Element')
303     def count(self):
304         return self.iface.count()
305     def select(self, idx):
306         return self.iface.select(idx)
307     def selected(self):
308         return self.iface.selected()
309     def getEnumLabel(self, idx):
310         return self.iface.getEnumLabel(idx)
311     def attributeCount(self):
312         return self.iface.attributeCount()
313     def getAttributeValue(self, idx):
314         return self.iface.getAttributeValue(idx)
315     def getAttributeName(self, idx):
316         return self.iface.getAttributeName(idx)
317     def canChangeValue(self):
318         return self.iface_element.canChangeValue()
319
320 class EnumInterface:
321     def __init__(self, servername, basepath):
322         self.basepath = basepath
323         self.servername = servername
324         self.bus = dbus.SessionBus()
325         self.dev = self.bus.get_object(self.servername, self.basepath)
326         self.iface = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Enum')
327         self.iface_element = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Element')
328     def count(self):
329         return self.iface.count()
330     def select(self, idx):
331         return self.iface.select(idx)
332     def selected(self):
333         return self.iface.selected()
334     def getEnumLabel(self, idx):
335         return self.iface.getEnumLabel(idx)
336     def canChangeValue(self):
337         return self.iface_element.canChangeValue()
338     def devConfigChanged(self, idx):
339         return self.iface.devConfigChanged(idx)
340
341 class SamplerateSelectInterface(EnumInterface):
342     def __init__(self, servername, devicepath):
343         EnumInterface.__init__(self, servername, devicepath + '/Generic/SamplerateSelect')
344
345 class StreamingStatusInterface(EnumInterface):
346     def __init__(self, servername, devicepath):
347         EnumInterface.__init__(self, servername, devicepath + '/Generic/StreamingStatus')
348
349 class TextInterface:
350     def __init__(self, servername, basepath):
351         self.basepath=basepath
352         self.servername=servername
353         self.bus=dbus.SessionBus()
354         self.dev = self.bus.get_object( self.servername, self.basepath )
355         self.iface = dbus.Interface( self.dev, dbus_interface="org.ffado.Control.Element.Text" )
356         self.iface_element = dbus.Interface(self.dev, dbus_interface='org.ffado.Control.Element.Element')
357     def text(self):
358         return self.iface.getValue()
359     def setText(self,text):
360         self.iface.setValue(text)
361     def canChangeValue(self):
362         return self.iface_element.canChangeValue()
363
364 # vim: et
Note: See TracBrowser for help on using the browser.