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

Revision 2803, 11.9 kB (checked in by jwoithe, 3 years ago)

Cosmetic: capitalise "L" in "Linux".

"Linux" is a proper noun so it should start with a capital letter. These
changes are almost all within comments.

This patch was originally proposed by pander on the ffado-devel mailing
list. It has been expanded to cover all similar cases to maintain
consistency throughout the source tree.

Line 
1 #
2 # presonus_firebox.py - Qt4/FFADO application for Presonus FIREBOX
3 # Copyright (C) 2013 Takashi Sakamoto <o-takashi@sakamocchi.jp>
4 #
5 # This file is part of FFADO
6 # FFADO = Free FireWire (pro-)audio drivers for Linux
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 2 of the License, or
11 # version 3 of the License.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21
22 # from PyQt4 import QtGui, QtCore
23 # from PyQt4.QtCore import Qt
24 # from PyQt4.QtGui import QHBoxLayout, QVBoxLayout, QGridLayout
25 # from PyQt4.QtGui import QWidget, QTabWidget, QGroupBox, QLabel, QSizePolicy, QToolButton, QSlider, QComboBox, QSpacerItem, QDial
26 from ffado.import_pyqt import *
27
28 from math import log10
29 from ffado.config import *
30
31 class Presonus_Firebox(QWidget):
32     #name/feature_id/+12dB_id
33     inputs = [["Analog in 1/2",  5, 10],
34               ["Analog in 3/4",  6, 11],
35               ["Digital in 1/2", 7,  0],
36               ["Stream in",      8,  0]]
37
38     # name/id for mixer sorce selector
39     streams = [["Stream in 1/2", 0],
40                ["Stream in 3/4", 1],
41                ["Stream in 5/6", 2],
42                ["Stream in 7/8", 3]]
43
44     # name/feature id
45     outputs = [["Analog out 1/2",    1],
46                ["Analog out 3/4",    2],
47                ["Analog out 5/6",    3],
48                ["Digital out 1/2",   0],
49                ["Headphone out 1/2", 4]]
50
51     # selector_id/sources
52     out_src = [[1, ["Stream in 1/2", "Mixer out 1/2"]],
53                [2, ["Stream in 3/4", "Mixer out 1/2"]],
54                [3, ["Stream in 5/6", "Mixer out 1/2"]],
55                [5, ["Stream in 7/8", "Mixer out 1/2"]],
56                [4, ["Stream in 1/2", "Stream in 3/4",
57                     "Stream in 5/6", "Stream in 7/8", "Mixer out 1/2"]]]
58
59     def __init__(self, parent=None):
60         QWidget.__init__(self, parent)
61
62     def getDisplayTitle(self):
63         return 'Firebox'
64
65     def buildMixer(self):
66         self.Selectors = {}
67         self.MicBoosts = {}
68         self.Volumes = {}
69         self.Mutes = {}
70         self.Balances = {}
71
72         tabs = QTabWidget(self)
73         tabs_layout = QHBoxLayout(self)
74         tabs_layout.addWidget(tabs)
75
76         self.addMixer(tabs)
77         self.addOutput(tabs)
78
79     def addMixer(self, tabs):
80         tab_mixer = QWidget(tabs)
81         tabs.addTab(tab_mixer, "Mixer")
82         tab_mixer_layout = QGridLayout()
83         tab_mixer.setLayout(tab_mixer_layout)
84
85         for i in range(len(self.inputs)):
86             col = 2 * i;
87             label = QLabel(tab_mixer)
88             tab_mixer_layout.addWidget(label, 0, col, 1, 2, Qt.AlignHCenter)
89
90             label.setText(self.inputs[i][0])
91             label.setAlignment(Qt.AlignCenter)
92             label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
93
94             link = self.getLink(tab_mixer)
95             tab_mixer_layout.addWidget(link, 3, col, 1, 2, Qt.AlignHCenter)
96
97             if self.inputs[i][2] > 0:
98                 for j in range(1, 3):
99                     button = QToolButton(tab_mixer)
100                     tab_mixer_layout.addWidget(button, 1, col + j - 1, Qt.AlignHCenter)
101                     button.setText('+12dB')
102                     button.setCheckable(True)
103                     button.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
104                     path = "/Mixer/Feature_Volume_%d" % self.inputs[i][2]
105                     self.MicBoosts[button] = [path, j]
106
107             elif self.inputs[i][0].find('Stream') >= 0:
108                 cmb = QComboBox(tab_mixer)
109                 tab_mixer_layout.addWidget(cmb, 1, col, 1, 2, Qt.AlignHCenter)
110                 for i in range(len(self.streams)):
111                     cmb.addItem(self.streams[i][0], self.streams[i][1])
112                 self.Selectors[cmb] = ["/Mixer/Selector_6"]
113
114             l_sld = self.getSlider(tab_mixer)
115             r_sld = self.getSlider(tab_mixer)
116             tab_mixer_layout.addWidget(l_sld, 2, col, Qt.AlignHCenter)
117             tab_mixer_layout.addWidget(r_sld, 2, col + 1, Qt.AlignHCenter)
118
119             mute = self.getMute(tab_mixer)
120             tab_mixer_layout.addWidget(mute, 4, col, 1, 2, Qt.AlignHCenter)
121
122             path = "/Mixer/Feature_Volume_%d" % self.inputs[i][1]
123             self.Volumes[l_sld] = [path, 1, r_sld, link, mute]
124             self.Volumes[r_sld] = [path, 2, l_sld, link, mute]
125             self.Mutes[mute] = [path, l_sld, r_sld]
126
127             for j in range(0, 2):
128                 dial = self.getDial(tab_mixer)
129                 tab_mixer_layout.addWidget(dial, 5, col + j, Qt.AlignHCenter)
130                 if self.inputs[i][2] > 0:
131                     path = "/Mixer/Feature_LRBalance_%d" % self.inputs[i][1]
132                     self.Balances[dial] = [path, j + 1]
133                 # to keep width
134                 else:
135                     dial.setDisabled(True)
136
137     def addOutput(self, tabs):
138         tab_out = QWidget(self)
139         tabs.addTab(tab_out, "Output")
140         tab_out_layout = QGridLayout()
141         tab_out.setLayout(tab_out_layout)
142
143         for i in range(len(self.outputs)):
144             col = 2 * i
145
146             label = QLabel(tab_out)
147             tab_out_layout.addWidget(label, 0, col, 1, 2, Qt.AlignCenter)
148             label.setText(self.outputs[i][0])
149
150             cmb = QComboBox(tab_out)
151             tab_out_layout.addWidget(cmb, 1, col, 1, 2, Qt.AlignHCenter)
152             for j in range(len(self.out_src[i][1])):
153                 cmb.addItem(self.out_src[i][1][j])
154             self.Selectors[cmb] = ["/Mixer/Selector_%d" % self.out_src[i][0]]
155
156             if self.outputs[i][1] == 0:
157                 continue
158
159             l_sld = self.getSlider(tab_out)
160             r_sld = self.getSlider(tab_out)
161             tab_out_layout.addWidget(l_sld, 2, col, Qt.AlignHCenter)
162             tab_out_layout.addWidget(r_sld, 2, col + 1, Qt.AlignHCenter)
163
164             link = self.getLink(tab_out)
165             tab_out_layout.addWidget(link, 3, col, 1, 2, Qt.AlignHCenter)
166
167             mute = self.getMute(tab_out)
168             tab_out_layout.addWidget(mute, 4, col, 1, 2, Qt.AlignHCenter)
169
170             path = "/Mixer/Feature_Volume_%d" % self.outputs[i][1]
171             self.Volumes[l_sld] = [path, 1, r_sld, link, mute]
172             self.Volumes[r_sld] = [path, 2, l_sld, link, mute]
173             self.Mutes[mute] = [path, l_sld, r_sld]
174
175     def getSlider(self, parent):
176         sld = QSlider(parent)
177         sld.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
178         sld.setMinimum(0)
179         sld.setMaximum(99)
180         sld.setPageStep(10)
181         sld.setPageStep(10)
182         sld.setMinimumHeight(50)
183         sld.setTickInterval(25)
184         sld.setTickPosition(QSlider.TicksBothSides)
185         return sld
186
187     def getDial(self, parent):
188         dial = QDial(parent)
189         dial.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
190         dial.setMinimumSize(50, 50)
191         dial.setMaximumHeight(50)
192         dial.setNotchTarget(25)
193         dial.setNotchesVisible(True)
194         dial.setMinimum(0)
195         dial.setMaximum(99)
196         dial.setPageStep(10)
197         dial.setPageStep(10)
198         return dial
199
200     def getLink(self, parent):
201         link = QToolButton(parent)
202         link.setText("link")
203         link.setCheckable(True)
204         link.setMinimumWidth(100)
205         link.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
206         return link
207
208     def getMute(self, parent):
209         mute = QToolButton(parent)
210         mute.setText("mute")
211         mute.setCheckable(True)
212         mute.setMinimumWidth(100)
213         mute.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
214         return mute
215
216     def initValues(self):
217         for elm, params in self.Selectors.items():
218             path = params[0]
219             state = self.hw.getDiscrete(path)
220             elm.setCurrentIndex(state)
221             elm.activated.connect(self.updateSelector)
222
223         for elm, params in self.MicBoosts.items():
224             path = params[0]
225             idx  = params[1]
226             value = self.hw.getContignuous(path, idx)
227             elm.setChecked(not value == 0)
228             elm.clicked.connect(self.updateMicBoost)
229
230         for elm, params in self.Volumes.items():
231             path = params[0]
232             idx  = params[1]
233             db   = self.hw.getContignuous(path, idx)
234             vol  = self.db2vol(db)
235             elm.setValue(vol)
236             elm.valueChanged.connect(self.updateVolume)
237
238             if idx == 0:
239                 continue
240
241             p_idx = 0
242             pair = params[2]
243             link = params[3]
244             mute = params[4]
245
246             p_db = self.hw.getContignuous(path, p_idx)
247             if db == p_db:
248                 link.setChecked(True)
249
250         for elm, params in self.Mutes.items():
251             path  = params[0]
252             l_elm = params[1]
253             r_elm = params[2]
254
255             l_db  = self.hw.getContignuous(path, 1)
256             r_db  = self.hw.getContignuous(path, 2)
257             l_vol = self.db2vol(l_db)
258             r_vol = self.db2vol(r_db)
259
260             if l_vol == r_vol and l_vol == 0:
261                 elm.setChecked(True)
262                 l_elm.setDisabled(True)
263                 r_elm.setDisabled(True)
264             elm.clicked.connect(self.updateMute)
265
266         for elm, params in self.Balances.items():
267             path = params[0]
268             idx  = params[1]
269             pan = self.hw.getContignuous(path, idx)
270             val = self.pan2val(pan)
271             elm.setValue(val)
272             elm.valueChanged.connect(self.updateBalance)
273
274     # helper functions
275     def vol2db(self, vol):
276         return (log10(vol + 1) - 2) * 16384
277     def db2vol(self, db):
278         return pow(10, db / 16384 + 2) - 1
279
280     #       Right - Center - Left
281     # 0x8000 - 0x0000 - 0x0001 - 0x7FFE
282     #        ..., -1, 0, +1, ...
283     def val2pan(self, val):
284         return (val - 50) * 0x7ffe / -50
285     def pan2val(self, pan):
286         return -(pan/ 0x7ffe) * 50 + 50
287
288     def updateSelector(self, state):
289         sender = self.sender()
290         path   = self.Selectors[sender][0]
291         self.hw.setDiscrete(path, state)
292
293     def updateVolume(self, vol):
294         sender = self.sender()
295         path   = self.Volumes[sender][0]
296         idx    = self.Volumes[sender][1]
297         pair   = self.Volumes[sender][2]
298         link   = self.Volumes[sender][3]
299         mute   = self.Volumes[sender][4]
300         db = self.vol2db(vol)
301         self.hw.setContignuous(path, db, idx)
302
303         if idx == 1:
304             p_idx = 2
305         else:
306             p_idx = 1
307         if link.isChecked():
308             self.hw.setContignuous(path, db, p_idx)
309             pair.setValue(vol)
310
311     def updateMicBoost(self, state):
312         sender = self.sender()
313         path   = self.MicBoosts[sender][0]
314         idx    = self.MicBoosts[sender][1]
315         if state:
316             value = 0x7ffe
317         else:
318             value = 0x0000
319         self.hw.setContignuous(path, value, idx)
320
321     def updateBalance(self, val):
322         sender = self.sender()
323         path   = self.Balances[sender][0]
324         idx    = self.Balances[sender][1]
325         pan    = self.val2pan(val)
326         self.hw.setContignuous(path, pan, idx)
327
328     def updateMute(self, state):
329         sender = self.sender()
330         path   = self.Mutes[sender][0]
331         l_elm  = self.Mutes[sender][1]
332         r_elm  = self.Mutes[sender][2]
333
334         if state:
335             # mute emulation
336             db = self.vol2db(10)
337             l_elm.setValue(0)
338             l_elm.setDisabled(True)
339             r_elm.setValue(0)
340             r_elm.setDisabled(True)
341         else:
342             db = self.vol2db(99)
343             l_elm.setDisabled(False)
344             l_elm.setValue(99)
345             r_elm.setDisabled(False)
346             r_elm.setValue(99)
347
348         self.hw.setContignuous(path, db, 1)
349         self.hw.setContignuous(path, db, 2)
Note: See TracBrowser for help on using the browser.