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

Revision 2037, 10.3 kB (checked in by jwoithe, 9 years ago)

rme: make clock mode control active. Note that this isn't overly useful without the other clock-related controls and indicators being active. They will follow soon.

  • Property svn:mergeinfo set to
Line 
1 #
2 # Copyright (C) 2009, 2011 by Jonathan Woithe
3 #
4 # This file is part of FFADO
5 # FFADO = Free Firewire (pro-)audio drivers for linux
6 #
7 # FFADO is based upon FreeBoB.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 2 of the License, or
12 # (at your option) version 3 of the License.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 #
22
23 from PyQt4 import QtGui
24
25 from PyQt4.QtCore import SIGNAL, SLOT, QObject, Qt
26 from PyQt4.QtGui import QWidget, QApplication
27 from ffado.config import *
28
29 from ffado.widgets.matrixmixer import MatrixMixer
30
31 import logging
32 log = logging.getLogger('rme')
33
34 # Model defines.  These must agree with what is used in rme_avdevice.h.
35 RME_MODEL_NONE      = 0x0000
36 RME_MODEL_FF800     = 0x0001
37 RME_MODEL_FF400     = 0x0002
38
39 class Rme(QWidget):
40     def __init__(self,parent = None):
41         QWidget.__init__(self,parent)
42         uicLoad("ffado/mixer/rme", self)
43
44         self.init()
45
46     def init(self):
47
48         self.PhantomSwitches={
49             self.phantom_0: ['/Control/Phantom', 0],
50             self.phantom_1: ['/Control/Phantom', 1],
51             self.phantom_2: ['/Control/Phantom', 2],
52             self.phantom_3: ['/Control/Phantom', 3],
53         }
54
55         self.Switches={
56             self.ff400_chan3_opt_instr: ['/Control/Chan3_opt_instr'],
57             self.ff400_chan3_opt_pad:   ['/Control/Chan3_opt_pad'],
58             self.ff400_chan4_opt_instr: ['/Control/Chan4_opt_instr'],
59             self.ff400_chan4_opt_pad:   ['/Control/Chan4_opt_pad'],
60
61             self.spdif_output_optical:  ['/Control/SPDIF_output_optical', 0],
62             self.spdif_output_emphasis: ['/Control/SPDIF_output_emphasis', 0],
63             self.spdif_output_pro:      ['/Control/SPDIF_output_pro', 0],
64             self.spdif_output_nonaudio: ['/Control/SPDIF_output_nonaudio', 0],
65         }
66
67         self.Radiobuttons={
68             self.level_in_lo_gain: ['/Control/Input_level', 1],
69             self.level_in_p4dBu:   ['/Control/Input_level', 2],
70             self.level_in_m10dBV:  ['/Control/Input_level', 3],
71
72             self.level_out_hi_gain: ['/Control/Output_level', 1],
73             self.level_out_p4dBu:   ['/Control/Output_level', 2],
74             self.level_out_m10dBV:  ['/Control/Output_level', 3],
75
76             self.spdif_input_coax:    ['/Control/SPDIF_input_mode', 0],
77             self.spdif_input_optical: ['/Control/SPDIF_input_mode', 1],
78
79             self.phones_hi_gain: ['/Control/Phones_level', 1],
80             self.phones_p4dBu:   ['/Control/Phones_level', 2],
81             self.phones_m10dBV:  ['/Control/Phones_level', 3],
82
83             self.clock_mode_autosync: ['/Control/Clock_mode', 1],
84             self.clock_mode_master: ['/Control/Clock_mode', 0],
85         }
86
87
88         self.Gains={
89             self.gain_mic1: ['/Control/Gains', 0],
90             self.gain_mic2: ['/Control/Gains', 1],
91             self.gain_input3: ['/Control/Gains', 2],
92             self.gain_input4: ['/Control/Gains', 3],
93         }
94
95         # Other mixer variables
96         self.is_streaming = 0
97         self.sample_rate = 0
98         self.model = 0
99         self.tco_present = 0
100
101     # Public slot: update phantom power hardware switches
102     def updatePhantomSwitch(self, a0):
103         sender = self.sender()
104         # Value is the phantom switch value, with a corresponding enable
105         # bit in the high 16 bit word
106         val = (a0 << self.PhantomSwitches[sender][1]) | (0x00010000 << self.PhantomSwitches[sender][1])
107         log.debug("phantom switch %d set to %d" % (self.PhantomSwitches[sender][1], a0))
108         self.hw.setDiscrete(self.PhantomSwitches[sender][0], val)
109
110     # Public slot: update generic switches
111     def updateSwitch(self, a0):
112         sender = self.sender()
113         log.debug("switch %s set to %d" % (self.Switches[sender][0], a0))
114         self.hw.setDiscrete(self.Switches[sender][0], a0)
115
116     # Public slot: update generic radiobuttons
117     def updateRadiobutton(self, a0):
118         sender = self.sender()
119         if (a0 != 0):
120             # Only change the control state on a button being "checked"
121             log.debug("radiobutton group %s set to %d" % (self.Radiobuttons[sender][0], self.Radiobuttons[sender][1]))
122             self.hw.setDiscrete(self.Radiobuttons[sender][0], self.Radiobuttons[sender][1])
123
124     # Public slot: update gains
125     def updateGain(self, a0):
126         sender = self.sender()
127         log.debug("gain %s[%d] set to %d" % (self.Gains[sender][0], self.Gains[sender][1], a0))
128         self.hw.setMatrixMixerValue(self.Gains[sender][0], 0, self.Gains[sender][1], a0)
129
130     # Hide and disable a control
131     def disable_hide(self,widget):
132         widget.hide()
133         widget.setEnabled(False)
134
135     def initValues(self):
136
137         # print self.hw.servername
138         # print self.hw.basepath
139         self.inputmatrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/Mixer/InputFaders", self, 0x8000, self.hw.basepath+"/Mixer/InputMutes", self.hw.basepath+"/Mixer/InputInverts")
140         layout = QtGui.QVBoxLayout()
141         scrollarea = QtGui.QScrollArea()
142         scrollarea.setWidgetResizable(True)
143         scrollarea.setWidget(self.inputmatrix)
144         layout.addWidget(scrollarea)
145         self.mixer.setLayout(layout)
146
147         self.playbackmatrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/Mixer/PlaybackFaders", self, 0x8000, self.hw.basepath+"/Mixer/PlaybackMutes", self.hw.basepath+"/Mixer/PlaybackInverts")
148         layout = QtGui.QVBoxLayout()
149         scrollarea = QtGui.QScrollArea()
150         scrollarea.setWidgetResizable(True)
151         scrollarea.setWidget(self.playbackmatrix)
152         layout.addWidget(scrollarea)
153         self.playbackmixer.setLayout(layout)
154
155         self.outputmatrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/Mixer/OutputFaders", self, 0x8000, self.hw.basepath+"/Mixer/OutputMutes")
156         layout = QtGui.QVBoxLayout()
157         scrollarea = QtGui.QScrollArea()
158         scrollarea.setWidgetResizable(True)
159         scrollarea.setWidget(self.outputmatrix)
160         layout.addWidget(scrollarea)
161         self.outputmixer.setLayout(layout)
162
163         # Is the device streaming?
164         #self.is_streaming = self.hw.getDiscrete('/Mixer/Info/IsStreaming')
165         self.is_streaming = 0
166         #log.debug("device streaming flag: %d" % (self.is_streaming))
167
168         # Retrieve other device settings as needed and customise the UI
169         # based on these options.
170         self.model = self.hw.getDiscrete('/Control/Model')
171         log.debug("device model identifier: %d" % (self.model))
172         self.tco_present = self.hw.getDiscrete('/Control/TCO_present')
173         log.debug("device has TCO: %d" % (self.tco_present))
174         #self.sample_rate = self.hw.getDiscrete('/Mixer/Info/SampleRate')
175         #log.debug("device sample rate: %d" % (self.sample_rate))
176
177         # The Fireface-400 only has 2 phantom-capable channels
178         if (self.model == RME_MODEL_FF400):
179             self.disable_hide(self.phantom_2)
180             self.disable_hide(self.phantom_3)
181         else:
182             self.phantom_0.setText("Mic 7")
183             self.phantom_1.setText("Mic 8")
184             self.phantom_2.setText("Mic 9")
185             self.phantom_3.setText("Mic 10")
186
187         # Instrument options, input jack selection controls and an ADAT2
188         # input are applicable only to the FF800
189         if (self.model != RME_MODEL_FF800):
190             self.instrument_options_group.setEnabled(False)
191             self.input_plug_select_group.setEnabled(False)
192             self.sync_ref_adat2.setEnabled(False)
193             self.sync_check_adat2_label.setEnabled(False)
194             self.sync_check_adat2_status.setEnabled(False)
195
196         # Only the FF400 has specific channel 3/4 options, input gain
197         # controls and switchable phones level
198         if (self.model != RME_MODEL_FF400):
199             self.disable_hide(self.input_gains_group)
200             self.disable_hide(self.channel_3_4_options_group)
201             self.phones_level_group.setEnabled(False)
202
203         # Get current hardware values and connect GUI element signals to
204         # their respective slots
205         for ctrl, info in self.PhantomSwitches.iteritems():
206             if (not(ctrl.isEnabled())):
207                 continue
208             val = (self.hw.getDiscrete(info[0]) >> info[1]) & 0x01
209             log.debug("phantom switch %d is %d" % (info[1], val))
210             if val:
211                 ctrl.setChecked(True)
212             else:
213                 ctrl.setChecked(False)
214             QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updatePhantomSwitch)
215
216         for ctrl, info in self.Switches.iteritems():
217             if (not(ctrl.isEnabled())):
218                 continue
219             val = self.hw.getDiscrete(info[0])
220             log.debug("switch %s is %d" % (info[0], val))
221             if val:
222                 ctrl.setChecked(True)
223             else:
224                 ctrl.setChecked(False)
225             QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateSwitch)
226
227         for ctrl, info in self.Radiobuttons.iteritems():
228             if (not(ctrl.isEnabled())):
229                 continue;
230             # This is a touch wasteful since it means we retrieve the control
231             # value once per radio button rather than once per radio button
232             # group.  In time we might introduce radiobutton groupings in the
233             # self.* datastructures to avoid this, but for the moment this is
234             # easy and it works.
235             val = self.hw.getDiscrete(info[0])
236             if (val == info[1]):
237                 val = 1
238             else:
239                 val = 0
240             ctrl.setChecked(val)
241             log.debug("Radiobutton %s[%d] is %d" % (info[0], info[1], val))
242             QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateRadiobutton)
243
244         for ctrl, info in self.Gains.iteritems():
245             if (not(ctrl.isEnabled())):
246                 continue
247             val = self.hw.getMatrixMixerValue(info[0], 0, info[1])
248             log.debug("gain %s[%d] is %d" % (info[0], info[1], val))
249             ctrl.setValue(val);
250             QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateGain)
251
252 # vim: et
Note: See TracBrowser for help on using the browser.