def __init__(self, button_index, mono_chrome = False, *a, **k): super(ControlMode, self).__init__(button_index, *a, **a) self._device_bank_registry = DeviceBankRegistry() self._device_bank_registry.add_device_bank_listener(self._on_device_bank_changed) self.track_selections = tuple(lambda .0: for idx in .0: ControlTrackElement(idx)(range(8))) self._is_monochrome = mono_chrome self.main_buttons = ([ None, self._do_select_level], [ None, self._do_select_pan], [ None, self._do_select_send], [ None, self._do_select_device]) self.nav_buttons = ([ None, self._do_nav1], [ None, self._do_nav2], [ None, self._do_nav3], [ None, self._do_nav4]) self.song().add_return_tracks_listener(self.return_tracks_changed)
def _init_device(self): make_button = partial(make_launch_control_button, channel=10) make_encoder = partial(make_launch_control_encoder, channel=10) bottom_encoders, top_encoders = make_all_encoders( 'Device', make_encoder) parameter_controls = top_encoders[:4] + bottom_encoders[:4] bank_buttons = [ make_button(identifier, 'Device_Bank_Button_' + str(i), is_pad=True) for i, identifier in enumerate(pad_identifiers) ] for button in bank_buttons: button.set_on_off_values(Colors.LED_ON, Colors.LED_OFF) self._device_bank_registry = DeviceBankRegistry() self._device = DeviceComponent( device_bank_registry=self._device_bank_registry, name='Device') self._device.set_enabled(False) self._device.layer = Layer( parameter_controls=ButtonMatrixElement(rows=[parameter_controls]), bank_buttons=ButtonMatrixElement(rows=[bank_buttons])) self.set_device_component(self._device) self._device_navigation = DeviceNavigationComponent() self._device_navigation.set_enabled(False) self._device_navigation.name = 'Device_Navigation' self._device_navigation.layer = Layer( next_device_button=make_button(115, 'Next_Device_Button'), previous_device_button=make_button(114, 'Prev_Device_Button')) self._view_control = ViewControlComponent() self._view_control.set_enabled(False) self._view_control.name = 'View_Control' self._view_control.layer = Layer( next_track_button=make_button(117, 'Device_Next_Track_Button'), prev_track_button=make_button(116, 'Device_Prev_Track_Button'))
def __init__(self, button_index, mono_chrome = False, *a, **k): super(ControlMode, self).__init__(button_index, *a, **k) self._device_bank_registry = DeviceBankRegistry() self._device_bank_registry.add_device_bank_listener(self._on_device_bank_changed) self.track_selections = tuple((ControlTrackElement(idx) for idx in range(8))) self._is_monochrome = mono_chrome self.main_buttons = ([None, self._do_select_level], [None, self._do_select_pan], [None, self._do_select_send], [None, self._do_select_device]) self.nav_buttons = ([None, self._do_nav1], [None, self._do_nav2], [None, self._do_nav3], [None, self._do_nav4]) self.song().add_return_tracks_listener(self.return_tracks_changed)
def __init__(self, mode_selector, *a, **k): super(MonoNavSection, self).__init__(*a, **k) is_momentary = True self._modesel = mode_selector self._device_bank_registry = DeviceBankRegistry() self.volume_knob = SliderElement(MIDI_CC_TYPE, 0, 40) self.tempo_knob = SliderElement(MIDI_CC_TYPE, 0, 41) self.swing_knob = SliderElement(MIDI_CC_TYPE, 0, 42) self.mode_button = ButtonElement(True, MIDI_CC_TYPE, 2, 86) self.alt_button = ButtonElement(True, MIDI_CC_TYPE, 2, 81) self._do_left_knob.subject = self.volume_knob self._do_center_knob.subject = self.tempo_knob self._do_right_knob.subject = self.swing_knob self._do_mode_button.subject = self.mode_button self._do_alt_button.subject = self.alt_button self._mode = MODE_ADJUST self._alt_down = False
class ControlMode(MaschineMode): _mode = CM_LEVEL _track_sel_index = 0 _track_off = 0 _knob_section = None _parm_raster_value = 1 _parm = None _parm_is_quant = False _selected_sends_index = 0 _bank_index = 0 _parm_index = 0 _device_parm = None _banks = None _device = None _device_list = None _in_clear_mode = False def __init__(self, button_index, mono_chrome=False, *a, **k): super(ControlMode, self).__init__(button_index, *a, **k) self._device_bank_registry = DeviceBankRegistry() self._device_bank_registry.add_device_bank_listener( self._on_device_bank_changed) self.track_selections = tuple( (ControlTrackElement(idx) for idx in range(8))) self._is_monochrome = mono_chrome self.main_buttons = ([None, self._do_select_level], [ None, self._do_select_pan ], [None, self._do_select_send], [None, self._do_select_device]) self.nav_buttons = ([None, self._do_nav1], [None, self._do_nav2], [None, self._do_nav3], [None, self._do_nav4]) self.song().add_return_tracks_listener(self.return_tracks_changed) return def connect_main_knob(self, knobsection): self._knob_section = knobsection def knob_adjust(self, inc, shift, pushdown): if self._parm: if pushdown: value = self.change_parm(inc, self._parm, False) self._parm.value = value else: count = 0 while count < 4: value = self.change_parm(inc, self._parm, False) self._parm.value = value count += 1 else: if self._device_parm: if self._parm_is_quant: val = self.change_parm(inc, self._device_parm, True) self._device_parm.value = val else: new_value = self.change_parm(inc, self._device_parm, False) self._device_parm.value = new_value if not is_equal(self._device_parm.value, new_value): self.parm_is_quant = True if not self.parm_is_quant and not pushdown: count = 0 while count < 3: value = self.change_parm(inc, self._device_parm, False) self._device_parm.value = value count += 1 def change_parm(self, delta, parm, is_quant): if is_quant: parm_range = parm.max - parm.min + 1 new_val = min(parm.max, max(parm.min, parm.value + delta)) return float(new_val) parm_range = parm.max - parm.min self._parm_raster_value = min(N_PARM_RANGE, max(0, self._parm_raster_value + delta)) return float(self._parm_raster_value) / float( N_PARM_RANGE) * parm_range + parm.min def get_mode_id(self): return CONTROL_MODE def navigate(self, dir, modifier, alt_modifier=False): tracks = self.song().tracks nr_of_tracks = len(tracks) new_off = self._track_off + dir if new_off >= 0 and new_off + 8 <= nr_of_tracks: self._track_off = new_off self._track_sel_index += dir self.canonical_parent.show_message('Control assigned to Tracks ' + str(self._track_off + 1) + ' to ' + str(self._track_off + 9)) self._assign(False) def unbind(self): pass def nr_of_parms_in_bank(self, device, bank_index): if device == None: return 0 nr_of_parms = len(device.parameters) bip = nr_of_parms - 8 * bank_index if bip < 8: return bip return 8 def _assign(self, register=True): tracks = self.song().tracks bmatrix = self.canonical_parent._bmatrix for button, (column, row) in bmatrix.iterbuttons(): if button: if register: self.canonical_parent._forwarding_registry[( MIDI_NOTE_ON_STATUS, button.get_identifier())] = button self.canonical_parent._forwarding_registry[( MIDI_NOTE_OFF_STATUS, button.get_identifier())] = button button.set_to_notemode(False) if row < 2: index = row * 4 + column tindex = index + self._track_off track = None if tindex < len(tracks): track = tracks[tindex] self.track_selections[index].set_button( button, self._do_track_selection) self.track_selections[index].set_track(track) elif row < 3: if not self.main_buttons[column][0]: self.main_buttons[column][0] = button button.add_value_listener(self.main_buttons[column][1]) else: if not self.nav_buttons[column][0]: self.nav_buttons[column][0] = button button.add_value_listener(self.nav_buttons[column][1]) if self._mode == CM_LEVEL or self._mode == CM_PAN: button.send_color_direct(PColor.OFF[1]) self._mode_sel() return def _set_send_color(self, nr_ret_tracks, index, button): if index == 3: button.send_color_direct(PColor.OFF[0]) if nr_ret_tracks > index: col = max(21, (21 + (self._selected_sends_index - 3) * 20) % 127) if self._selected_sends_index >= 3: col = max( 21, (21 + (self._selected_sends_index - 3) * 20) % 127) button.send_color_direct((col, 120, 127, 1, 0)) else: button.send_color_direct((21, 120, 20, 0, 0)) else: if nr_ret_tracks > index: if index == self._selected_sends_index: button.send_color_direct(PColor.MIX_SELECT_SEND[0]) else: button.send_color_direct(PColor.MIX_SELECT_SEND[1]) else: button.send_color_direct(PColor.OFF[0]) def _turn_off_nav_buttons(self): for button, callback in self.nav_buttons: if button: button.send_color_direct(PColor.OFF[0]) def _set_up_control_send(self): nr_of_tracks = len(self.song().return_tracks) for idx in range(4): self._set_send_color(nr_of_tracks, idx, self.nav_buttons[idx][0]) def _assign_device_nav(self): if self._device: idx = list(self._device_list).index(self._device) nr_of_dev = len(self._device_list) if idx > 0: self.nav_buttons[0][0].send_color_direct(PColor.DEVICE_LEFT[0]) else: self.nav_buttons[0][0].send_color_direct(PColor.DEVICE_LEFT[1]) if idx < nr_of_dev - 1: self.nav_buttons[1][0].send_color_direct( PColor.DEVICE_RIGHT[0]) else: self.nav_buttons[1][0].send_color_direct( PColor.DEVICE_RIGHT[1]) nr_of_banks = len(self._banks) if self._bank_index > 0: self.nav_buttons[2][0].send_color_direct(PColor.BANK_LEFT[0]) else: self.nav_buttons[2][0].send_color_direct(PColor.BANK_LEFT[1]) if self._bank_index < nr_of_banks - 1: self.nav_buttons[3][0].send_color_direct(PColor.BANK_RIGHT[0]) else: self.nav_buttons[3][0].send_color_direct(PColor.BANK_RIGHT[1]) else: self.nav_buttons[0][0].send_color_direct(PColor.DEVICE_LEFT[1]) self.nav_buttons[1][0].send_color_direct(PColor.DEVICE_RIGHT[1]) self.nav_buttons[2][0].send_color_direct(PColor.BANK_LEFT[1]) self.nav_buttons[3][0].send_color_direct(PColor.BANK_RIGHT[1]) def _assign_device_selection(self): if not self._device: self._update_device() device = self._device self._parm = None self._device_parm = None if device: is_on = device.parameters[0].value == 1 if len(self._banks) > 0: bank = self._banks[self._bank_index] for parameter, track_sel in zip(bank, self.track_selections): track_sel.set_parm(parameter) if parameter: track_sel.set_color(is_on and PColor.MIX_MODE_DEVICE or PColor.MIX_MODE_DEVICE_OFF) if self._parm_index == track_sel._index: track_sel.turn_on() self._assign_device_parm(parameter) else: track_sel.turn_off() else: track_sel.set_color(PColor.OFF) track_sel.turn_off() else: for track_sel in self.track_selections: track_sel.set_parm(None) track_sel.set_color(PColor.OFF) track_sel.turn_off() else: for track_sel in self.track_selections: track_sel.set_color(PColor.OFF) track_sel.turn_off() self._assign_device_nav() return def _mode_sel(self): self.main_buttons[0][0].send_color_direct( self._mode == CM_LEVEL and PColor.MIX_MODE_VOLUME[0] or PColor.MIX_MODE_VOLUME[1]) self.main_buttons[1][0].send_color_direct( self._mode == CM_PAN and PColor.MIX_MODE_PANNING[0] or PColor.MIX_MODE_PANNING[1]) self.main_buttons[2][0].send_color_direct( self._mode == CM_SEND and PColor.MIX_MODE_SEND[0] or PColor.MIX_MODE_SEND[1]) self.main_buttons[3][0].send_color_direct( self._mode == CM_DEVICE and PColor.MIX_MODE_DEVICE[0] or PColor.MIX_MODE_DEVICE[1]) reassign_parms = False if self._mode <= CM_SEND: max_index = 0 for track_sel in self.track_selections: if track_sel._track: max_index = track_sel._index if self._track_sel_index > max_index: self._track_sel_index = max_index reassign_parms = True for track_sel in self.track_selections: if track_sel._track: track_sel.set_color(BASIC_COLORS[self._mode]) else: track_sel.set_color(PColor.OFF) if track_sel._index == self._track_sel_index: track_sel.turn_on() else: track_sel.turn_off() if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if self._selected_sends_index > nr_of_tracks - 1: reassign_parms = True self._selected_sends_index = nr_of_tracks - 1 for idx in range(4): self._set_send_color(nr_of_tracks, idx, self.nav_buttons[idx][0]) else: self._turn_off_nav_buttons() else: self._assign_device_selection() if reassign_parms: self._assign_parameters() def _assign_device_parm(self, param): self.parm_device_message(param) self._device_parm = param if param.is_quantized: self._parm_is_quant = True else: self._parm_is_quant = False parm_range = param.max - param.min self._parm_raster_value = int((param.value - param.min) / parm_range * N_PARM_RANGE + 0.1) def parm_device_message(self, param): self.canonical_parent.show_message(' Control ' + str(param.name)) def _get_mixer_parm(self, track): if self._mode == CM_LEVEL: return track.mixer_device.volume if self._mode == CM_PAN: return track.mixer_device.panning if self._mode == CM_SEND: nr_of_ret_tracks = len(track.mixer_device.sends) if self._selected_sends_index < nr_of_ret_tracks and self._selected_sends_index != -1: return track.mixer_device.sends[self._selected_sends_index] return def _assign_mixer_parm(self, track): self._device_parm = None if self._mode == CM_LEVEL: self._parm = track.mixer_device.volume else: if self._mode == CM_PAN: self._parm = track.mixer_device.panning else: if self._mode == CM_SEND: self._device_parm = None nr_of_ret_tracks = len(track.mixer_device.sends) if self._selected_sends_index < nr_of_ret_tracks and self._selected_sends_index != -1: self._parm = track.mixer_device.sends[ self._selected_sends_index] self.parm_is_quant = False if self._parm: parm_range = self._parm.max - self._parm.min self._parm_raster_value = int((self._parm.value - self._parm.min) / parm_range * N_PARM_RANGE + 0.1) return def _assign_parameters(self): current = self.track_selections[self._track_sel_index] track = current._track if track: self._assign_mixer_parm(track) def _do_track_selection(self, button_index): self._knob_section.set_override(self.knob_adjust) track_sel = self.track_selections[button_index] if self._mode == CM_DEVICE: if track_sel._dev_param: if self._in_clear_mode: cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip: cs.clip.clear_envelope(track_sel._dev_param) else: current = self.track_selections[self._parm_index] current.turn_off() self._parm_index = button_index track_sel.turn_on() self._assign_device_parm(track_sel._dev_param) else: current = self.track_selections[self._track_sel_index] if self._in_clear_mode and track_sel._track: parm = self._get_mixer_parm(track_sel._track) cs = self.song().view.highlighted_clip_slot if parm and cs and cs.has_clip: cs.clip.clear_envelope(parm) else: if button_index != self._track_sel_index and track_sel._track: current.turn_off() track_sel.turn_on() current = track_sel self._track_sel_index = button_index self._assign_mixer_parm(track_sel._track) def _do_select_level(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode != CM_LEVEL: self._mode = CM_LEVEL self._mode_sel() self._assign_parameters() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message( 'Control Mode Focus: Track Levels') def _do_select_pan(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode != CM_PAN: self._mode = CM_PAN self._mode_sel() self._assign_parameters() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message( 'Control Mode Focus: Track Panning') def _do_select_send(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode != CM_SEND: self._mode = CM_SEND self._mode_sel() self._assign_parameters() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message( 'Control Mode Focus: Track Sends') def _do_select_device(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode == CM_DEVICE and self.isShiftDown(): if self._device: parm = self._device.parameters[0] if parm.value == 0: parm.value = 1 else: parm.value = 0 if value > 0 and self._mode != CM_DEVICE: self._mode = CM_DEVICE self._mode_sel() self._assign_device_selection() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message( 'Control Mode Focus: Device') def _do_nav1(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 0: self._selected_sends_index = 0 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message( 'Control Mode Focus: Send A') elif self._mode == CM_DEVICE and self._device: if not self.application().view.is_view_visible( 'Detail') or not self.application( ).view.is_view_visible('Detail/DeviceChain'): self.application().view.show_view('Detail') self.application().view.show_view('Detail/DeviceChain') direction = Live.Application.Application.View.NavDirection.left self.application().view.scroll_view(direction, 'Detail/DeviceChain', False) def _do_nav2(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 1: self._selected_sends_index = 1 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message( 'Control Mode Focus: Send B') elif self._mode == CM_DEVICE and self._device: if not self.application().view.is_view_visible( 'Detail') or not self.application( ).view.is_view_visible('Detail/DeviceChain'): self.application().view.show_view('Detail') self.application().view.show_view('Detail/DeviceChain') direction = Live.Application.Application.View.NavDirection.right self.application().view.scroll_view(direction, 'Detail/DeviceChain', False) def _do_nav3(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 2: self._selected_sends_index = 2 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message( 'Control Mode Focus: Send C') elif self._mode == CM_DEVICE and self._device and len( self._banks) > 0: self._bank_index = max(0, self._bank_index - 1) bank = self._banks[self._bank_index] name = self._parameter_bank_names()[self._bank_index] self._device_bank_registry.set_device_bank( self._device, self._bank_index) self._assign_device_selection() self.canonical_parent.show_message(' Bank : ' + name) def _do_nav4(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 3: if self._selected_sends_index < 3 or self._selected_sends_index + 1 == nr_of_tracks: self._selected_sends_index = 3 else: self._selected_sends_index += 1 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message( 'Control Mode Focus: Send ' + SENDS[self._selected_sends_index]) elif self._mode == CM_DEVICE and self._device and len( self._banks) > 0: max_bank = len(self._banks) - 1 self._bank_index = min(max_bank, self._bank_index + 1) name = self._parameter_bank_names()[self._bank_index] self._device_bank_registry.set_device_bank( self._device, self._bank_index) self._assign_device_selection() self.canonical_parent.show_message(' Bank : ' + name) def _release(self): for track_sel in self.track_selections: track_sel.release() for button, callback in self.main_buttons: if button: button.remove_value_listener(callback) for button, callback in self.nav_buttons: if button: button.remove_value_listener(callback) for idx in range(4): self.main_buttons[idx][0] = None self.nav_buttons[idx][0] = None self._device_parameters_changed.subject = None self._device_active_changed.subject = None return def _on_device_bank_changed(self, device, bank): if device == self._device: self._bank_index = bank self._assign_device_selection() def _update_device(self): self._device = self.song().appointed_device if self._device: self._parm_index = 0 track = self._device.canonical_parent devices = track.devices self._device_list = track.devices self._device_parameters_changed.subject = self._device self._device_active_changed.subject = self._device.parameters[0] self._banks = parameter_banks(self._device) self._bank_index = self._device_bank_registry.get_device_bank( self._device) else: self._device_parameters_changed.subject = None self._device_active_changed.subject = None return def _device_changed(self): if self._active: self._bank_index = 0 if self._mode == CM_DEVICE: self._update_device() self._assign_device_selection() def return_tracks_changed(self): if self._active: self._assign(False) @subject_slot('parameters') def _device_parameters_changed(self): if self._active and self._mode == CM_DEVICE: self._banks = parameter_banks(self._device) self._bank_index = self._device_bank_registry.get_device_bank( self._device) self._assign_device_selection() @subject_slot('value') def _device_active_changed(self): if self._active and self._mode == CM_DEVICE: self._assign_device_selection() def on_track_list_changed(self): if self._active: for track_sel in self.track_selections: track_sel.release() self._assign(False) def _parameter_bank_names(self): return parameter_bank_names(self._device) def enter(self): self._active = True self._assign() if self._knob_section: self._knob_section.set_override(self.knob_adjust) self._assign_parameters() def exit(self): self._active = False self._release() if self._knob_section: self._knob_section.reset_overide() def enter_clear_state(self): self._in_clear_mode = True def exit_clear_state(self): self._in_clear_mode = False def disconnect(self): if self._active: self._release() self.song().remove_return_tracks_listener(self.return_tracks_changed) self._device_bank_registry.remove_device_bank_listener( self._on_device_bank_changed) self._device_parameters_changed.subject = None super(MaschineMode, self).disconnect() return
class ControlMode(MaschineMode): _mode = CM_LEVEL _track_sel_index = 0 _track_off = 0 _knob_section = None _parm_raster_value = 1 _parm = None _parm_is_quant = False _selected_sends_index = 0 _bank_index = 0 _parm_index = 0 _device_parm = None _banks = None _device = None _device_list = None _in_clear_mode = False def __init__(self, button_index, mono_chrome = False, *a, **k): super(ControlMode, self).__init__(button_index, *a, **k) self._device_bank_registry = DeviceBankRegistry() self._device_bank_registry.add_device_bank_listener(self._on_device_bank_changed) self.track_selections = tuple((ControlTrackElement(idx) for idx in range(8))) self._is_monochrome = mono_chrome self.main_buttons = ([None, self._do_select_level], [None, self._do_select_pan], [None, self._do_select_send], [None, self._do_select_device]) self.nav_buttons = ([None, self._do_nav1], [None, self._do_nav2], [None, self._do_nav3], [None, self._do_nav4]) self.song().add_return_tracks_listener(self.return_tracks_changed) def connect_main_knob(self, knobsection): self._knob_section = knobsection def knob_adjust(self, inc, shift, pushdown): if self._parm: if pushdown: value = self.change_parm(inc, self._parm, False) self._parm.value = value else: count = 0 while count < 4: value = self.change_parm(inc, self._parm, False) self._parm.value = value count += 1 elif self._device_parm: if self._parm_is_quant: val = self.change_parm(inc, self._device_parm, True) self._device_parm.value = val else: new_value = self.change_parm(inc, self._device_parm, False) self._device_parm.value = new_value if not is_equal(self._device_parm.value, new_value): self.parm_is_quant = True if not self.parm_is_quant and not pushdown: count = 0 while count < 3: value = self.change_parm(inc, self._device_parm, False) self._device_parm.value = value count += 1 def change_parm(self, delta, parm, is_quant): if is_quant: parm_range = parm.max - parm.min + 1 new_val = min(parm.max, max(parm.min, parm.value + delta)) return float(new_val) else: parm_range = parm.max - parm.min self._parm_raster_value = min(N_PARM_RANGE, max(0, self._parm_raster_value + delta)) return float(self._parm_raster_value) / float(N_PARM_RANGE) * parm_range + parm.min def get_mode_id(self): return CONTROL_MODE def navigate(self, dir, modifier, alt_modifier = False): tracks = self.song().tracks nr_of_tracks = len(tracks) new_off = self._track_off + dir if new_off >= 0 and new_off + 8 <= nr_of_tracks: self._track_off = new_off self._track_sel_index += dir self.canonical_parent.show_message('Control assigned to Tracks ' + str(self._track_off + 1) + ' to ' + str(self._track_off + 9)) self._assign(False) def unbind(self): pass def nr_of_parms_in_bank(self, device, bank_index): if device == None: return 0 nr_of_parms = len(device.parameters) bip = nr_of_parms - 8 * bank_index if bip < 8: return bip return 8 def _assign(self, register = True): tracks = self.song().tracks bmatrix = self.canonical_parent._bmatrix for button, (column, row) in bmatrix.iterbuttons(): if button: if register: self.canonical_parent._forwarding_registry[MIDI_NOTE_ON_STATUS, button.get_identifier()] = button self.canonical_parent._forwarding_registry[MIDI_NOTE_OFF_STATUS, button.get_identifier()] = button button.set_to_notemode(False) if row < 2: index = row * 4 + column tindex = index + self._track_off track = None if tindex < len(tracks): track = tracks[tindex] self.track_selections[index].set_button(button, self._do_track_selection) self.track_selections[index].set_track(track) elif row < 3: if not self.main_buttons[column][0]: self.main_buttons[column][0] = button button.add_value_listener(self.main_buttons[column][1]) else: if not self.nav_buttons[column][0]: self.nav_buttons[column][0] = button button.add_value_listener(self.nav_buttons[column][1]) if self._mode == CM_LEVEL or self._mode == CM_PAN: button.send_color_direct(PColor.OFF[1]) self._mode_sel() def _set_send_color(self, nr_ret_tracks, index, button): if index == 3: button.send_color_direct(PColor.OFF[0]) if nr_ret_tracks > index: col = max(21, (21 + (self._selected_sends_index - 3) * 20) % 127) if self._selected_sends_index >= 3: col = max(21, (21 + (self._selected_sends_index - 3) * 20) % 127) button.send_color_direct((col, 120, 127, 1, 0)) else: button.send_color_direct((21, 120, 20, 0, 0)) elif nr_ret_tracks > index: if index == self._selected_sends_index: button.send_color_direct(PColor.MIX_SELECT_SEND[0]) else: button.send_color_direct(PColor.MIX_SELECT_SEND[1]) else: button.send_color_direct(PColor.OFF[0]) def _turn_off_nav_buttons(self): for button, callback in self.nav_buttons: if button: button.send_color_direct(PColor.OFF[0]) def _set_up_control_send(self): nr_of_tracks = len(self.song().return_tracks) for idx in range(4): self._set_send_color(nr_of_tracks, idx, self.nav_buttons[idx][0]) def _assign_device_nav(self): if self._device: idx = list(self._device_list).index(self._device) nr_of_dev = len(self._device_list) if idx > 0: self.nav_buttons[0][0].send_color_direct(PColor.DEVICE_LEFT[0]) else: self.nav_buttons[0][0].send_color_direct(PColor.DEVICE_LEFT[1]) if idx < nr_of_dev - 1: self.nav_buttons[1][0].send_color_direct(PColor.DEVICE_RIGHT[0]) else: self.nav_buttons[1][0].send_color_direct(PColor.DEVICE_RIGHT[1]) nr_of_banks = len(self._banks) if self._bank_index > 0: self.nav_buttons[2][0].send_color_direct(PColor.BANK_LEFT[0]) else: self.nav_buttons[2][0].send_color_direct(PColor.BANK_LEFT[1]) if self._bank_index < nr_of_banks - 1: self.nav_buttons[3][0].send_color_direct(PColor.BANK_RIGHT[0]) else: self.nav_buttons[3][0].send_color_direct(PColor.BANK_RIGHT[1]) else: self.nav_buttons[0][0].send_color_direct(PColor.DEVICE_LEFT[1]) self.nav_buttons[1][0].send_color_direct(PColor.DEVICE_RIGHT[1]) self.nav_buttons[2][0].send_color_direct(PColor.BANK_LEFT[1]) self.nav_buttons[3][0].send_color_direct(PColor.BANK_RIGHT[1]) def _assign_device_selection(self): if not self._device: self._update_device() device = self._device self._parm = None self._device_parm = None if device: is_on = device.parameters[0].value == 1 if len(self._banks) > 0: bank = self._banks[self._bank_index] for parameter, track_sel in zip(bank, self.track_selections): track_sel.set_parm(parameter) if parameter: track_sel.set_color(is_on and PColor.MIX_MODE_DEVICE or PColor.MIX_MODE_DEVICE_OFF) if self._parm_index == track_sel._index: track_sel.turn_on() self._assign_device_parm(parameter) else: track_sel.turn_off() else: track_sel.set_color(PColor.OFF) track_sel.turn_off() else: for track_sel in self.track_selections: track_sel.set_parm(None) track_sel.set_color(PColor.OFF) track_sel.turn_off() else: for track_sel in self.track_selections: track_sel.set_color(PColor.OFF) track_sel.turn_off() self._assign_device_nav() def _mode_sel(self): self.main_buttons[0][0].send_color_direct(self._mode == CM_LEVEL and PColor.MIX_MODE_VOLUME[0] or PColor.MIX_MODE_VOLUME[1]) self.main_buttons[1][0].send_color_direct(self._mode == CM_PAN and PColor.MIX_MODE_PANNING[0] or PColor.MIX_MODE_PANNING[1]) self.main_buttons[2][0].send_color_direct(self._mode == CM_SEND and PColor.MIX_MODE_SEND[0] or PColor.MIX_MODE_SEND[1]) self.main_buttons[3][0].send_color_direct(self._mode == CM_DEVICE and PColor.MIX_MODE_DEVICE[0] or PColor.MIX_MODE_DEVICE[1]) reassign_parms = False if self._mode <= CM_SEND: max_index = 0 for track_sel in self.track_selections: if track_sel._track: max_index = track_sel._index if self._track_sel_index > max_index: self._track_sel_index = max_index reassign_parms = True for track_sel in self.track_selections: if track_sel._track: track_sel.set_color(BASIC_COLORS[self._mode]) else: track_sel.set_color(PColor.OFF) if track_sel._index == self._track_sel_index: track_sel.turn_on() else: track_sel.turn_off() if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if self._selected_sends_index > nr_of_tracks - 1: reassign_parms = True self._selected_sends_index = nr_of_tracks - 1 for idx in range(4): self._set_send_color(nr_of_tracks, idx, self.nav_buttons[idx][0]) else: self._turn_off_nav_buttons() else: self._assign_device_selection() if reassign_parms: self._assign_parameters() def _assign_device_parm(self, param): self.parm_device_message(param) self._device_parm = param if param.is_quantized: self._parm_is_quant = True else: self._parm_is_quant = False parm_range = param.max - param.min self._parm_raster_value = int((param.value - param.min) / parm_range * N_PARM_RANGE + 0.1) def parm_device_message(self, param): self.canonical_parent.show_message(' Control ' + str(param.name)) def _get_mixer_parm(self, track): if self._mode == CM_LEVEL: return track.mixer_device.volume elif self._mode == CM_PAN: return track.mixer_device.panning elif self._mode == CM_SEND: nr_of_ret_tracks = len(track.mixer_device.sends) if self._selected_sends_index < nr_of_ret_tracks and self._selected_sends_index != -1: return track.mixer_device.sends[self._selected_sends_index] def _assign_mixer_parm(self, track): self._device_parm = None if self._mode == CM_LEVEL: self._parm = track.mixer_device.volume elif self._mode == CM_PAN: self._parm = track.mixer_device.panning elif self._mode == CM_SEND: self._device_parm = None nr_of_ret_tracks = len(track.mixer_device.sends) if self._selected_sends_index < nr_of_ret_tracks and self._selected_sends_index != -1: self._parm = track.mixer_device.sends[self._selected_sends_index] self.parm_is_quant = False if self._parm: parm_range = self._parm.max - self._parm.min self._parm_raster_value = int((self._parm.value - self._parm.min) / parm_range * N_PARM_RANGE + 0.1) def _assign_parameters(self): current = self.track_selections[self._track_sel_index] track = current._track if track: self._assign_mixer_parm(track) def _do_track_selection(self, button_index): self._knob_section.set_override(self.knob_adjust) track_sel = self.track_selections[button_index] if self._mode == CM_DEVICE: if track_sel._dev_param: if self._in_clear_mode: cs = self.song().view.highlighted_clip_slot if cs and cs.has_clip: cs.clip.clear_envelope(track_sel._dev_param) else: current = self.track_selections[self._parm_index] current.turn_off() self._parm_index = button_index track_sel.turn_on() self._assign_device_parm(track_sel._dev_param) else: current = self.track_selections[self._track_sel_index] if self._in_clear_mode and track_sel._track: parm = self._get_mixer_parm(track_sel._track) cs = self.song().view.highlighted_clip_slot if parm and cs and cs.has_clip: cs.clip.clear_envelope(parm) elif button_index != self._track_sel_index and track_sel._track: current.turn_off() track_sel.turn_on() current = track_sel self._track_sel_index = button_index self._assign_mixer_parm(track_sel._track) def _do_select_level(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode != CM_LEVEL: self._mode = CM_LEVEL self._mode_sel() self._assign_parameters() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message('Control Mode Focus: Track Levels') def _do_select_pan(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode != CM_PAN: self._mode = CM_PAN self._mode_sel() self._assign_parameters() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message('Control Mode Focus: Track Panning') def _do_select_send(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode != CM_SEND: self._mode = CM_SEND self._mode_sel() self._assign_parameters() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message('Control Mode Focus: Track Sends') def _do_select_device(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0 and self._mode == CM_DEVICE and self.isShiftDown(): if self._device: parm = self._device.parameters[0] if parm.value == 0: parm.value = 1 else: parm.value = 0 if value > 0 and self._mode != CM_DEVICE: self._mode = CM_DEVICE self._mode_sel() self._assign_device_selection() if self.canonical_parent.is_monochrome(): self.canonical_parent.show_message('Control Mode Focus: Device') def _do_nav1(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 0: self._selected_sends_index = 0 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message('Control Mode Focus: Send A') elif self._mode == CM_DEVICE and self._device: if not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain'): self.application().view.show_view('Detail') self.application().view.show_view('Detail/DeviceChain') direction = Live.Application.Application.View.NavDirection.left self.application().view.scroll_view(direction, 'Detail/DeviceChain', False) def _do_nav2(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 1: self._selected_sends_index = 1 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message('Control Mode Focus: Send B') elif self._mode == CM_DEVICE and self._device: if not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain'): self.application().view.show_view('Detail') self.application().view.show_view('Detail/DeviceChain') direction = Live.Application.Application.View.NavDirection.right self.application().view.scroll_view(direction, 'Detail/DeviceChain', False) def _do_nav3(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 2: self._selected_sends_index = 2 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message('Control Mode Focus: Send C') elif self._mode == CM_DEVICE and self._device and len(self._banks) > 0: self._bank_index = max(0, self._bank_index - 1) bank = self._banks[self._bank_index] name = self._parameter_bank_names()[self._bank_index] self._device_bank_registry.set_device_bank(self._device, self._bank_index) self._assign_device_selection() self.canonical_parent.show_message(' Bank : ' + name) def _do_nav4(self, value): self._knob_section.set_override(self.knob_adjust) if value > 0: if self._mode == CM_SEND: nr_of_tracks = len(self.song().return_tracks) if nr_of_tracks > 3: if self._selected_sends_index < 3 or self._selected_sends_index + 1 == nr_of_tracks: self._selected_sends_index = 3 else: self._selected_sends_index += 1 self._set_up_control_send() self._assign_parameters() self.canonical_parent.show_message('Control Mode Focus: Send ' + SENDS[self._selected_sends_index]) elif self._mode == CM_DEVICE and self._device and len(self._banks) > 0: max_bank = len(self._banks) - 1 self._bank_index = min(max_bank, self._bank_index + 1) name = self._parameter_bank_names()[self._bank_index] self._device_bank_registry.set_device_bank(self._device, self._bank_index) self._assign_device_selection() self.canonical_parent.show_message(' Bank : ' + name) def _release(self): for track_sel in self.track_selections: track_sel.release() for button, callback in self.main_buttons: if button: button.remove_value_listener(callback) for button, callback in self.nav_buttons: if button: button.remove_value_listener(callback) for idx in range(4): self.main_buttons[idx][0] = None self.nav_buttons[idx][0] = None self._device_parameters_changed.subject = None self._device_active_changed.subject = None def _on_device_bank_changed(self, device, bank): if device == self._device: self._bank_index = bank self._assign_device_selection() def _update_device(self): self._device = self.song().appointed_device if self._device: self._parm_index = 0 track = self._device.canonical_parent devices = track.devices self._device_list = track.devices self._device_parameters_changed.subject = self._device self._device_active_changed.subject = self._device.parameters[0] self._banks = parameter_banks(self._device) self._bank_index = self._device_bank_registry.get_device_bank(self._device) else: self._device_parameters_changed.subject = None self._device_active_changed.subject = None def _device_changed(self): if self._active: self._bank_index = 0 if self._mode == CM_DEVICE: self._update_device() self._assign_device_selection() def return_tracks_changed(self): if self._active: self._assign(False) @subject_slot('parameters') def _device_parameters_changed(self): if self._active and self._mode == CM_DEVICE: self._banks = parameter_banks(self._device) self._bank_index = self._device_bank_registry.get_device_bank(self._device) self._assign_device_selection() @subject_slot('value') def _device_active_changed(self): if self._active and self._mode == CM_DEVICE: self._assign_device_selection() def on_track_list_changed(self): if self._active: for track_sel in self.track_selections: track_sel.release() self._assign(False) def _parameter_bank_names(self): return parameter_bank_names(self._device) def enter(self): self._active = True self._assign() if self._knob_section: self._knob_section.set_override(self.knob_adjust) self._assign_parameters() def exit(self): self._active = False self._release() if self._knob_section: self._knob_section.reset_overide() def enter_clear_state(self): self._in_clear_mode = True def exit_clear_state(self): self._in_clear_mode = False def disconnect(self): if self._active: self._release() self.song().remove_return_tracks_listener(self.return_tracks_changed) self._device_bank_registry.remove_device_bank_listener(self._on_device_bank_changed) self._device_parameters_changed.subject = None super(MaschineMode, self).disconnect()