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

Revision 2038, 14.8 kB (checked in by jwoithe, 9 years ago)

rme: various information panes are now active in ffado-mixer: sync check, autosync reference, spdif freqency and system clock. The function of these in the presence of actual external sync sources is yet to be confirmed. The system clock information has been confirmed to update when the clock mode and/or sample rate controls are altered.

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) == 0) {
97                 m_value = v;
98             }
99             break;
100         case RME_CTRL_OUTPUT_LEVEL:
101             if (m_parent.setOutputLevel(v) == 0) {
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) == 0) {
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) == 0) {
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_SPDIF_OUTPUT_OPTICAL:
123             if (m_parent.setSpdifOutputIsOptical(v!=0) == 0) {
124                m_value = (v != 0);
125             }
126             break;
127         case RME_CTRL_SPDIF_OUTPUT_PRO:
128             if (m_parent.setSpdifOutputProOn(v!=0) == 0) {
129                m_value = (v != 0);
130             }
131             break;
132         case RME_CTRL_SPDIF_OUTPUT_EMPHASIS:
133             if (m_parent.setSpdifOutputEmphasisOn(v!=0) == 0) {
134                m_value = (v != 0);
135             }
136             break;
137         case RME_CTRL_SPDIF_OUTPUT_NONAUDIO:
138             if (m_parent.setSpdifOutputNonAudioOn(v!=0) == 0) {
139                m_value = (v != 0);
140             }
141             break;
142         case RME_CTRL_PHONES_LEVEL:
143             if (m_parent.setPhonesLevel(v) == 0) {
144                 m_value = v;
145             }
146             break;
147
148         case RME_CTRL_CLOCK_MODE:
149             if (m_parent.setClockMode(v==1?FF_SWPARAM_CLOCK_MODE_AUTOSYNC:FF_SWPARAM_CLOCK_MODE_MASTER) == 0) {
150                 m_value = v;
151             }
152             break;
153
154         // All RME_CTRL_INFO_* controls are read-only.  Warn on attempts to
155         // set these.
156         case RME_CTRL_INFO_MODEL:
157         case RME_CTRL_INFO_TCO_PRESENT:
158         case RME_CTRL_INFO_SYSCLOCK_FREQ:
159         case RME_CTRL_INFO_AUTOSYNC_FREQ:
160         case RME_CTRL_INFO_AUTOSYNC_SRC:
161         case RME_CTRL_INFO_SYNC_STATUS:
162         case RME_CTRL_INFO_SPDIF_FREQ:
163             debugOutput(DEBUG_LEVEL_ERROR, "Attempt to set readonly info control 0x%08x\n", m_type);
164             err = 1;
165             break;
166
167         default:
168             debugOutput(DEBUG_LEVEL_ERROR, "Unknown control type 0x%08x\n", m_type);
169             err = 1;
170     }
171
172     return err==0?true:false;
173 }
174
175 int
176 RmeSettingsCtrl::getValue() {
177
178 signed int i;
179 signed int val = 0;
180 FF_state_t ff_state;
181
182     switch (m_type) {
183         case RME_CTRL_NONE:
184             debugOutput(DEBUG_LEVEL_ERROR, "control has no type set\n");
185             break;
186
187         case RME_CTRL_PHANTOM_SW:
188             for (i=0; i<3; i++)
189                 val |= (m_parent.getPhantom(i) << i);
190             return val;
191             break;
192         case RME_CTRL_INPUT_LEVEL:
193             return m_parent.getInputLevel();
194             break;
195         case RME_CTRL_OUTPUT_LEVEL:
196             return m_parent.getOutputLevel();
197             break;
198         case RME_CTRL_FF400_PAD_SW:
199             return m_parent.getInputPadOpt(m_info);
200             break;
201         case RME_CTRL_FF400_INSTR_SW:
202             return m_parent.getInputInstrOpt(m_info);
203             break;
204         case RME_CTRL_SPDIF_INPUT_MODE:
205             i = m_parent.getSpdifInputMode();
206             return i==FF_SWPARAM_SPDIF_INPUT_COAX?0:1;
207             break;
208         case RME_CTRL_SPDIF_OUTPUT_OPTICAL:
209             return m_parent.getSpdifOutputIsOptical();
210             break;
211         case RME_CTRL_SPDIF_OUTPUT_PRO:
212             return m_parent.getSpdifOutputProOn();
213             break;
214         case RME_CTRL_SPDIF_OUTPUT_EMPHASIS:
215             return m_parent.getSpdifOutputEmphasisOn();
216             break;
217         case RME_CTRL_SPDIF_OUTPUT_NONAUDIO:
218             return m_parent.getSpdifOutputNonAudioOn();
219             break;
220         case RME_CTRL_PHONES_LEVEL:
221             return m_parent.getPhonesLevel();
222             break;
223         case RME_CTRL_CLOCK_MODE:
224             return m_parent.getClockMode()==FF_SWPARAM_CLOCK_MODE_AUTOSYNC?1:0;
225             break;
226
227         case RME_CTRL_INFO_MODEL:
228             return m_parent.getRmeModel();
229             break;
230
231         case RME_CTRL_INFO_TCO_PRESENT:
232             return m_parent.getTcoPresent();
233
234         case RME_CTRL_INFO_SYSCLOCK_MODE:
235             if (m_parent.get_hardware_state(&ff_state) == 0)
236                 return ff_state.clock_mode;
237             break;
238         case RME_CTRL_INFO_SYSCLOCK_FREQ:
239             return m_parent.getSamplingFrequency();
240         case RME_CTRL_INFO_AUTOSYNC_FREQ:
241             if (m_parent.get_hardware_state(&ff_state) == 0)
242                 return ff_state.autosync_freq;
243             break;
244         case RME_CTRL_INFO_AUTOSYNC_SRC:
245             if (m_parent.get_hardware_state(&ff_state) == 0)
246                 return ff_state.autosync_source;
247             break;
248         case RME_CTRL_INFO_SYNC_STATUS:
249             if (m_parent.get_hardware_state(&ff_state) == 0)
250                 return (ff_state.adat1_sync_status) |
251                        (ff_state.adat2_sync_status << 2) |
252                        (ff_state.spdif_sync_status << 4) |
253                        (ff_state.wclk_sync_status << 6) |
254                        (ff_state.tco_sync_status << 8);
255             break;
256         case RME_CTRL_INFO_SPDIF_FREQ:
257             if (m_parent.get_hardware_state(&ff_state) == 0)
258                 return ff_state.spdif_freq;
259             break;
260
261         default:
262             debugOutput(DEBUG_LEVEL_ERROR, "Unknown control type 0x%08x\n", m_type);
263     }
264
265     return 0;
266 }
267
268
269 static std::string getOutputName(const signed int model, const int idx)
270 {
271     char buf[64];
272     if (model == RME_MODEL_FIREFACE400) {
273         if (idx >= 10)
274             snprintf(buf, sizeof(buf), "ADAT out %d", idx-9);
275         else
276         if (idx >= 8)
277             snprintf(buf, sizeof(buf), "SPDIF out %d", idx-7);
278         else
279         if (idx >= 6)
280             snprintf(buf, sizeof(buf), "Mon out %d", idx+1);
281         else
282             snprintf(buf, sizeof(buf), "Line out %d", idx+1);
283     } else {
284         snprintf(buf, sizeof(buf), "out %d", idx);
285     }
286     return buf;
287 }
288
289 static std::string getInputName(const signed int model, const int idx)
290 {
291     char buf[64];
292     if (model == RME_MODEL_FIREFACE400) {
293         if (idx >= 10)
294             snprintf(buf, sizeof(buf), "ADAT in %d", idx-9);
295         else
296         if (idx >= 8)
297             snprintf(buf, sizeof(buf), "SPDIF in %d", idx-7);
298         else
299         if (idx >= 4)
300             snprintf(buf, sizeof(buf), "Line in %d", idx+1);
301         else
302         if (idx >= 2)
303             snprintf(buf, sizeof(buf), "Inst/line %d", idx+1);
304         else
305             snprintf(buf, sizeof(buf), "Mic/line %d", idx+1);
306     } else {
307         snprintf(buf, sizeof(buf), "in %d", idx);
308     }
309     return buf;
310 }
311
312 RmeSettingsMatrixCtrl::RmeSettingsMatrixCtrl(Device &parent, unsigned int type)
313 : Control::MatrixMixer(&parent)
314 , m_parent(parent)
315 , m_type(type)
316 {
317 }
318
319 RmeSettingsMatrixCtrl::RmeSettingsMatrixCtrl(Device &parent, unsigned int type,
320     std::string name)
321 : Control::MatrixMixer(&parent)
322 , m_parent(parent)
323 , m_type(type)
324 {
325     setName(name);
326 }
327
328 void RmeSettingsMatrixCtrl::show()
329 {
330     debugOutput(DEBUG_LEVEL_NORMAL, "RME matrix mixer type %d\n", m_type);
331 }
332
333 std::string RmeSettingsMatrixCtrl::getRowName(const int row)
334 {
335     if (m_type == RME_MATRIXCTRL_OUTPUT_FADER)
336         return "";
337     return getOutputName(m_parent.getRmeModel(), row);
338 }
339
340 std::string RmeSettingsMatrixCtrl::getColName(const int col)
341 {
342     if (m_type == RME_MATRIXCTRL_PLAYBACK_FADER)
343         return "";
344     if (m_type == RME_MATRIXCTRL_OUTPUT_FADER)
345         return getOutputName(m_parent.getRmeModel(), col);
346
347     return getInputName(m_parent.getRmeModel(), col);
348 }
349
350 int RmeSettingsMatrixCtrl::getRowCount()
351 {
352     switch (m_type) {
353         case RME_MATRIXCTRL_GAINS:
354             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
355                 return 1;
356             break;
357         case RME_MATRIXCTRL_INPUT_FADER:
358         case RME_MATRIXCTRL_PLAYBACK_FADER:
359             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
360                 return RME_FF400_MAX_CHANNELS;
361             else
362                 return RME_FF800_MAX_CHANNELS;
363             break;
364         case RME_MATRIXCTRL_OUTPUT_FADER:
365             return 1;
366             break;
367     }
368
369     return 0;
370 }
371
372 int RmeSettingsMatrixCtrl::getColCount()
373 {
374     switch (m_type) {
375         case RME_MATRIXCTRL_GAINS:
376             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
377                 return 22;
378             break;
379         case RME_MATRIXCTRL_INPUT_FADER:
380         case RME_MATRIXCTRL_PLAYBACK_FADER:
381         case RME_MATRIXCTRL_OUTPUT_FADER:
382             if (m_parent.getRmeModel() == RME_MODEL_FIREFACE400)
383                 return RME_FF400_MAX_CHANNELS;
384             else
385                 return RME_FF800_MAX_CHANNELS;
386             break;
387     }
388
389     return 0;
390 }
391
392 double RmeSettingsMatrixCtrl::setValue(const int row, const int col, const double val)
393 {
394     signed int ret = true;
395     signed int i;
396
397     switch (m_type) {
398         case RME_MATRIXCTRL_GAINS:
399             i = val;
400             if (i >= 0)
401                 ret = m_parent.setAmpGain(col, val);
402             else
403                 ret = -1;
404             break;
405         case RME_MATRIXCTRL_INPUT_FADER:
406           return m_parent.setMixerGain(RME_FF_MM_INPUT, col, row, val);
407           break;
408         case RME_MATRIXCTRL_PLAYBACK_FADER:
409           return m_parent.setMixerGain(RME_FF_MM_PLAYBACK, col, row, val);
410           break;
411         case RME_MATRIXCTRL_OUTPUT_FADER:
412           return m_parent.setMixerGain(RME_FF_MM_OUTPUT, col, row, val);
413           break;
414
415         case RME_MATRIXCTRL_INPUT_MUTE:
416           return m_parent.setMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_MUTED, val!=0);
417           break;
418         case RME_MATRIXCTRL_PLAYBACK_MUTE:
419           return m_parent.setMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_MUTED, val!=0);
420           break;
421         case RME_MATRIXCTRL_OUTPUT_MUTE:
422           return m_parent.setMixerFlags(RME_FF_MM_OUTPUT, col, row, FF_SWPARAM_MF_MUTED, val!=0);
423           break;
424         case RME_MATRIXCTRL_INPUT_INVERT:
425           return m_parent.setMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_INVERTED, val!=0);
426           break;
427         case RME_MATRIXCTRL_PLAYBACK_INVERT:
428           return m_parent.setMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_INVERTED, val!=0);
429           break;
430
431     }
432
433     return ret;
434 }
435
436 double RmeSettingsMatrixCtrl::getValue(const int row, const int col)
437 {
438     double val = 0.0;
439     switch (m_type) {
440         case RME_MATRIXCTRL_GAINS:
441             val = m_parent.getAmpGain(col);
442             break;
443         case RME_MATRIXCTRL_INPUT_FADER:
444             val = m_parent.getMixerGain(RME_FF_MM_INPUT, col, row);
445             break;
446         case RME_MATRIXCTRL_PLAYBACK_FADER:
447             val = m_parent.getMixerGain(RME_FF_MM_PLAYBACK, col, row);
448             break;
449         case RME_MATRIXCTRL_OUTPUT_FADER:
450             val = m_parent.getMixerGain(RME_FF_MM_OUTPUT, col, row);
451             break;
452
453         case RME_MATRIXCTRL_INPUT_MUTE:
454           return m_parent.getMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_MUTED) != 0;
455           break;
456         case RME_MATRIXCTRL_PLAYBACK_MUTE:
457           return m_parent.getMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_MUTED) != 0;
458           break;
459         case RME_MATRIXCTRL_OUTPUT_MUTE:
460           return m_parent.getMixerFlags(RME_FF_MM_OUTPUT, col, row, FF_SWPARAM_MF_MUTED) != 0;
461           break;
462         case RME_MATRIXCTRL_INPUT_INVERT:
463           return m_parent.getMixerFlags(RME_FF_MM_INPUT, col, row, FF_SWPARAM_MF_INVERTED) != 0;
464           break;
465         case RME_MATRIXCTRL_PLAYBACK_INVERT:
466           return m_parent.getMixerFlags(RME_FF_MM_PLAYBACK, col, row, FF_SWPARAM_MF_INVERTED) != 0;
467           break;
468     }
469
470     return val;
471 }
472      
473
474 }
Note: See TracBrowser for help on using the browser.