Skip to content

Commit 7df4b01

Browse files
committed
MackieHostControl.py: optimised challenge-response code
* MackieHostControl.py: version requests now work when MCU emulation is online * GUI: auto-scroll log window * support "V-Select" LEDs * ApplicationAbout.py: correct calculation of path to configuration file * ApplicationAbout.py: limited license term display in __repr__() to five lines
1 parent 81cfe6e commit 7df4b01

File tree

4 files changed

+258
-217
lines changed

4 files changed

+258
-217
lines changed

src/PythonMcu.py

Lines changed: 64 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ def __init__(self, parent=None):
7979
self.callback_log('')
8080
self.callback_log('')
8181

82+
# auto-scroll log window by setting cursor to end of document
83+
self._edit_logger.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
84+
8285
self._read_configuration()
8386

8487
self._timer = None
@@ -122,28 +125,22 @@ def __init__(self, parent=None):
122125

123126

124127
self._combo_mcu_model_id = self._create_combo_box( \
125-
self.grid_layout_mcu, self._emulated_mcu_model, \
126-
'MCU model:', mcu_model_ids)
127-
128-
self._checkbox_use_challenge_response = QCheckBox()
129-
self._checkbox_use_challenge_response.setText('Use ch&allenge response')
130-
131-
if self._use_challenge_response:
132-
self._checkbox_use_challenge_response.setCheckState(Qt.Checked)
133-
else:
134-
self._checkbox_use_challenge_response.setCheckState(Qt.Unchecked)
128+
self.grid_layout_mcu, self._mcu_emulated_model, \
129+
'Emulation:', mcu_model_ids)
135130

136-
self.grid_layout_mcu.addWidget(self._checkbox_use_challenge_response, \
137-
self.grid_layout_mcu.rowCount(), 1)
138-
self._checkbox_use_challenge_response.stateChanged.connect( \
139-
(self.checkbox_state_changed))
131+
connection_types = [MackieHostControl.ASSUME_SUCCESSFUL_CONNECTION, \
132+
MackieHostControl.CHALLENGE_RESPONSE, \
133+
MackieHostControl.WAIT_FOR_MIDI_DATA]
134+
self._combo_mcu_connection = self._create_combo_box( \
135+
self.grid_layout_mcu, self._mcu_connection, \
136+
'Connection:', connection_types)
140137

141138
self._combo_mcu_midi_input = self._create_combo_box( \
142-
self.grid_layout_mcu, self._sequencer_midi_input, \
143-
'MIDI In:', MidiConnection.get_midi_inputs(), )
139+
self.grid_layout_mcu, self._mcu_midi_input, \
140+
'MIDI In:', MidiConnection.get_midi_inputs())
144141

145142
self._combo_mcu_midi_output = self._create_combo_box( \
146-
self.grid_layout_mcu, self._sequencer_midi_output, \
143+
self.grid_layout_mcu, self._mcu_midi_output, \
147144
'MIDI Out:', MidiConnection.get_midi_outputs())
148145

149146

@@ -191,54 +188,50 @@ def __init__(self, parent=None):
191188

192189
def _read_configuration(self):
193190
# initialise defaults for MCU and hardware controller
194-
emulated_mcu_model_default = MackieHostControl.get_preferred_mcu_model()
191+
mcu_emulated_model_default = MackieHostControl.get_preferred_mcu_model()
195192
hardware_controller_default = 'Novation ZeRO SL MkII'
196193
midi_latency_default = '1'
197194

198195
# retrieve user configuration for MCU and hardware controller
199-
self._emulated_mcu_model = configuration.get_option( \
200-
'Python MCU', 'emulated_mcu_model', emulated_mcu_model_default)
196+
self._mcu_emulated_model = configuration.get_option( \
197+
'Python MCU', 'mcu_emulated_model', mcu_emulated_model_default)
201198
self._hardware_controller = configuration.get_option( \
202-
'Python MCU', 'hardware_controller', hardware_controller_default)
199+
'Python MCU', 'controller_hardware', hardware_controller_default)
203200
self._midi_latency = configuration.get_option( \
204201
'Python MCU', 'midi_latency', midi_latency_default)
205202

