Clean up compiler warnings when compiling on 64-bit systems. These are mostly fixing...
[ffado.git] / libffado / support / mixer-qt4 / ffado / mixer / rme.py
blobf4fb852280439442b6de8ba0ec2fa35c8db9c473
2 # Copyright (C) 2009, 2011 by Jonathan Woithe
4 # This file is part of FFADO
5 # FFADO = Free Firewire (pro-)audio drivers for linux
7 # FFADO is based upon FreeBoB.
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 2 of the License, or
12 # (at your option) version 3 of the License.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 from PyQt4 import QtGui
25 from PyQt4.QtCore import SIGNAL, SLOT, QObject, Qt, QTimer
26 from PyQt4.QtGui import QWidget, QApplication
27 from ffado.config import *
29 from ffado.widgets.matrixmixer import MatrixMixer
31 import logging
32 log = logging.getLogger('rme')
34 # Model defines. These must agree with what is used in rme_avdevice.h.
35 RME_MODEL_NONE = 0x0000
36 RME_MODEL_FF800 = 0x0001
37 RME_MODEL_FF400 = 0x0002
39 class Rme(QWidget):
40 def __init__(self,parent = None):
41 QWidget.__init__(self,parent)
42 uicLoad("ffado/mixer/rme", self)
44 self.init()
46 def init(self):
48 self.PhantomSwitches={
49 self.phantom_0: ['/Control/Phantom', 0],
50 self.phantom_1: ['/Control/Phantom', 1],
51 self.phantom_2: ['/Control/Phantom', 2],
52 self.phantom_3: ['/Control/Phantom', 3],
55 self.Switches={
56 self.ff400_chan3_opt_instr: ['/Control/Chan3_opt_instr'],
57 self.ff400_chan3_opt_pad: ['/Control/Chan3_opt_pad'],
58 self.ff400_chan4_opt_instr: ['/Control/Chan4_opt_instr'],
59 self.ff400_chan4_opt_pad: ['/Control/Chan4_opt_pad'],
61 self.spdif_output_optical: ['/Control/SPDIF_output_optical', 0],
62 self.spdif_output_emphasis: ['/Control/SPDIF_output_emphasis', 0],
63 self.spdif_output_pro: ['/Control/SPDIF_output_pro', 0],
64 self.spdif_output_nonaudio: ['/Control/SPDIF_output_nonaudio', 0],
67 self.Radiobuttons={
68 self.level_in_lo_gain: ['/Control/Input_level', 0],
69 self.level_in_p4dBu: ['/Control/Input_level', 2],
70 self.level_in_m10dBV: ['/Control/Input_level', 1],
72 self.level_out_hi_gain: ['/Control/Output_level', 2],
73 self.level_out_p4dBu: ['/Control/Output_level', 1],
74 self.level_out_m10dBV: ['/Control/Output_level', 0],
76 self.spdif_input_coax: ['/Control/SPDIF_input_mode', 0],
77 self.spdif_input_optical: ['/Control/SPDIF_input_mode', 1],
79 self.phones_hi_gain: ['/Control/Phones_level', 0],
80 self.phones_p4dBu: ['/Control/Phones_level', 1],
81 self.phones_m10dBV: ['/Control/Phones_level', 2],
83 self.clock_mode_autosync: ['/Control/Clock_mode', 1],
84 self.clock_mode_master: ['/Control/Clock_mode', 0],
86 self.sync_ref_wordclk: ['/Control/Sync_ref', 0],
87 self.sync_ref_adat1: ['/Control/Sync_ref', 1],
88 self.sync_ref_adat2: ['/Control/Sync_ref', 2],
89 self.sync_ref_spdif: ['/Control/Sync_ref', 3],
90 self.sync_ref_tco: ['/Control/Sync_ref', 4],
93 self.Checkboxes={
94 self.ch1_instr_fuzz: ['/Control/Chan1_instr_opts', 0x04],
95 self.ch1_instr_limiter: ['/Control/Chan1_instr_opts', 0x08],
96 self.ch1_instr_filter: ['/Control/Chan1_instr_opts', 0x02],
99 self.Gains={
100 self.gain_mic1: ['/Control/Gains', 0],
101 self.gain_mic2: ['/Control/Gains', 1],
102 self.gain_input3: ['/Control/Gains', 2],
103 self.gain_input4: ['/Control/Gains', 3],
106 self.Combos={
107 self.ff800_ch1_src: ['/Control/Chan1_source'],
108 self.ff800_ch7_src: ['/Control/Chan7_source'],
109 self.ff800_ch8_src: ['/Control/Chan8_source'],
112 self.CommandButtons={
113 self.control_load: ['/Control/Flash_control', 0],
114 self.control_save: ['/Control/Flash_control', 1],
115 self.mixer_load: ['/Control/Flash_control', 2],
116 self.mixer_save: ['/Control/Flash_control', 3],
117 self.mixer_preset_ffado_default: ['/Control/Mixer_preset', 0],
120 # Other mixer variables
121 self.is_streaming = 0
122 self.sample_rate = 0
123 self.model = 0
124 self.tco_present = 0
126 # Public slot: update phantom power hardware switches
127 def updatePhantomSwitch(self, a0):
128 sender = self.sender()
129 # Value is the phantom switch value, with a corresponding enable
130 # bit in the high 16 bit word
131 val = (a0 << self.PhantomSwitches[sender][1]) | (0x00010000 << self.PhantomSwitches[sender][1])
132 log.debug("phantom switch %d set to %d" % (self.PhantomSwitches[sender][1], a0))
133 self.hw.setDiscrete(self.PhantomSwitches[sender][0], val)
135 # Public slot: update generic switches
136 def updateSwitch(self, a0):
137 sender = self.sender()
138 log.debug("switch %s set to %d" % (self.Switches[sender][0], a0))
139 self.hw.setDiscrete(self.Switches[sender][0], a0)
141 # Public slot: update generic radiobuttons
142 def updateRadiobutton(self, a0):
143 sender = self.sender()
144 if (a0 != 0):
145 # Only change the control state on a button being "checked"
146 log.debug("radiobutton group %s set to %d" % (self.Radiobuttons[sender][0], self.Radiobuttons[sender][1]))
147 self.hw.setDiscrete(self.Radiobuttons[sender][0], self.Radiobuttons[sender][1])
149 def updateCheckboxes(self, a0):
150 sender = self.sender()
151 val = self.hw.getDiscrete(self.Checkboxes[sender][0]);
152 if (a0 != 0):
153 val = val | self.Checkboxes[sender][1]
154 else:
155 val = val & ~self.Checkboxes[sender][1]
156 log.debug("checkbox group %s set to %d" % (self.Checkboxes[sender][0], val));
157 self.hw.setDiscrete(self.Checkboxes[sender][0], val)
159 # Public slot: update gains
160 def updateGain(self, a0):
161 sender = self.sender()
162 log.debug("gain %s[%d] set to %d" % (self.Gains[sender][0], self.Gains[sender][1], a0))
163 self.hw.setMatrixMixerValue(self.Gains[sender][0], 0, self.Gains[sender][1], a0)
165 def updateBandwidthLimit(self, a0):
166 # Account for the "No ADAT-2" item which will not be present on
167 # a FF400.
168 if (self.model==RME_MODEL_FF400 and a0>0):
169 a0 = a0 + 1
170 # log.debug("limit update: %d" % (a0));
171 self.hw.setDiscrete('/Control/Bandwidth_limit', a0);
173 # Public slot: send command
174 def sendCommand(self, a0):
175 sender = self.sender()
176 log.debug("command %d sent to %s" % (self.CommandButtons[sender][1], self.CommandButtons[sender][0]))
177 self.hw.setDiscrete(self.CommandButtons[sender][0], self.CommandButtons[sender][1])
179 # If mixer values have been reloaded, refresh the mixer GUI. This
180 # will also commit the new values to the hardware via the "changed"
181 # signal handlers of the mixer elements.
182 if (self.CommandButtons[sender][1] == 2):
183 self.inputmatrix.refreshValues()
184 self.outputmatrix.refreshValues()
185 self.playbackmatrix.refreshValues()
187 # If settings have been reloaded from flash, refresh the GUI. The
188 # settings will be made active in the hardware via the "changed"
189 # signal handlers of the respective GUI control widgets.
190 if (self.CommandButtons[sender][1] == 0):
191 self.getValuesFromFF()
193 def updateCombo(self, a0):
194 sender = self.sender()
195 log.debug("combo %s set to %d" % (self.Combos[sender][0], a0))
196 self.hw.setDiscrete(self.Combos[sender][0], a0)
198 # Enable the limiter control only when the front source is active
199 if (sender == self.ff800_ch1_src):
200 self.ch1_instr_limiter.setEnabled(a0==0)
202 def updateStreamingState(self):
203 ss = self.streamingstatus.selected()
204 ss_txt = self.streamingstatus.getEnumLabel(ss)
205 if ss_txt != 'Idle':
206 self.is_streaming = True
207 else:
208 self.is_streaming = False
209 if (self.last_streaming_state != self.is_streaming):
210 self.bandwidth_limit.setEnabled(not(self.is_streaming));
211 self.control_load.setEnabled(not(self.is_streaming));
212 self.last_streaming_state = self.is_streaming
214 def status_update(self):
215 # log.debug("timer event")
216 self.updateStreamingState()
217 clk_mode = ['Master', 'Slave']
218 src_str = ['None', 'ADAT 1', 'ADAT 2', 'SPDIF', 'Wordclock', 'TCO']
219 sync_stat = ['No lock', 'Locked', 'Synced']
220 sysclock_mode = self.hw.getDiscrete('/Control/sysclock_mode')
221 sysclock_freq = self.hw.getDiscrete('/Control/sysclock_freq')
222 autosync_freq = self.hw.getDiscrete('/Control/autosync_freq')
223 autosync_src = self.hw.getDiscrete('/Control/autosync_src')
224 sync_status = self.hw.getDiscrete('/Control/sync_status')
225 spdif_freq = self.hw.getDiscrete('/Control/spdif_freq')
226 self.sysclock_freq.setText("%d Hz" % (sysclock_freq))
227 self.sysclock_mode.setText(clk_mode[sysclock_mode])
228 self.autosync_freq.setText("%d Hz" % (autosync_freq))
229 self.autosync_src.setText(src_str[autosync_src])
230 self.sync_check_adat1_status.setText(sync_stat[sync_status & 0x03])
231 self.sync_check_adat2_status.setText(sync_stat[(sync_status >> 2) & 0x03])
232 self.sync_check_spdif_status.setText(sync_stat[(sync_status >> 4) & 0x03])
233 self.sync_check_wclk_status.setText(sync_stat[(sync_status >> 6) & 0x03])
234 self.sync_check_tco_status.setText(sync_stat[(sync_status >> 8) & 0x03])
235 self.spdif_freq.setText("%d Hz" % (spdif_freq))
237 # Hide and disable a control
238 def disable_hide(self,widget):
239 for w in widget.children():
240 if isinstance(w, QWidget):
241 w.hide()
242 w.setEnabled(False)
243 widget.hide()
244 widget.setEnabled(False)
246 def setupSignals(self):
248 # Connect signal handlers for all command buttons
249 for ctrl, info in self.CommandButtons.iteritems():
250 if (not(ctrl.isEnabled())):
251 continue
252 QObject.connect(ctrl, SIGNAL('clicked(bool)'), self.sendCommand)
254 for ctrl, info in self.Combos.iteritems():
255 if (not(ctrl.isEnabled())):
256 continue;
257 QObject.connect(ctrl, SIGNAL('currentIndexChanged(int)'), self.updateCombo)
259 QObject.connect(self.bandwidth_limit, SIGNAL('currentIndexChanged(int)'), self.updateBandwidthLimit)
261 # Get current hardware values and connect GUI element signals to
262 # their respective slots
263 for ctrl, info in self.PhantomSwitches.iteritems():
264 if (not(ctrl.isEnabled())):
265 continue
266 QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updatePhantomSwitch)
268 for ctrl, info in self.Switches.iteritems():
269 if (not(ctrl.isEnabled())):
270 continue
271 QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateSwitch)
273 for ctrl, info in self.Radiobuttons.iteritems():
274 if (not(ctrl.isEnabled())):
275 continue;
276 QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateRadiobutton)
278 for ctrl, info in self.Checkboxes.iteritems():
279 if (not(ctrl.isEnabled())):
280 continue;
281 QObject.connect(ctrl, SIGNAL('toggled(bool)'), self.updateCheckboxes)
283 for ctrl, info in self.Gains.iteritems():
284 if (not(ctrl.isEnabled())):
285 continue
286 QObject.connect(ctrl, SIGNAL('valueChanged(int)'), self.updateGain)
288 # Obtain control values from the Fireface and make the GUI reflect these
289 def getValuesFromFF(self):
290 for ctrl, info in self.Combos.iteritems():
291 if (not(ctrl.isEnabled())):
292 continue;
293 val = self.hw.getDiscrete(info[0])
294 log.debug("combo %s is %d" % (info[0], val));
295 ctrl.setCurrentIndex(val);
297 # Set the bandwidth limit control to reflect the current device
298 # setting, allowing for the additional "No ADAT-2" item which is
299 # present on the FF800.
300 val = self.hw.getDiscrete('/Control/Bandwidth_limit')
301 if (self.model==RME_MODEL_FF400 and val>1):
302 val = val - 1
303 self.bandwidth_limit.setCurrentIndex(val);
305 # Get current hardware values
306 for ctrl, info in self.PhantomSwitches.iteritems():
307 if (not(ctrl.isEnabled())):
308 continue
309 val = (self.hw.getDiscrete(info[0]) >> info[1]) & 0x01
310 log.debug("phantom switch %d is %d" % (info[1], val))
311 if val:
312 ctrl.setChecked(True)
313 else:
314 ctrl.setChecked(False)
316 for ctrl, info in self.Switches.iteritems():
317 if (not(ctrl.isEnabled())):
318 continue
319 val = self.hw.getDiscrete(info[0])
320 log.debug("switch %s is %d" % (info[0], val))
321 if val:
322 ctrl.setChecked(True)
323 else:
324 ctrl.setChecked(False)
326 for ctrl, info in self.Radiobuttons.iteritems():
327 if (not(ctrl.isEnabled())):
328 continue;
329 # This is a touch wasteful since it means we retrieve the control
330 # value once per radio button rather than once per radio button
331 # group. In time we might introduce radiobutton groupings in the
332 # self.* datastructures to avoid this, but for the moment this is
333 # easy and it works.
334 val = self.hw.getDiscrete(info[0])
335 if (val == info[1]):
336 val = 1
337 else:
338 val = 0
339 ctrl.setChecked(val)
340 log.debug("Radiobutton %s[%d] is %d" % (info[0], info[1], val))
342 # Make sure the Limiter control can receive a value
343 if (self.ff800_ch1_src.isEnabled()):
344 self.ch1_instr_limiter.setEnabled(1)
346 for ctrl, info in self.Checkboxes.iteritems():
347 if (not(ctrl.isEnabled())):
348 continue;
349 # This is a touch wasteful since it means we retrieve the control
350 # value once per checkbox button rather than once per checkbox
351 # group. In time we might introduce checkbox groupings in the
352 # self.* datastructures to avoid this, but for the moment this is
353 # easy and it works.
354 val = self.hw.getDiscrete(info[0])
355 if (val & info[1]):
356 val = 1
357 else:
358 val = 0
359 ctrl.setChecked(val)
360 log.debug("Checkbox %s[%d] is %d" % (info[0], info[1], val))
362 # The limiter (a checkbox) can only be controlled if the front
363 # source is selected for channel 1.
364 ch1_src = self.ff800_ch1_src.currentIndex()
365 if (self.ff800_ch1_src.isEnabled()):
366 self.ch1_instr_limiter.setEnabled(ch1_src==0)
368 for ctrl, info in self.Gains.iteritems():
369 if (not(ctrl.isEnabled())):
370 continue
371 val = self.hw.getMatrixMixerValue(info[0], 0, info[1])
372 log.debug("gain %s[%d] is %d" % (info[0], info[1], val))
373 ctrl.setValue(val);
377 def initValues(self):
379 # print self.hw.servername
380 # print self.hw.basepath
381 self.inputmatrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/Mixer/InputFaders", self, "Columns_are_inputs", 0x8000, self.hw.basepath+"/Mixer/InputMutes", self.hw.basepath+"/Mixer/InputInverts", True)
382 layout = QtGui.QVBoxLayout()
383 layout.addWidget(self.inputmatrix)
384 self.mixer.setLayout(layout)
386 self.playbackmatrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/Mixer/PlaybackFaders", self, "Columns_are_inputs", 0x8000, self.hw.basepath+"/Mixer/PlaybackMutes", self.hw.basepath+"/Mixer/PlaybackInverts", True)
387 layout = QtGui.QVBoxLayout()
388 layout.addWidget(self.playbackmatrix)
389 self.playbackmixer.setLayout(layout)
391 self.outputmatrix = MatrixMixer(self.hw.servername, self.hw.basepath+"/Mixer/OutputFaders", self, "Columns_are_inputs", 0x8000, self.hw.basepath+"/Mixer/OutputMutes", None, True)
392 layout = QtGui.QVBoxLayout()
394 # This is a bit of a hack, but it works to ensure this single-row
395 # matrix mixer doesn't fill the entire screen but also doesn't end
396 # up with a pointless scrollbar. The matrix mixer's minimum height
397 # is 0 according to minimumHeight(), which is probably the
398 # fundamental issue here; however, I've already wasted too much time
399 # trying to get this to work so if the hack is effective we'll run
400 # with it.
401 self.outputmatrix.setMinimumHeight(150)
402 layout.addWidget(self.outputmatrix, 0, Qt.AlignTop)
403 self.outputmixer.setLayout(layout)
405 self.is_streaming = False
406 self.last_streaming_state = False
408 # Disable the "load settings" button if streaming is active. Its
409 # enable state will be kept up to date by updateStreamingState().
410 self.control_load.setEnabled(not(self.is_streaming))
412 # Also disable other controls which are not yet implemented.
413 self.mixer_preset_ffado_default.setEnabled(False)
415 # Retrieve other device settings as needed and customise the UI
416 # based on these options.
417 self.model = self.hw.getDiscrete('/Control/Model')
418 log.debug("device model identifier: %d" % (self.model))
419 self.tco_present = self.hw.getDiscrete('/Control/TCO_present')
420 log.debug("device has TCO: %d" % (self.tco_present))
421 #self.sample_rate = self.hw.getDiscrete('/Mixer/Info/SampleRate')
422 #log.debug("device sample rate: %d" % (self.sample_rate))
424 # The Fireface-400 only has 2 phantom-capable channels
425 if (self.model == RME_MODEL_FF400):
426 self.disable_hide(self.phantom_2)
427 self.disable_hide(self.phantom_3)
428 else:
429 self.phantom_0.setText("Mic 7")
430 self.phantom_1.setText("Mic 8")
431 self.phantom_2.setText("Mic 9")
432 self.phantom_3.setText("Mic 10")
434 # Instrument options, input jack selection controls and an ADAT2
435 # input are applicable only to the FF800
436 if (self.model != RME_MODEL_FF800):
437 self.instrument_options_group.setEnabled(False)
438 self.input_plug_select_group.setEnabled(False)
439 self.sync_ref_adat2.setEnabled(False)
440 self.sync_check_adat2_label.setEnabled(False)
441 self.sync_check_adat2_status.setEnabled(False)
443 if (not(self.tco_present)):
444 self.sync_check_tco_label.setEnabled(False)
445 self.sync_check_tco_status.setEnabled(False)
446 self.sync_ref_tco.setEnabled(False)
448 # Only the FF400 has specific channel 3/4 options, input gain
449 # controls and switchable phones level
450 if (self.model != RME_MODEL_FF400):
451 # Hide the upper-level frame (and everything in it) to ensure it
452 # requests no vertical space when its contents aren't needed.
453 self.disable_hide(self.igains_chan34_opts_frame)
454 self.phones_level_group.setEnabled(False)
456 # Add the "No ADAT-2" item to the bandwidth limit control if the
457 # device is not a FF400.
458 if (self.model != RME_MODEL_FF400):
459 self.bandwidth_limit.insertItem(1, "No ADAT-2")
461 self.getValuesFromFF()
462 self.setupSignals()
464 # Ensure the limiter checkbox has a signal handler associated with
465 # it. If getValuesFromFF() disabled it because the front input was
466 # not selected, setupSignals() would not have configured a handler.
467 if (not(self.ch1_instr_limiter.isEnabled())):
468 QObject.connect(self.ch1_instr_limiter, SIGNAL('toggled(bool)'), self.updateCheckboxes)
470 self.updateStreamingState()
471 #log.debug("device streaming flag: %d" % (self.is_streaming))
473 self.update_timer = QTimer(self)
474 QObject.connect(self.update_timer, SIGNAL('timeout()'), self.status_update)
475 self.update_timer.start(1000)
477 def saveSettings(self, indent):
478 saveString = []
479 idt = indent + " "
480 saveString.append('%s<inputmatrix>\n' % indent)
481 saveString.extend(self.inputmatrix.saveSettings(idt))
482 # Do not forget to mention the adopted rule for matrix columns mixer
483 # This might be useful for future import function
484 saveString.append("%s <col_rule>\n" % indent)
485 saveString.append("%s Columns_are_inputs\n" % indent)
486 saveString.append("%s </col_rule>\n" % indent)
487 saveString.append('%s</inputmatrix>\n' % indent)
489 saveString.append('%s<playbackmatrix>\n' % indent)
490 saveString.extend(self.inputmatrix.saveSettings(idt))
491 # Do not forget to mention the adopted rule for matrix columns mixer
492 # This might be useful for future import function
493 saveString.append("%s <col_rule>\n" % indent)
494 saveString.append("%s Columns_are_inputs\n" % indent)
495 saveString.append("%s </col_rule>\n" % indent)
496 saveString.append('%s</playbackmatrix>\n' % indent)
498 saveString.append('%s<outputmatrix>\n' % indent)
499 saveString.extend(self.inputmatrix.saveSettings(idt))
500 # Do not forget to mention the adopted rule for matrix columns mixer
501 # This might be useful for future import function
502 saveString.append("%s <col_rule>\n" % indent)
503 saveString.append("%s Columns_are_inputs\n" % indent)
504 saveString.append("%s </col_rule>\n" % indent)
505 saveString.append('%s</outputmatrix>\n' % indent)
506 return saveString
508 def readSettings(self, readString):
509 try:
510 idxb = readString.index('<inputmatrix>')
511 idxe = readString.index('</inputmatrix>')
512 except Exception:
513 log.debug("No Input matrix settings found")
514 idxb = -1
515 idxe = -1
516 if idxb >= 0:
517 if idxe > idxb + 1:
518 stringMixer = []
519 for s in readString[idxb+1:idxe]:
520 stringMixer.append(s)
521 # When trying to import from a different device, the rule for column interpretation is
522 # not necessarily the same
523 try:
524 idx = stringMixer.index('<col_rule>')
525 except Exception:
526 log.debug('Do not know how to handle column versus input/output')
527 idx = -1
528 transpose_coeff = False
529 if idx >=0:
530 if stringMixer[idx+1].find("Columns_are_inputs") == -1:
531 log.debug('Transposing the matrix coefficient; you are importing, are not you ?')
532 transpose_coeff = True
533 if self.inputmatrix.readSettings(stringMixer, transpose_coeff):
534 log.debug("Input matrix settings modified")
535 del stringMixer
537 try:
538 idxb = readString.index('<playbackmatrix>')
539 idxe = readString.index('</playbackmatrix>')
540 except Exception:
541 log.debug("No Plaback matrix settings found")
542 idxb = -1
543 idxe = -1
544 if idxb >= 0:
545 if idxe > idxb + 1:
546 stringMixer = []
547 for s in readString[idxb+1:idxe]:
548 stringMixer.append(s)
549 # When trying to import from a different device, the rule for column interpretation is
550 # not necessarily the same
551 try:
552 idx = stringMixer.index('<col_rule>')
553 except Exception:
554 log.debug('Do not know how to handle column versus input/output')
555 idx = -1
556 transpose_coeff = False
557 if idx >=0:
558 if stringMixer[idx+1].find("Columns_are_inputs") == -1:
559 log.debug('Transposing the matrix coefficient; you are importing, are not you ?')
560 transpose_coeff = True
561 if self.playbackmatrix.readSettings(stringMixer, transpose_coeff):
562 log.debug("Plaback matrix settings modified")
563 del stringMixer
565 try:
566 idxb = readString.index('<outputmatrix>')
567 idxe = readString.index('</outputmatrix>')
568 except Exception:
569 log.debug("No Output matrix settings found")
570 idxb = -1
571 idxe = -1
572 if idxb >= 0:
573 if idxe > idxb + 1:
574 stringMixer = []
575 for s in readString[idxb+1:idxe]:
576 stringMixer.append(s)
577 # When trying to import from a different device, the rule for column interpretation is
578 # not necessarily the same
579 try:
580 idx = stringMixer.index('<col_rule>')
581 except Exception:
582 log.debug('Do not know how to handle column versus input/output')
583 idx = -1
584 transpose_coeff = False
585 if idx >=0:
586 if stringMixer[idx+1].find("Columns_are_inputs") == -1:
587 log.debug('Transposing the matrix coefficient; you are importing, are not you ?')
588 transpose_coeff = True
589 if self.outputmatrix.readSettings(stringMixer, transpose_coeff):
590 log.debug("Output matrix settings modified")
591 del stringMixer
593 # vim: et