root/trunk/libffado/src/rme/fireface_settings_ctrls.cpp

Revision 2008, 9.7 kB (checked in by jwoithe, 12 years ago)

rme: refine input matrix mixer channel names. Add low level support for mixer channel phase inversion and muting (untested). Add playback mixer to RME ffado-mixer.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2008-2009 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 #include <math.h>
25
26 #include "rme/rme_avdevice.h"
27 #include "rme/fireface_settings_ctrls.h"
28
29 namespace Rme {
30
31 RmeSettingsCtrl::RmeSettingsCtrl(Device &parent, unsigned int type,
32     unsigned int info)
33 : Control::Discrete(&parent)
34 , m_parent(parent)
35 , m_type(type)
36 , m_value(0)
37 , m_info(info)
38 {
39 }
40
41 RmeSettingsCtrl::RmeSettingsCtrl(Device &parent, unsigned int type,
42     unsigned int info,
43     std::string name, std::string label, std::string descr)
44 : Control::Discrete(&parent)
45 , m_parent(parent)
46 , m_type(type)
47 , m_value(0)
48 , m_info(info)
49 {
50     setName(name);
51     setLabel(label);
52     setDescription(descr);
53 }
54
55 bool
56 RmeSettingsCtrl::setValue(int v) {
57
58 signed int i;
59 signed int err = 0;
60
61     switch (m_type) {
62         case RME_CTRL_NONE:
63             debugOutput(DEBUG_LEVEL_ERROR, "control has no type set\n");
64             err = 1;
65             break;
66         case RME_CTRL_PHANTOM_SW:
67             // Lowest 16 bits are phantom status bits (max 16 channels).
68             // High 16 bits are "write enable" bits for the corresponding
69             // channel represented in the low 16 bits.  This way changes can
70             // be made to one channel without needing to first read the
71             // existing value.
72             //
73             // At present there are at most 4 phantom-capable channels.
74             // Flag attempts to write to the bits corresponding to channels
75             // beyond this.
76             if (v & 0xfff00000) {
77                 debugOutput(DEBUG_LEVEL_WARNING, "Ignored out-of-range phantom set request: mask=0x%04x, value=0x%04x\n",
78                   (v >> 16) & 0xfff0, v && 0xfff0);
79             }
80
81             for (i=0; i<4; i++) {
82                 if (v & (0x00010000 << i)) {
83                     unsigned int on = (v & (0x00000001 << i)) != 0;
84                     err = m_parent.setPhantom(i, on);
85                     if (!err) {
86                         if (on) {
87                             m_value |= (0x01 << i);
88                         } else {
89                             m_value &= ~(0x01 << i);
90                         }
91                     }
92                 }
93             }
94             break;
95         case RME_CTRL_INPUT_LEVEL:
96             if (m_parent.setInputLevel(v)) {
97                 m_value = v;
98             }
99             break;
100         case RME_CTRL_OUTPUT_LEVEL:
101             if (m_parent.setOutputLevel(v)) {
102                 m_value = v;
103             }
104             break;
105         case RME_CTRL_FF400_PAD_SW:
106             // Object's "m_info" field is the channel
107             if (m_parent.setInputPadOpt(m_info, v)) {
108                 m_value = (v != 0);
109             }
110             break;
111         case RME_CTRL_FF400_INSTR_SW:
112             // Object's "m_info" field is the channel
113             if (m_parent.setInputInstrOpt(m_info, v)) {
114                 m_value = (v != 0);
115             }
116             break;
117         case RME_CTRL_PHONES_LEVEL:
118             if (m_parent.setPhonesLevel(v)) {
119                 m_value = v;
120             }
121             break;
122
123         // All RME_CTRL_INFO_* controls are read-only.  Warn on attempts to
124         // set these.
125         case RME_CTRL_INFO_MODEL:
126         case RME_CTRL_INFO_TCO_PRESENT:
127             debugOutput(DEBUG_LEVEL_ERROR, "Attempt to set readonly info control 0x%08x\n", m_type);
128             err = 1;
129             break;
130
131         default:
132             debugOutput(DEBUG_LEVEL_ERROR, "Unknown control type 0x%08x\n", m_type);
133             err = 1;
134     }
135
136     return err==0?true:false;
137 }
138
139 int
140 RmeSettingsCtrl::getValue() {
141
142 signed int i;
143 signed int val = 0;
144
145     switch (m_type) {
146         case RME_CTRL_NONE:
147             debugOutput(DEBUG_LEVEL_ERROR, "control has no type set\n");
148             break;
149
150         case RME_CTRL_PHANTOM_SW:
151             for (i=0; i<3; i++)
152                 val |= (m_parent.getPhantom(i) << i);
153             return val;
154             break;
155         case RME_CTRL_INPUT_LEVEL:
156             return m_parent.getInputLevel();
157             break;
158         case RME_CTRL_OUTPUT_LEVEL:
159             return m_parent.getOutputLevel();
160             break;
161         case RME_CTRL_FF400_PAD_SW:
162             return m_parent.getInputPadOpt(m_info);
163             break;
164         case RME_CTRL_FF400_INSTR_SW:
165             return m_parent.getInputInstrOpt(m_info);
166             break;
167         case RME_CTRL_PHONES_LEVEL:
168             return m_parent.getPhonesLevel();
169             break;
170
171         case RME_CTRL_INFO_MODEL:
172             return m_parent.getRmeModel();
173             break;
174
175         case RME_CTRL_INFO_TCO_PRESENT:
176             return m_parent.getTcoPresent();
177
178         default:
179             debugOutput(DEBUG_LEVEL_ERROR, "Unknown control type 0x%08x\n", m_type);
180     }
181
182     return 0;
183 }
184
185
186 RmeSettingsMatrixCtrl::RmeSettingsMatrixCtrl(Device &parent, unsigned int type)
187 : Control::MatrixMixer(&parent)
188 , m_parent(parent)
189 , m_type(type)
190 {
191 }
192
193 RmeSettingsMatrixCtrl::RmeSettingsMatrixCtrl(Device &parent, unsigned int type,
194     std::string name)
195 : Control::MatrixMixer(&parent)
196 , m_parent(parent)
197 , m_type(type)
198 {
199     setName(name);
200 }
201
202 void RmeSettingsMatrixCtrl::show()
203 {
204     debugOutput(DEBUG_LEVEL_NORMAL, "RME matrix mixer type %d\n", m_type);
205 }
206
207 std::string RmeSettingsMatrixCtrl::getRowName(const int row)
208 {
209     char buf[64];
210     if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400) {
211         if (row >= 10)
212             snprintf(buf, sizeof(buf), "ADAT out %d", row-9);
213         else
214         if (row >= 8)
215             snprintf(buf, sizeof(buf), "SPDIF out %d", row-7);
216         else
217         if (row >= 6)
218             snprintf(buf, sizeof(buf), "Mon out %d", row+1);
219         else
220             snprintf(buf, sizeof(buf), "Line out %d", row+1);
221     } else {
222         snprintf(buf, sizeof(buf), "row %d", row);
223     }
224     return buf;
225 }
226
227 std::string RmeSettingsMatrixCtrl::getColName(const int col)
228 {
229     char buf[64];
230     if (m_type == RME_MATRIXCTRL_PLAYBACK_FADER)
231         return "";
232     if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400) {
233         if (col >= 10)
234             snprintf(buf, sizeof(buf), "ADAT in %d", col-9);
235         else
236         if (col >= 8)
237             snprintf(buf, sizeof(buf), "SPDIF in %d", col-7);
238         else
239         if (col >= 4)
240             snprintf(buf, sizeof(buf), "Line in %d", col+1);
241         else
242         if (col >= 2)
243             snprintf(buf, sizeof(buf), "Inst/line %d", col+1);
244         else
245             snprintf(buf, sizeof(buf), "Mic/line %d", col+1);
246     } else {
247         snprintf(buf, sizeof(buf), "col %d", col);
248     }
249     return buf;
250 }
251
252 int RmeSettingsMatrixCtrl::getRowCount()
253 {
254     switch (m_type) {
255         case RME_MATRIXCTRL_GAINS:
256             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
257                 return 1;
258             break;
259         case RME_MATRIXCTRL_INPUT_FADER:
260         case RME_MATRIXCTRL_PLAYBACK_FADER:
261             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
262                 return RME_FF400_MAX_CHANNELS;
263             else
264                 return RME_FF800_MAX_CHANNELS;
265             break;
266         case RME_MATRIXCTRL_OUTPUT_FADER:
267             return 1;
268             break;
269     }
270
271     return 0;
272 }
273
274 int RmeSettingsMatrixCtrl::getColCount()
275 {
276     switch (m_type) {
277         case RME_MATRIXCTRL_GAINS:
278             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
279                 return 22;
280             break;
281         case RME_MATRIXCTRL_INPUT_FADER:
282         case RME_MATRIXCTRL_PLAYBACK_FADER:
283         case RME_MATRIXCTRL_OUTPUT_FADER:
284             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
285                 return RME_FF400_MAX_CHANNELS;
286             else
287                 return RME_FF800_MAX_CHANNELS;
288             break;
289     }
290
291     return 0;
292 }
293
294 double RmeSettingsMatrixCtrl::setValue(const int row, const int col, const double val)
295 {
296     signed int ret = true;
297     signed int i;
298
299     switch (m_type) {
300         case RME_MATRIXCTRL_GAINS:
301             i = val;
302             if (i >= 0)
303                 ret = m_parent.setAmpGain(col, val);
304             else
305                 ret = -1;
306             break;
307         case RME_MATRIXCTRL_INPUT_FADER:
308           return m_parent.setMixerGain(RME_FF_MM_INPUT, col, row, val);
309           break;
310         case RME_MATRIXCTRL_PLAYBACK_FADER:
311           return m_parent.setMixerGain(RME_FF_MM_PLAYBACK, col, row, val);
312           break;
313         case RME_MATRIXCTRL_OUTPUT_FADER:
314           return m_parent.setMixerGain(RME_FF_MM_OUTPUT, col, row, val);
315           break;
316     }
317
318     return ret;
319 }
320
321 double RmeSettingsMatrixCtrl::getValue(const int row, const int col)
322 {
323     double val = 0.0;
324     switch (m_type) {
325         case RME_MATRIXCTRL_GAINS:
326             val = m_parent.getAmpGain(col);
327             break;
328         case RME_MATRIXCTRL_INPUT_FADER:
329             val = m_parent.getMixerGain(RME_FF_MM_INPUT, col, row);
330             break;
331         case RME_MATRIXCTRL_PLAYBACK_FADER:
332             val = m_parent.getMixerGain(RME_FF_MM_PLAYBACK, col, row);
333             break;
334         case RME_MATRIXCTRL_OUTPUT_FADER:
335             val = m_parent.getMixerGain(RME_FF_MM_OUTPUT, col, row);
336             break;
337     }
338
339     return val;
340 }
341      
342
343 }
Note: See TracBrowser for help on using the browser.