206203
# calculate MCU model ID from its name
207204
self._mcu_model_id = MackieHostControl.get_mcu_id_from_model( \
208-
self._emulated_mcu_model)
205+
self._mcu_emulated_model)
209206

210207
# Logic Control units use MCU challenge-response by default, ...
211208
if self._mcu_model_id in [0x10, 0x11]:
212-
use_challenge_response_default = True
209+
mcu_connection_default = MackieHostControl.CHALLENGE_RESPONSE
213210
# whereas Mackie Control Units don't seem to use it
214211
else:
215-
use_challenge_response_default = False
212+
mcu_connection_default = MackieHostControl.WAIT_FOR_MIDI_DATA
216213

217-
if configuration.get_option( \
218-
'Python MCU', 'use_challenge_response', \
219-
use_challenge_response_default) == 'True':
220-
self._use_challenge_response = True
221-
else:
222-
self._use_challenge_response = False
214+
self._mcu_connection = configuration.get_option( \
215+
'Python MCU', 'mcu_connection', mcu_connection_default)
223216

224217
# get preferred MIDI ports for hardware controller
225218
(controller_midi_input_default, controller_midi_output_default) = \
226219
self._initialise_hardware_controller()
227220

228221
# initialise MIDI port defaults for MCU and hardware
229222
# controller
230-
sequencer_midi_input_default = \
223+
mcu_midi_input_default = \
231224
MackieHostControl.get_preferred_midi_input()
232-
sequencer_midi_output_default = \
225+
mcu_midi_output_default = \
233226
MackieHostControl.get_preferred_midi_output()
234227

235228
# retrieve user configuration for MCU's MIDI ports
236-
self._sequencer_midi_input = configuration.get_option( \
237-
'Python MCU', 'sequencer_midi_input', \
238-
sequencer_midi_input_default)
239-
self._sequencer_midi_output = configuration.get_option( \
240-
'Python MCU', 'sequencer_midi_output', \
241-
sequencer_midi_output_default)
229+
self._mcu_midi_input = configuration.get_option( \
230+
'Python MCU', 'mcu_midi_input', \
231+
mcu_midi_input_default)
232+
self._mcu_midi_output = configuration.get_option( \
233+
'Python MCU', 'mcu_midi_output', \
234+
mcu_midi_output_default)
242235

243236
# retrieve user configuration for hardware controller's MIDI
244237
# ports
@@ -319,31 +312,34 @@ def combobox_item_selected(self, selected_text):
319312
widget = self.sender()
320313

321314
if widget == self._combo_mcu_model_id:
322-
self._emulated_mcu_model = selected_text
315+
self._mcu_emulated_model = selected_text
323316
configuration.set_option( \
324-
'Python MCU', 'emulated_mcu_model', \
325-
self._emulated_mcu_model)
317+
'Python MCU', 'mcu_emulated_model', \
318+
self._mcu_emulated_model)
326319

327-
if self._emulated_mcu_model.startswith('Logic'):
328-
self._checkbox_use_challenge_response.setCheckState(Qt.Checked)
320+
if self._mcu_emulated_model.startswith('Logic'):
321+
current_index = self._combo_mcu_connection.findText( \
322+
MackieHostControl.CHALLENGE_RESPONSE)
323+
self._combo_mcu_connection.setCurrentIndex(current_index)
329324
else:
330-
self._checkbox_use_challenge_response.setCheckState( \
331-
Qt.Unchecked)
325+
current_index = self._combo_mcu_connection.findText( \
326+
MackieHostControl.WAIT_FOR_MIDI_DATA)
327+
self._combo_mcu_connection.setCurrentIndex(current_index)
332328

