2 # presonus_inspire1394.py - Qt4/FFADO application for Presonus Inspire1394
3 # Copyright (C) 2014 Takashi Sakamoto <o-takashi@sakamocchi.jp>
5 # This file is part of FFADO
6 # FFADO = Free Firewire (pro-)audio drivers for linux
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.
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.
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/>.
22 from PyQt4
import QtGui
, QtCore
23 from PyQt4
.QtCore
import QObject
, Qt
, SIGNAL
24 from PyQt4
.QtGui
import QHBoxLayout
, QVBoxLayout
, QGridLayout
25 from PyQt4
.QtGui
import QGroupBox
, QLabel
, QSizePolicy
, QSlider
, QComboBox
, QToolButton
26 from math
import log10
27 from ffado
.config
import *
29 class Presonus_Inspire1394(QtGui
.QWidget
):
31 inputs
= [[1, "Analog in 1/2"],
35 mixer_src
= [[3, "Analog in 1/2"],
40 outputs
= [[6, "Analog out 1/2"],
44 out_src
= [1, ["Mixer out 1/2", "Stream in 1/2"]]
46 def __init__(self
, parent
=None):
47 QtGui
.QWidget
.__init
__(self
, parent
)
49 def getDisplayTitle(self
):
56 plain_layout
= QHBoxLayout(self
)
58 left
= QGroupBox(self
)
59 plain_layout
.addWidget(left
)
60 self
.addAnalogInputs(left
)
62 center
= QGroupBox(self
)
63 plain_layout
.addWidget(center
)
64 self
.addInternalMixer(center
)
66 right
= QGroupBox(self
)
67 plain_layout
.addWidget(right
)
68 self
.addAnalogOutputs(right
)
70 def addAnalogInputs(self
, box
):
71 box_layout
= QVBoxLayout()
72 box
.setLayout(box_layout
)
73 box
.setTitle("Analog Inputs")
76 box_layout
.addWidget(grid
)
77 grid_layout
= QGridLayout()
78 grid
.setLayout(grid_layout
)
80 self
.addVolumes(self
.inputs
, grid
, grid_layout
)
82 def addAnalogOutputs(self
, box
):
83 box_layout
= QVBoxLayout()
84 box
.setLayout(box_layout
)
85 box
.setTitle("Analog Outputs")
88 box_layout
.addWidget(cmb
)
89 for i
in range(len(self
.out_src
[1])):
90 cmb
.addItem(self
.out_src
[1][i
], i
)
91 self
.Selectors
[cmb
] = ["/Mixer/Selector_%d" % self
.out_src
[0]]
94 box_layout
.addWidget(grid
)
95 grid_layout
= QGridLayout()
96 grid
.setLayout(grid_layout
)
98 self
.addVolumes(self
.outputs
, grid
, grid_layout
)
100 def addInternalMixer(self
, box
):
101 box_layout
= QGridLayout()
102 box
.setLayout(box_layout
)
103 box
.setTitle("Hardware Mixer")
105 self
.addVolumes(self
.mixer_src
, box
, box_layout
)
107 def addVolumes(self
, elms
, parent
, layout
):
108 for col
in range(len(elms
)):
109 label
= QLabel(parent
)
110 label
.setText(elms
[col
][1])
111 layout
.addWidget(label
, 0, col
* 2, 1, 2, Qt
.AlignHCenter
)
113 l_sld
= self
.getSlider(parent
)
114 r_sld
= self
.getSlider(parent
)
115 layout
.addWidget(l_sld
, 1, col
* 2, Qt
.AlignHCenter
)
116 layout
.addWidget(r_sld
, 1, col
* 2 + 1, Qt
.AlignHCenter
)
118 link
= self
.getLink(parent
)
119 layout
.addWidget(link
, 2, col
* 2, 1, 2, Qt
.AlignHCenter
)
121 path
= "/Mixer/Feature_Volume_%d" % elms
[col
][0]
122 self
.Volumes
[l_sld
] = [path
, 1, r_sld
, link
]
123 self
.Volumes
[r_sld
] = [path
, 2, l_sld
, link
]
125 # widget helper functions
126 def getSlider(self
, parent
):
127 sld
= QSlider(parent
)
128 sld
.setSizePolicy(QSizePolicy
.Expanding
, QSizePolicy
.Minimum
)
133 sld
.setMinimumHeight(50)
134 sld
.setTickInterval(25)
135 sld
.setTickPosition(QSlider
.TicksBothSides
)
138 def getLink(self
, parent
):
139 link
= QToolButton(parent
)
141 link
.setCheckable(True)
142 link
.setMinimumWidth(100)
143 link
.setSizePolicy(QSizePolicy
.Preferred
, QSizePolicy
.Fixed
)
146 def initValues(self
):
147 for ctl
, params
in self
.Selectors
.items():
149 state
= self
.hw
.getDiscrete(path
)
150 ctl
.setCurrentIndex(state
)
151 QObject
.connect(ctl
, SIGNAL('activated(int)'), self
.updateSelector
)
153 for ctl
, params
in self
.Volumes
.items():
159 db
= self
.hw
.getContignuous(path
, idx
)
160 vol
= self
.db2vol(db
)
162 QObject
.connect(ctl
, SIGNAL('valueChanged(int)'), self
.updateVolume
)
165 pair_db
= self
.hw
.getContignuous(path
, 1)
167 link
.setChecked(True)
170 def vol2db(self
, vol
):
171 return (log10(vol
+ 1) - 2) * 16384
173 def db2vol(self
, db
):
174 return pow(10, db
/ 16384 + 2) - 1
176 def updateSelector(self
, state
):
177 sender
= self
.sender()
178 path
= self
.Selectors
[sender
][0]
179 self
.hw
.setDiscrete(path
, state
)
181 def updateVolume(self
, vol
):
182 sender
= self
.sender()
183 path
= self
.Volumes
[sender
][0]
184 idx
= self
.Volumes
[sender
][1]
185 pair
= self
.Volumes
[sender
][2]
186 link
= self
.Volumes
[sender
][3]
188 db
= self
.vol2db(vol
)
189 self
.hw
.setContignuous(path
, db
, idx
)