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

Revision 2032, 12.0 kB (checked in by jwoithe, 9 years ago)

rme: implement SPDIF input mode selection via ffado-mixer. Whether this has the desired effect on the device remains to be seen - I do not have anything to test the mode of the optical port right now.

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_SPDIF_INPUT_MODE:
118             if (m_parent.setSpdifInputMode(v==0?FF_SWPARAM_SPDIF_INPUT_COAX:FF_SWPARAM_SPDIF_INPUT_OPTICAL)) {
119                 m_value = v;
120             }
121             break;
122         case RME_CTRL_PHONES_LEVEL:
123             if (m_parent.setPhonesLevel(v)) {
124                 m_value = v;
125             }
126             break;
127
128         // All RME_CTRL_INFO_* controls are read-only.  Warn on attempts to
129         // set these.
130         case RME_CTRL_INFO_MODEL:
131         case RME_CTRL_INFO_TCO_PRESENT:
132             debugOutput(DEBUG_LEVEL_ERROR, "Attempt to set readonly info control 0x%08x\n", m_type);
133             err = 1;
134             break;
135
136         default:
137             debugOutput(DEBUG_LEVEL_ERROR, "Unknown control type 0x%08x\n", m_type);
138             err = 1;
139     }
140
141     return err==0?true:false;
142 }
143
144 int
145 RmeSettingsCtrl::getValue() {
146
147 signed int i;
148 signed int val = 0;
149
150     switch (m_type) {
151         case RME_CTRL_NONE:
152             debugOutput(DEBUG_LEVEL_ERROR, "control has no type set\n");
153             break;
154
155         case RME_CTRL_PHANTOM_SW:
156             for (i=0; i<3; i++)
157                 val |= (m_parent.getPhantom(i) << i);
158             return val;
159             break;
160         case RME_CTRL_INPUT_LEVEL:
161             return m_parent.getInputLevel();
162             break;
163         case RME_CTRL_OUTPUT_LEVEL:
164             return m_parent.getOutputLevel();
165             break;
166         case RME_CTRL_FF400_PAD_SW:
167             return m_parent.getInputPadOpt(m_info);
168             break;
169         case RME_CTRL_FF400_INSTR_SW:
170             return m_parent.getInputInstrOpt(m_info);
171             break;
172         case RME_CTRL_SPDIF_INPUT_MODE:
173             i = m_parent.getSpdifInputMode();
174             return i==FF_SWPARAM_SPDIF_INPUT_COAX?0:1;
175             break;
176         case RME_CTRL_PHONES_LEVEL:
177             return m_parent.getPhonesLevel();
178             break;
179
180         case RME_CTRL_INFO_MODEL:
181             return m_parent.getRmeModel();
182             break;
183
184         case RME_CTRL_INFO_TCO_PRESENT:
185             return m_parent.getTcoPresent();
186
187         default:
188             debugOutput(DEBUG_LEVEL_ERROR, "Unknown control type 0x%08x\n", m_type);
189     }
190
191     return 0;
192 }
193
194
195 static std::string getOutputName(const signed int model, const int idx)
196 {
197     char buf[64];
198     if (model == RME_MODEL_FIREFACE400) {
199         if (idx >= 10)
200             snprintf(buf, sizeof(buf), "ADAT out %d", idx-9);
201         else
202         if (idx >= 8)
203             snprintf(buf, sizeof(buf), "SPDIF out %d", idx-7);
204         else
205         if (idx >= 6)
206             snprintf(buf, sizeof(buf), "Mon out %d", idx+1);
207         else
208             snprintf(buf, sizeof(buf), "Line out %d", idx+1);
209     } else {
210         snprintf(buf, sizeof(buf), "out %d", idx);
211     }
212     return buf;
213 }
214
215 static std::string getInputName(const signed int model, const int idx)
216 {
217     char buf[64];
218     if (model == RME_MODEL_FIREFACE400) {
219         if (idx >= 10)
220             snprintf(buf, sizeof(buf), "ADAT in %d", idx-9);
221         else
222         if (idx >= 8)
223             snprintf(buf, sizeof(buf), "SPDIF in %d", idx-7);
224         else
225         if (idx >= 4)
226             snprintf(buf, sizeof(buf), "Line in %d", idx+1);
227         else
228         if (idx >= 2)
229             snprintf(buf, sizeof(buf), "Inst/line %d", idx+1);
230         else
231             snprintf(buf, sizeof(buf), "Mic/line %d", idx+1);
232     } else {
233         snprintf(buf, sizeof(buf), "in %d", idx);
234     }
235     return buf;
236 }
237
238 RmeSettingsMatrixCtrl::RmeSettingsMatrixCtrl(Device &parent, unsigned int type)
239 : Control::MatrixMixer(&parent)
240 , m_parent(parent)
241 , m_type(type)
242 {
243 }
244
245 RmeSettingsMatrixCtrl::RmeSettingsMatrixCtrl(Device &parent, unsigned int type,
246     std::string name)
247 : Control::MatrixMixer(&parent)
248 , m_parent(parent)
249 , m_type(type)
250 {
251     setName(name);
252 }
253
254 void RmeSettingsMatrixCtrl::show()
255 {
256     debugOutput(DEBUG_LEVEL_NORMAL, "RME matrix mixer type %d\n", m_type);
257 }
258
259 std::string RmeSettingsMatrixCtrl::getRowName(const int row)
260 {
261     if (m_type == RME_MATRIXCTRL_OUTPUT_FADER)
262         return "";
263     return getOutputName(m_parent.getRmeModel(), row);
264 }
265
266 std::string RmeSettingsMatrixCtrl::getColName(const int col)
267 {
268     if (m_type == RME_MATRIXCTRL_PLAYBACK_FADER)
269         return "";
270     if (m_type == RME_MATRIXCTRL_OUTPUT_FADER)
271         return getOutputName(m_parent.getRmeModel(), col);
272
273     return getInputName(m_parent.getRmeModel(), col);
274 }
275
276 int RmeSettingsMatrixCtrl::getRowCount()
277 {
278     switch (m_type) {
279         case RME_MATRIXCTRL_GAINS:
280             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
281                 return 1;
282             break;
283         case RME_MATRIXCTRL_INPUT_FADER:
284         case RME_MATRIXCTRL_PLAYBACK_FADER:
285             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
286                 return RME_FF400_MAX_CHANNELS;
287             else
288                 return RME_FF800_MAX_CHANNELS;
289             break;
290         case RME_MATRIXCTRL_OUTPUT_FADER:
291             return 1;
292             break;
293     }
294
295     return 0;
296 }
297
298 int RmeSettingsMatrixCtrl::getColCount()
299 {
300     switch (m_type) {
301         case RME_MATRIXCTRL_GAINS:
302             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
303                 return 22;
304             break;
305         case RME_MATRIXCTRL_INPUT_FADER:
306         case RME_MATRIXCTRL_PLAYBACK_FADER:
307         case RME_MATRIXCTRL_OUTPUT_FADER:
308             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
309                 return RME_FF400_MAX_CHANNELS;
310             else
311                 return RME_FF800_MAX_CHANNELS;
312             break;
313     }
314
315     return 0;
316 }
317
318 double RmeSettingsMatrixCtrl::setValue(const int row, const int col, const double val)
319 {
320     signed int ret = true;
321     signed int i;
322
323     switch (m_type) {
324         case RME_MATRIXCTRL_GAINS:
325             i = val;
326             if (i >= 0)
327                 ret = m_parent.setAmpGain(col, val);
328             else
329                 ret = -1;
330             break;
331         case RME_MATRIXCTRL_INPUT_FADER:
332           return m_parent.setMixerGain(RME_FF_MM_INPUT, col, row, val);
333           break;
334         case RME_MATRIXCTRL_PLAYBACK_FADER:
335           return m_parent.setMixerGain(RME_FF_MM_PLAYBACK, col, row, val);
336           break;
337         case RME_MATRIXCTRL_OUTPUT_FADER:
338           return m_parent.setMixerGain(RME_FF_MM_OUTPUT, col, row, val);
339           break;
340
341         case RME_MATRIXCTRL_INPUT_MUTE:
342           return m_parent.setMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_MUTED, val!=0);
343           break;
344         case RME_MATRIXCTRL_PLAYBACK_MUTE:
345           return m_parent.setMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_MUTED, val!=0);
346           break;
347         case RME_MATRIXCTRL_OUTPUT_MUTE:
348           return m_parent.setMixerFlags(RME_FF_MM_OUTPUT, col, row, FF_SWPARAM_MF_MUTED, val!=0);
349           break;
350         case RME_MATRIXCTRL_INPUT_INVERT:
351           return m_parent.setMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_INVERTED, val!=0);
352           break;
353         case RME_MATRIXCTRL_PLAYBACK_INVERT:
354           return m_parent.setMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_INVERTED, val!=0);
355           break;
356
357     }
358
359     return ret;
360 }
361
362 double RmeSettingsMatrixCtrl::getValue(const int row, const int col)
363 {
364     double val = 0.0;
365     switch (m_type) {
366         case RME_MATRIXCTRL_GAINS:
367             val = m_parent.getAmpGain(col);
368             break;
369         case RME_MATRIXCTRL_INPUT_FADER:
370             val = m_parent.getMixerGain(RME_FF_MM_INPUT, col, row);
371             break;
372         case RME_MATRIXCTRL_PLAYBACK_FADER:
373             val = m_parent.getMixerGain(RME_FF_MM_PLAYBACK, col, row);
374             break;
375         case RME_MATRIXCTRL_OUTPUT_FADER:
376             val = m_parent.getMixerGain(RME_FF_MM_OUTPUT, col, row);
377             break;
378
379         case RME_MATRIXCTRL_INPUT_MUTE:
380           return m_parent.getMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_MUTED) != 0;
381           break;
382         case RME_MATRIXCTRL_PLAYBACK_MUTE:
383           return m_parent.getMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_MUTED) != 0;
384           break;
385         case RME_MATRIXCTRL_OUTPUT_MUTE:
386           return m_parent.getMixerFlags(RME_FF_MM_OUTPUT, col, row, FF_SWPARAM_MF_MUTED) != 0;
387           break;
388         case RME_MATRIXCTRL_INPUT_INVERT:
389           return m_parent.getMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_INVERTED) != 0;
390           break;
391         case RME_MATRIXCTRL_PLAYBACK_INVERT:
392           return m_parent.getMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_INVERTED) != 0;
393           break;
394     }
395
396     return val;
397 }
398      
399
400 }
Note: See TracBrowser for help on using the browser.