333329
elif widget == self._combo_mcu_midi_input:
334-
self._sequencer_midi_input = selected_text
330+
self._mcu_midi_input = selected_text
335331
configuration.set_option( \
336-
'Python MCU', 'sequencer_midi_input', \
337-
self._sequencer_midi_input)
332+
'Python MCU', 'mcu_midi_input', \
333+
self._mcu_midi_input)
338334
elif widget == self._combo_mcu_midi_output:
339-
self._sequencer_midi_output = selected_text
335+
self._mcu_midi_output = selected_text
340336
configuration.set_option( \
341-
'Python MCU', 'sequencer_midi_output', \
342-
self._sequencer_midi_output)
337+
'Python MCU', 'mcu_midi_output', \
338+
self._mcu_midi_output)
343339
elif widget == self._combo_hardware_controller:
344340
self._hardware_controller = selected_text
345341
configuration.set_option( \
346-
'Python MCU', 'hardware_controller', \
342+
'Python MCU', 'controller_hardware', \
347343
self._hardware_controller)
348344

349345
# get preferred MIDI ports for hardware controller
@@ -368,21 +364,13 @@ def combobox_item_selected(self, selected_text):
368364
configuration.set_option( \
369365
'Python MCU', 'controller_midi_output', \
370366
self._controller_midi_output)
371-
else:
372-
self.callback_log('QComboBox not handled ("%s").' % selected_text)
373-
374-
375-
def checkbox_state_changed(self, state):
376-
widget = self.sender()
377-
378-
if widget == self._checkbox_use_challenge_response:
379-
self._use_challenge_response = widget.isChecked()
380-
367+
elif widget == self._combo_mcu_connection:
368+
self._mcu_connection = selected_text
381369
configuration.set_option( \
382-
'Python MCU', 'use_challenge_response', \
383-
self._use_challenge_response)
370+
'Python MCU', 'mcu_connection', \
371+
self._mcu_connection)
384372
else:
385-
self.callback_log('QCheckBox not handled ("%d").' % state)
373+
self.callback_log('QComboBox not handled ("%s").' % selected_text)
386374

387375

388376
def process_midi_input(self):
@@ -400,24 +388,18 @@ def interconnector_start_stop(self):
400388

401389
self.callback_log('Settings')
402390
self.callback_log('========')
403-
self.callback_log('Emulated MCU model: %s' % \
404-
self._emulated_mcu_model)
405-
self.callback_log('Use challenge-response: %s' % \
406-
self._use_challenge_response)
407-
self.callback_log('Sequencer MIDI input: %s' % \
408-
self._sequencer_midi_input)
409-
self.callback_log('Sequencer MIDI output: %s' % \
410-
self._sequencer_midi_output)
391+
self.callback_log('MCU emulation: %s' % self._mcu_emulated_model)
392+
self.callback_log('Connection: %s' % self._mcu_connection)
393+
self.callback_log('MIDI input: %s' % self._mcu_midi_input)
394+
self.callback_log('MIDI output: %s' % self._mcu_midi_output)
411395
self.callback_log('')
412-
self.callback_log('Hardware controller: %s' % \
413-
self._hardware_controller)
414-
self.callback_log('Controller MIDI input: %s' % \
396+
self.callback_log('Controller: %s' % self._hardware_controller)
397+
self.callback_log('MIDI input: %s' % \
415398
self._controller_midi_input)
416-
self.callback_log('Controller MIDI output: %s' % \
399+
self.callback_log('MIDI output: %s' % \
417400
self._controller_midi_output)
418401
self.callback_log('')
419-
self.callback_log('MIDI latency: %s ms' % \
420-
self._midi_latency)
402+
self.callback_log('MIDI latency: %s ms' % self._midi_latency)
421403
self.callback_log('')
422404
self.callback_log('')
423405

@@ -433,9 +415,9 @@ def interconnector_start_stop(self):
433415
# handling the complete MIDI translation between those two
434416
self._interconnector = McuInterconnector( \
435417
self._mcu_model_id, \
436-
self._use_challenge_response, \
437-
self._sequencer_midi_input, \
438-
self._sequencer_midi_output, \
418+
self._mcu_connection, \
419+
self._mcu_midi_input, \
420+
self._mcu_midi_output, \
439421
self._hardware_controller_class, \
440422
self._controller_midi_input, \
441423
self._controller_midi_output, \

0 commit comments

Comments
 (0)