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

Revision 1056, 10.1 kB (checked in by jwoithe, 16 years ago)

* MOTU: Make optical mode control functional. It still needs to have the toslink option disabled for the likes of the 896HD which don't have this capability.
* MOTU: Implement channel pad and trimgain controls.
* MOTU: Minor updates to protocol documentation.

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,modal = 0,fl = 0):
29         MotuMixerUI.__init__(self,parent,name,modal,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: channel pan
39     def updatePan(self, a0):
40         sender = self.sender()
41         pan = a0
42         print "setting %s channel pan to %d" % (self.ChannelPans[sender][0], pan)
43         self.hw.setDiscrete(self.ChannelPans[sender][0], pan)
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.mix1_fader: ['/Mixer/Mix1/Mix_fader'],
82             }
83
84         self.ChannelPans={
85             self.mix1ana1_pan:   ['/Mixer/Mix1/Ana1_pan'],
86             self.mix1ana2_pan:   ['/Mixer/Mix1/Ana2_pan'],
87             self.mix1ana3_pan:   ['/Mixer/Mix1/Ana3_pan'],
88             self.mix1ana4_pan:   ['/Mixer/Mix1/Ana4_pan'],
89             self.mix1ana5_pan:   ['/Mixer/Mix1/Ana5_pan'],
90             self.mix1ana6_pan:   ['/Mixer/Mix1/Ana6_pan'],
91             self.mix1ana7_pan:   ['/Mixer/Mix1/Ana7_pan'],
92             self.mix1ana8_pan:   ['/Mixer/Mix1/Ana8_pan'],
93
94             self.ana1_trimgain:  ['/Mixer/Control/Ana1_trimgain'],
95             self.ana2_trimgain:  ['/Mixer/Control/Ana2_trimgain'],
96             self.ana3_trimgain:  ['/Mixer/Control/Ana3_trimgain'],
97             self.ana4_trimgain:  ['/Mixer/Control/Ana4_trimgain'],
98         }
99
100         self.BinarySwitches={
101             self.mix1ana1_mute:  ['/Mixer/Mix1/Ana1_mute'],
102             self.mix1ana2_mute:  ['/Mixer/Mix1/Ana2_mute'],
103             self.mix1ana3_mute:  ['/Mixer/Mix1/Ana3_mute'],
104             self.mix1ana4_mute:  ['/Mixer/Mix1/Ana4_mute'],
105             self.mix1ana5_mute:  ['/Mixer/Mix1/Ana5_mute'],
106             self.mix1ana6_mute:  ['/Mixer/Mix1/Ana6_mute'],
107             self.mix1ana7_mute:  ['/Mixer/Mix1/Ana7_mute'],
108             self.mix1ana8_mute:  ['/Mixer/Mix1/Ana8_mute'],
109             self.mix1_mute:  ['/Mixer/Mix1/Mix_mute'],
110             self.mix1ana1_solo:  ['/Mixer/Mix1/Ana1_solo'],
111             self.mix1ana2_solo:  ['/Mixer/Mix1/Ana2_solo'],
112             self.mix1ana3_solo:  ['/Mixer/Mix1/Ana3_solo'],
113             self.mix1ana4_solo:  ['/Mixer/Mix1/Ana4_solo'],
114             self.mix1ana5_solo:  ['/Mixer/Mix1/Ana5_solo'],
115             self.mix1ana6_solo:  ['/Mixer/Mix1/Ana6_solo'],
116             self.mix1ana7_solo:  ['/Mixer/Mix1/Ana7_solo'],
117             self.mix1ana8_solo:  ['/Mixer/Mix1/Ana8_solo'],
118             self.ana1_pad:       ['/Mixer/Control/Ana1_pad'],
119             self.ana2_pad:       ['/Mixer/Control/Ana2_pad'],
120             self.ana3_pad:       ['/Mixer/Control/Ana3_pad'],
121             self.ana4_pad:       ['/Mixer/Control/Ana4_pad'],
122             self.ana5_level:     ['/Mixer/Control/Ana5_level'],
123             self.ana6_level:     ['/Mixer/Control/Ana6_level'],
124             self.ana7_level:     ['/Mixer/Control/Ana7_level'],
125             self.ana8_level:     ['/Mixer/Control/Ana8_level'],
126             self.ana5_boost:     ['/Mixer/Control/Ana5_boost'],
127             self.ana6_boost:     ['/Mixer/Control/Ana6_boost'],
128             self.ana7_boost:     ['/Mixer/Control/Ana7_boost'],
129             self.ana8_boost:     ['/Mixer/Control/Ana8_boost'],
130         }
131
132         self.MixDests={
133             self.mix1_dest:      ['/Mixer/Mix1/Mix_dest'],
134
135             self.phones_src:     ['/Mixer/Control/Phones_src'],
136
137             self.optical_in_mode:   ['/Mixer/Control/OpticalIn_mode'],
138             self.optical_out_mode:  ['/Mixer/Control/OpticalOut_mode'],
139         }
140
141         self.SelectorControls={
142
143         }
144
145         # Other mixer variables
146         self.is_streaming = 0
147         self.sample_rate = 0
148
149     def initValues(self):
150         # Is the device streaming?
151         self.is_streaming = self.hw.getDiscrete('/Mixer/Info/IsStreaming')
152         print "device streaming flag: %d" % (self.is_streaming)
153
154         # Retrieve other device settings as needed
155         self.sample_rate = self.hw.getDiscrete('/Mixer/Info/SampleRate')
156         print "device sample rate: %d" % (self.sample_rate)
157         self.has_mic_inputs = self.hw.getDiscrete('/Mixer/Info/HasMicInputs')
158         print "device has mic inputs: %d" % (self.has_mic_inputs)
159         self.has_aesebu_inputs = self.hw.getDiscrete('/Mixer/Info/HasAESEBUInputs')
160         print "device has AES/EBU inputs: %d" % (self.has_aesebu_inputs)
161         self.has_spdif_inputs = self.hw.getDiscrete('/Mixer/Info/HasSPDIFInputs')
162         print "device has SPDIF inputs: %d" % (self.has_spdif_inputs)
163
164         # Customise the UI based on device options retrieved
165         if (self.has_mic_inputs):
166             # Mic input controls displace AES/EBU since no current device
167             # has both.
168             self.mix1_aes_group.setTitle("Mic inputs")
169             # FIXME: when implmented, will mic channels just reuse the AES/EBU
170             # dbus path?  If not we'll have to reset the respective values in
171             # the control arrays (self.ChannelFaders etc).
172         else:
173             if (not(self.has_aesebu_inputs)):
174                 self.mix1_aes_group.setEnabled(False)
175         if (not(self.has_spdif_inputs)):
176             self.mix1_spdif_group.setEnabled(False)
177
178         # Some controls must be disabled if the device is streaming
179         if (self.is_streaming):
180             print "Disabling controls which require inactive streaming"
181             self.optical_in_mode.setEnabled(False)
182             self.optical_out_mode.setEnabled(False)
183
184         # Some channels aren't available at higher sampling rates
185         if (self.sample_rate > 96000):
186             print "Disabling controls not present above 96 kHz"
187             self.mix1_adat_group.setEnabled(False)
188             self.mix1_aes_group.setEnabled(False)
189             self.mix1_spdif_group.setEnabled(False)
190         if (self.sample_rate > 48000):
191             print "Disabling controls not present above 48 kHz"
192             self.mix1_adat58_group.setEnabled(False)
193
194         # Now fetch the current values into the respective controls.  Don't
195         # bother fetching controls which are disabled.
196         for ctrl, info in self.ChannelFaders.iteritems():
197             if (not(ctrl.isEnabled())):
198                 continue
199             vol = 128-self.hw.getDiscrete(info[0])
200             print "%s channel fader is %d" % (info[0] , vol)
201             ctrl.setValue(vol)
202             QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateFader)
203
204         for ctrl, info in self.ChannelPans.iteritems():
205             if (not(ctrl.isEnabled())):
206                 continue
207             pan = self.hw.getDiscrete(info[0])
208             print "%s channel pan is %d" % (info[0] , pan)
209             ctrl.setValue(pan)
210             QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updatePan)
211
212         for ctrl, info in self.BinarySwitches.iteritems():
213             if (not(ctrl.isEnabled())):
214                 continue
215             val = self.hw.getDiscrete(info[0])
216             print "%s switch is %d" % (info[0] , val)
217             ctrl.setChecked(val)
218             QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateBinarySwitch)
219
220         for ctrl, info in self.MixDests.iteritems():
221             if (not(ctrl.isEnabled())):
222                 continue
223             dest = self.hw.getDiscrete(info[0])
224             print "%s mix destination is %d" % (info[0] , dest)
225             ctrl.setCurrentItem(dest)
226             QObject.connect(ctrl, SIGNAL('activated(int)'), self.updateMixDest)
227
228         for name, ctrl in self.SelectorControls.iteritems():
229             state = self.hw.getDiscrete(ctrl[0])
230             print "%s state is %d" % (name , state)
231             ctrl[1].setCurrentItem(state)   
232
233         # FIXME: If optical mode is not ADAT, disable ADAT controls here.
234         # It can't be done earlier because we need the current values of the
235         # ADAT channel controls in case the user goes ahead and enables the
236         # ADAT optical mode.
Note: See TracBrowser for help on using the browser.