root/trunk/libffado/support/mixer/mixer_motu.py

Revision 1141, 14.5 kB (checked in by jwoithe, 16 years ago)

* MOTU: Activate the mix-1 channel controls for ADAT, AES/EBU and SPDIF channels to facilitate further testing.

Line 
1 #
2 # Copyright (C) 2005-2008 by Pieter Palmers
3 # Copyright (C) 2008 by Jonathan Woithe
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 2 of the License, or
13 # (at your option) version 3 of the License.
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 from qt import *
25 from mixer_motuui import *
26
27 class MotuMixer(MotuMixerUI):
28     def __init__(self,parent = None,name = None,fl = 0):
29         MotuMixerUI.__init__(self,parent,name,fl)
30
31     # public slot: channel/mix faders
32     def updateFader(self, a0):
33         sender = self.sender()
34         vol = 128-a0
35         print "setting %s channel/mix fader to %d" % (self.ChannelFaders[sender][0], vol)
36         self.hw.setDiscrete(self.ChannelFaders[sender][0], vol)
37
38     # public slot: a generic multivalue control
39     def updateControl(self, a0):
40         sender = self.sender()
41         val = a0
42         print "setting %s control to %d" % (self.Controls[sender][0], val)
43         self.hw.setDiscrete(self.Controls[sender][0], val)
44
45     # public slot: generic binary switch
46     def updateBinarySwitch(self, a0):
47         sender = self.sender()
48         val=a0
49         print "setting %s switch to %d" % (self.BinarySwitches[sender][0], val)
50         self.hw.setDiscrete(self.BinarySwitches[sender][0], val)
51
52     # public slot: mix destination control
53     def updateMixDest(self, a0):
54         sender = self.sender()
55         dest=a0
56         print "setting %s mix destination to %d" % (self.MixDests[sender][0], dest)
57         self.hw.setDiscrete(self.MixDests[sender][0], dest)
58
59     # public slots: mix output controls
60     def set_mix1_dest(self,a0):
61         self.setMixDest('mix1', a0)
62
63     def setSelector(self,a0,a1):
64         name=a0
65         state = a1
66         print "setting %s state to %d" % (name, state)
67         self.hw.setDiscrete(self.SelectorControls[name][0], state)
68
69     def init(self):
70         print "Init MOTU mixer window"
71
72         self.ChannelFaders={
73             self.mix1ana1_fader: ['/Mixer/Mix1/Ana1_fader'],
74             self.mix1ana2_fader: ['/Mixer/Mix1/Ana2_fader'],
75             self.mix1ana3_fader: ['/Mixer/Mix1/Ana3_fader'],
76             self.mix1ana4_fader: ['/Mixer/Mix1/Ana4_fader'],
77             self.mix1ana5_fader: ['/Mixer/Mix1/Ana5_fader'],
78             self.mix1ana6_fader: ['/Mixer/Mix1/Ana6_fader'],
79             self.mix1ana7_fader: ['/Mixer/Mix1/Ana7_fader'],
80             self.mix1ana8_fader: ['/Mixer/Mix1/Ana8_fader'],
81             self.mix1adat1_fader: ['/Mixer/Mix1/Adat1_fader'],
82             self.mix1adat2_fader: ['/Mixer/Mix1/Adat2_fader'],
83             self.mix1adat3_fader: ['/Mixer/Mix1/Adat3_fader'],
84             self.mix1adat4_fader: ['/Mixer/Mix1/Adat4_fader'],
85             self.mix1adat5_fader: ['/Mixer/Mix1/Adat5_fader'],
86             self.mix1adat6_fader: ['/Mixer/Mix1/Adat6_fader'],
87             self.mix1adat7_fader: ['/Mixer/Mix1/Adat7_fader'],
88             self.mix1adat8_fader: ['/Mixer/Mix1/Adat8_fader'],
89             self.mix1aes1_fader:  ['/Mixer/Mix1/Aes1_fader'],
90             self.mix1aes2_fader:  ['/Mixer/Mix1/Aes2_fader'],
91             self.mix1spdif1_fader: ['/Mixer/Mix1/Spdif1_fader'],
92             self.mix1spdif2_fader: ['/Mixer/Mix1/Spdif2_fader'],
93             self.mix1_fader: ['/Mixer/Mix1/Mix_fader'],
94             }
95
96         self.Controls={
97             self.mix1ana1_pan:   ['/Mixer/Mix1/Ana1_pan'],
98             self.mix1ana2_pan:   ['/Mixer/Mix1/Ana2_pan'],
99             self.mix1ana3_pan:   ['/Mixer/Mix1/Ana3_pan'],
100             self.mix1ana4_pan:   ['/Mixer/Mix1/Ana4_pan'],
101             self.mix1ana5_pan:   ['/Mixer/Mix1/Ana5_pan'],
102             self.mix1ana6_pan:   ['/Mixer/Mix1/Ana6_pan'],
103             self.mix1ana7_pan:   ['/Mixer/Mix1/Ana7_pan'],
104             self.mix1ana8_pan:   ['/Mixer/Mix1/Ana8_pan'],
105             self.mix1adat1_pan:  ['/Mixer/Mix1/Adat1_pan'],
106             self.mix1adat2_pan:  ['/Mixer/Mix1/Adat2_pan'],
107             self.mix1adat3_pan:  ['/Mixer/Mix1/Adat3_pan'],
108             self.mix1adat4_pan:  ['/Mixer/Mix1/Adat4_pan'],
109             self.mix1adat5_pan:  ['/Mixer/Mix1/Adat5_pan'],
110             self.mix1adat6_pan:  ['/Mixer/Mix1/Adat6_pan'],
111             self.mix1adat7_pan:  ['/Mixer/Mix1/Adat7_pan'],
112             self.mix1adat8_pan:  ['/Mixer/Mix1/Adat8_pan'],
113             self.mix1aes1_pan:   ['/Mixer/Mix1/Aes1_pan'],
114             self.mix1aes2_pan:   ['/Mixer/Mix1/Aes2_pan'],
115             self.mix1spdif1_pan:  ['/Mixer/Mix1/Spdif1_pan'],
116             self.mix1spdif2_pan:  ['/Mixer/Mix1/Spdif2_pan'],
117
118             self.ana1_trimgain:  ['/Mixer/Control/Ana1_trimgain'],
119             self.ana2_trimgain:  ['/Mixer/Control/Ana2_trimgain'],
120             self.ana3_trimgain:  ['/Mixer/Control/Ana3_trimgain'],
121             self.ana4_trimgain:  ['/Mixer/Control/Ana4_trimgain'],
122         }
123
124         self.BinarySwitches={
125             self.mix1ana1_mute:  ['/Mixer/Mix1/Ana1_mute'],
126             self.mix1ana2_mute:  ['/Mixer/Mix1/Ana2_mute'],
127             self.mix1ana3_mute:  ['/Mixer/Mix1/Ana3_mute'],
128             self.mix1ana4_mute:  ['/Mixer/Mix1/Ana4_mute'],
129             self.mix1ana5_mute:  ['/Mixer/Mix1/Ana5_mute'],
130             self.mix1ana6_mute:  ['/Mixer/Mix1/Ana6_mute'],
131             self.mix1ana7_mute:  ['/Mixer/Mix1/Ana7_mute'],
132             self.mix1ana8_mute:  ['/Mixer/Mix1/Ana8_mute'],
133             self.mix1ana1_solo:  ['/Mixer/Mix1/Ana1_solo'],
134             self.mix1ana2_solo:  ['/Mixer/Mix1/Ana2_solo'],
135             self.mix1ana3_solo:  ['/Mixer/Mix1/Ana3_solo'],
136             self.mix1ana4_solo:  ['/Mixer/Mix1/Ana4_solo'],
137             self.mix1ana5_solo:  ['/Mixer/Mix1/Ana5_solo'],
138             self.mix1ana6_solo:  ['/Mixer/Mix1/Ana6_solo'],
139             self.mix1ana7_solo:  ['/Mixer/Mix1/Ana7_solo'],
140             self.mix1ana8_solo:  ['/Mixer/Mix1/Ana8_solo'],
141             self.mix1adat1_mute: ['/Mixer/Mix1/Adat1_mute'],
142             self.mix1adat2_mute: ['/Mixer/Mix1/Adat2_mute'],
143             self.mix1adat3_mute: ['/Mixer/Mix1/Adat3_mute'],
144             self.mix1adat4_mute: ['/Mixer/Mix1/Adat4_mute'],
145             self.mix1adat5_mute: ['/Mixer/Mix1/Adat5_mute'],
146             self.mix1adat6_mute: ['/Mixer/Mix1/Adat6_mute'],
147             self.mix1adat7_mute: ['/Mixer/Mix1/Adat7_mute'],
148             self.mix1adat8_mute: ['/Mixer/Mix1/Adat8_mute'],
149             self.mix1adat1_solo: ['/Mixer/Mix1/Adat1_solo'],
150             self.mix1adat2_solo: ['/Mixer/Mix1/Adat2_solo'],
151             self.mix1adat3_solo: ['/Mixer/Mix1/Adat3_solo'],
152             self.mix1adat4_solo: ['/Mixer/Mix1/Adat4_solo'],
153             self.mix1adat5_solo: ['/Mixer/Mix1/Adat5_solo'],
154             self.mix1adat6_solo: ['/Mixer/Mix1/Adat6_solo'],
155             self.mix1adat7_solo: ['/Mixer/Mix1/Adat7_solo'],
156             self.mix1adat8_solo: ['/Mixer/Mix1/Adat8_solo'],
157             self.mix1aes1_mute:  ['/Mixer/Mix1/Aes1_mute'],
158             self.mix1aes2_mute:  ['/Mixer/Mix1/Aes2_mute'],
159             self.mix1aes1_solo:  ['/Mixer/Mix1/Aes1_solo'],
160             self.mix1aes2_solo:  ['/Mixer/Mix1/Aes2_solo'],
161             self.mix1spdif1_mute: ['/Mixer/Mix1/Spdif1_mute'],
162             self.mix1spdif2_mute: ['/Mixer/Mix1/Spdif2_mute'],
163             self.mix1spdif1_solo: ['/Mixer/Mix1/Spdif1_solo'],
164             self.mix1spdif2_solo: ['/Mixer/Mix1/Spdif2_solo'],
165             self.mix1_mute:      ['/Mixer/Mix1/Mix_mute'],
166             self.ana1_pad:       ['/Mixer/Control/Ana1_pad'],
167             self.ana2_pad:       ['/Mixer/Control/Ana2_pad'],
168             self.ana3_pad:       ['/Mixer/Control/Ana3_pad'],
169             self.ana4_pad:       ['/Mixer/Control/Ana4_pad'],
170             self.ana5_level:     ['/Mixer/Control/Ana5_level'],
171             self.ana6_level:     ['/Mixer/Control/Ana6_level'],
172             self.ana7_level:     ['/Mixer/Control/Ana7_level'],
173             self.ana8_level:     ['/Mixer/Control/Ana8_level'],
174             self.ana5_boost:     ['/Mixer/Control/Ana5_boost'],
175             self.ana6_boost:     ['/Mixer/Control/Ana6_boost'],
176             self.ana7_boost:     ['/Mixer/Control/Ana7_boost'],
177             self.ana8_boost:     ['/Mixer/Control/Ana8_boost'],
178         }
179
180         # Ultimately these may be rolled into the BinarySwitches controls,
181         # but since they aren't implemented and therefore need to be
182         # disabled it's easier to keep them separate for the moment.
183         self.PairSwitches={
184             self.mix1ana1_2_pair:   ['Mixer/Mix1/Ana1_2_pair'],
185             self.mix1ana3_4_pair:   ['Mixer/Mix1/Ana3_4_pair'],
186             self.mix1ana5_6_pair:   ['Mixer/Mix1/Ana5_6_pair'],
187             self.mix1ana7_8_pair:   ['Mixer/Mix1/Ana7_8_pair'],
188             self.mix1aes1_2_pair:   ['Mixer/Mix1/Aes1_2_pair'],
189             self.mix1adat1_2_pair:  ['Mixer/Mix1/Adat1_2_pair'],
190             self.mix1adat3_4_pair:  ['Mixer/Mix1/Adat3_4_pair'],
191             self.mix1adat5_6_pair:  ['Mixer/Mix1/Adat5_6_pair'],
192             self.mix1adat7_8_pair:  ['Mixer/Mix1/Adat7_8_pair'],
193             self.mix1spdif1_2_pair: ['Mixer/Mix1/Spdif1_2_pair'],
194         }
195
196         self.MixDests={
197             self.mix1_dest:      ['/Mixer/Mix1/Mix_dest'],
198
199             self.phones_src:     ['/Mixer/Control/Phones_src'],
200
201             self.optical_in_mode:   ['/Mixer/Control/OpticalIn_mode'],
202             self.optical_out_mode:  ['/Mixer/Control/OpticalOut_mode'],
203         }
204
205         self.SelectorControls={
206
207         }
208
209         # Other mixer variables
210         self.is_streaming = 0
211         self.sample_rate = 0
212
213     def initValues(self):
214         # Is the device streaming?
215         self.is_streaming = self.hw.getDiscrete('/Mixer/Info/IsStreaming')
216         print "device streaming flag: %d" % (self.is_streaming)
217
218         # Retrieve other device settings as needed
219         self.sample_rate = self.hw.getDiscrete('/Mixer/Info/SampleRate')
220         print "device sample rate: %d" % (self.sample_rate)
221         self.has_mic_inputs = self.hw.getDiscrete('/Mixer/Info/HasMicInputs')
222         print "device has mic inputs: %d" % (self.has_mic_inputs)
223         self.has_aesebu_inputs = self.hw.getDiscrete('/Mixer/Info/HasAESEBUInputs')
224         print "device has AES/EBU inputs: %d" % (self.has_aesebu_inputs)
225         self.has_spdif_inputs = self.hw.getDiscrete('/Mixer/Info/HasSPDIFInputs')
226         print "device has SPDIF inputs: %d" % (self.has_spdif_inputs)
227         self.has_optical_spdif = self.hw.getDiscrete('/Mixer/Info/HasOpticalSPDIF')
228         print "device has optical SPDIF: %d" % (self.has_optical_spdif)
229
230         # Customise the UI based on device options retrieved
231         if (self.has_mic_inputs):
232             # Mic input controls displace AES/EBU since no current device
233             # has both.
234             self.mix1_aes_group.setTitle("Mic inputs")
235             # FIXME: when implmented, will mic channels just reuse the AES/EBU
236             # dbus path?  If not we'll have to reset the respective values in
237             # the control arrays (self.ChannelFaders etc).
238         else:
239             if (not(self.has_aesebu_inputs)):
240                 self.mix1_aes_group.setEnabled(False)
241         if (not(self.has_spdif_inputs)):
242             self.mix1_spdif_group.setEnabled(False)
243
244         # Some devices don't have the option of selecting an optical SPDIF
245         # mode.
246         if (not(self.has_optical_spdif)):
247             self.optical_in_mode.removeItem(2)
248             self.optical_out_mode.removeItem(2)
249
250         # Some controls must be disabled if the device is streaming
251         if (self.is_streaming):
252             print "Disabling controls which require inactive streaming"
253             self.optical_in_mode.setEnabled(False)
254             self.optical_out_mode.setEnabled(False)
255
256         # Some channels aren't available at higher sampling rates
257         if (self.sample_rate > 96000):
258             print "Disabling controls not present above 96 kHz"
259             self.mix1_adat_group.setEnabled(False)
260             self.mix1_aes_group.setEnabled(False)
261             self.mix1_spdif_group.setEnabled(False)
262         if (self.sample_rate > 48000):
263             print "Disabling controls not present above 48 kHz"
264             self.mix1_adat58_group.setEnabled(False)
265
266         # Now fetch the current values into the respective controls.  Don't
267         # bother fetching controls which are disabled.
268         for ctrl, info in self.ChannelFaders.iteritems():
269             if (not(ctrl.isEnabled())):
270                 continue
271             vol = 128-self.hw.getDiscrete(info[0])
272             print "%s channel fader is %d" % (info[0] , vol)
273             ctrl.setValue(vol)
274             QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateFader)
275
276         for ctrl, info in self.Controls.iteritems():
277             if (not(ctrl.isEnabled())):
278                 continue
279             pan = self.hw.getDiscrete(info[0])
280             print "%s control is %d" % (info[0] , pan)
281             ctrl.setValue(pan)
282             QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateControl)
283
284         # Disable the channel pair controls since they aren't yet implemented
285         for ctrl, info in self.PairSwitches.iteritems():
286             print "%s control is not implemented yet: disabling" % (info[0])
287             ctrl.setEnabled(False)
288
289         for ctrl, info in self.BinarySwitches.iteritems():
290             if (not(ctrl.isEnabled())):
291                 continue
292             val = self.hw.getDiscrete(info[0])
293             print "%s switch is %d" % (info[0] , val)
294             ctrl.setChecked(val)
295             QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateBinarySwitch)
296
297         for ctrl, info in self.MixDests.iteritems():
298             if (not(ctrl.isEnabled())):
299                 continue
300             dest = self.hw.getDiscrete(info[0])
301             print "%s mix destination is %d" % (info[0] , dest)
302             ctrl.setCurrentItem(dest)
303             QObject.connect(ctrl, SIGNAL('activated(int)'), self.updateMixDest)
304
305         for name, ctrl in self.SelectorControls.iteritems():
306             state = self.hw.getDiscrete(ctrl[0])
307             print "%s state is %d" % (name , state)
308             ctrl[1].setCurrentItem(state)   
309
310         # FIXME: If optical mode is not ADAT, disable ADAT controls here.
311         # It can't be done earlier because we need the current values of the
312         # ADAT channel controls in case the user goes ahead and enables the
313         # ADAT optical mode.
Note: See TracBrowser for help on using the browser.