class MainSelectorComponent(ModeSelectorComponent): " CLASS THAT REASSIGNS THE BUTTON ON THE LAUNCHPAD TO DIFFERENT FUNCTIONS " " INIT " def __init__(self, matrix, top_buttons, side_buttons, config_button): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._session = SpecialSessionComponent(self, len(self.song().tracks), matrix.height(), side_buttons) self._session.name = "Session_Control" self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._all_buttons = [] for button in (self._side_buttons + self._nav_buttons): self._all_buttons.append(button) self._sub_modes = SpecialMixerSelectorComponent( matrix, side_buttons, self._session) self._sub_modes.name = "Mixer_Modes" self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) # mixer-session hack self._buttons_for_mixer = [] for button in (self._side_buttons[5:]): self._buttons_for_mixer.append(button) for scene_index in range(self._matrix.height()): for track_index in range(self._matrix.width()): if scene_index > SESSION_HEIGHT_FOR_MIXER: self._buttons_for_mixer.append( self._matrix.get_button(track_index, scene_index)) " DISCONNECT " def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None self._buttons_for_mixer = None ModeSelectorComponent.disconnect(self) " GET SESSION COMPONENT " def session_component(self): return self._session " SET THE MODE BUTTONS " def set_modes_buttons(self, buttons): assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == self.number_of_modes()))) identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if (buttons != None): for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) " GET AMOUNT OF MODES " def number_of_modes(self): return 4 " CHANGE CALLBACK " def on_enabled_changed(self): self.update() " SET THE MODE " def set_mode(self, mode): assert (mode in range(self.number_of_modes())) if ((self._mode_index != mode) or (mode == 3) or True): self._mode_index = mode self.update() " UPDATE MODE BUTTONS " def _update_mode_buttons(self): for index in range(4): if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() " SET CHANNEL FOR THE CURRONT MODE " def channel_for_current_mode(self): #trying to keep if self._mode_index == 0: return 0 elif self._mode_index == 1: new_channel = 4 #user 1 elif self._mode_index == 2: new_channel = 5 #user 2 elif self._mode_index == 3: new_channel = 6 + self._sub_modes.mode() #mixer modes return new_channel " UPDATE THE SHIT " def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() #update matrix and side buttons for scene_index in range(self._matrix.height()): #update scene button self._side_buttons[scene_index].set_enabled(True) for track_index in range(self._matrix.width()): #update matrix self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = (self._mode_index == 1) if (self._mode_index == 0): #session self._setup_mixer((not as_active)) self._setup_session(as_active, as_enabled, False) elif (self._mode_index == 1): #user mode 1 self._setup_mixer((not as_active)) self._setup_session((not as_active), (not as_enabled), False) self._setup_user1(True, True, True) elif (self._mode_index == 2): #user mode 2 self._setup_mixer((not as_active)) self._setup_session((not as_active), (not as_enabled), False) self._setup_user2(release_buttons) elif (self._mode_index == 3): #mixer self._setup_session((as_active), as_enabled, True) self._setup_mixer(as_active) else: assert False self._session.set_allow_update(True) self._update_control_channels() " UPDATE THE CHANNELS OF THE BUTTONS IN THE USER MODES.. " def _update_control_channels(self): new_channel = self.channel_for_current_mode() if self._mode_index == 3: # skip the upper part of the matrix and buttons for button in self._buttons_for_mixer: button.set_channel(new_channel) button.set_force_next_value() else: for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() " SETUP THE SESSION " def _setup_session(self, as_active, as_enabled, for_mixer): #log("setup_session (active: " + str(as_active) + ", enabled: " + str(as_enabled) + ", forMixer: " + str(for_mixer) + ")") assert isinstance(as_active, type(False)) assert isinstance(as_enabled, type(False)) assert isinstance(for_mixer, type(False)) # --------------------------------------------------------------------- nav button color for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) # --------------------------------------------------------------------- matrix for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) if for_mixer: if scene_index <= SESSION_HEIGHT_FOR_MIXER: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, GREEN_THIRD) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) elif as_active and (not for_mixer): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, GREEN_THIRD) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) # SLOT BUTTONS button_index = 0 for track_index in range(len(self.song().tracks)): if self.song().tracks[track_index].is_foldable: if button_index < GROUPS_CONSIDERED: if for_mixer: if scene_index <= SESSION_HEIGHT_FOR_MIXER: button = self._matrix.get_button( button_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button( button) else: scene.clip_slot(track_index).set_launch_button( None) elif as_active and (not for_mixer): button = self._matrix.get_button( button_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button( button) else: scene.clip_slot(track_index).set_launch_button( None) button_index = button_index + 1 else: scene.clip_slot(track_index).set_launch_button(None) # --------------------------------------------------------------------- nav buttons if as_enabled or for_mixer: self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_scene_bank_buttons(None, None) " SETUP THE MIXER " def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) self._sub_modes.set_enabled(as_active) " SETUP USER 1 " def _setup_user1(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True): for scene_index in range(8): if (release_side_buttons): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: if (release_nav_buttons): button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if release_matrix: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) " SETUP USER 2 " def _setup_user2(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) " INIT THE SESSION " def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) # SCENES for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = ("Scene_" + str(scene_index)) # SLOTS button_index = 0 for track_index in range(len(self.song().tracks)): if button_index < GROUPS_CONSIDERED: if self.song().tracks[track_index].is_foldable: clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = ((str(track_index) + "_Clip_Slot_") + str(scene_index)) self._all_buttons.append( self._matrix.get_button(button_index, scene_index)) button_index = button_index + 1
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button, parent): assert isinstance(matrix, ButtonMatrixElement) assert (matrix.width() == 8) and (matrix.height() == 8) assert isinstance(top_buttons, tuple) assert len(top_buttons) == 8 assert isinstance(side_buttons, tuple) assert len(side_buttons) == 8 assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._parent = parent self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = SessionZoomingComponent(self._session) self._session.name = "Session_Control" self._zooming.name = "Session_Overview" self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = "Mixer_Modes" self._sub_modes.set_update_callback(self._update_control_channels) self._stepseq = StepSequencerComponent(self, self._matrix, self._side_buttons, self._nav_buttons) self._quick_mix = None # QuickMixerComponent(self._nav_buttons,self._side_buttons,self) self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self) self._init_session() self._all_buttons = tuple(self._all_buttons) self._mode_index = 0 self._previous_mode_index = -1 self._sub_mode_index = [0, 0, 0, 0] for index in range(4): self._sub_mode_index[index] = 0 self.set_mode_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] assert mode in range(self.number_of_modes()) # self.log_message(str(mode)) if self._mode_index == mode: if self._mode_index == 1: # user mode 1 and device controller self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index] + 1) % 2 self.update() elif self._mode_index == 2: # user mode 2 and step sequencer self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index] + 1) % 3 self.update() elif self._mode_index == 3: self.update() else: self._sub_mode_index[self._mode_index] = 0 self._previous_mode_index = self._mode_index else: self._mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self._mode_index != mode) or (mode == 3) or True): # self._mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 4 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): for index in range(4): if self._sub_mode_index[index] == 0: self._modes_buttons[index].set_on_off_values(AMBER_FULL, AMBER_THIRD) if self._sub_mode_index[index] == 1: self._modes_buttons[index].set_on_off_values(GREEN_FULL, GREEN_THIRD) if self._sub_mode_index[index] == 2: self._modes_buttons[index].set_on_off_values(RED_FULL, RED_THIRD) if index == self._mode_index: self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def channel_for_current_mode(self): # trying to keep if self._mode_index == 0: return 0 elif self._mode_index == 1: if self._sub_mode_index[self._mode_index] == 0: new_channel = 4 # user 1 else: new_channel = 1 # device ctrl elif self._mode_index == 2: if self._sub_mode_index[self._mode_index] == 0: new_channel = 5 # user 2 else: new_channel = 1 + self._sub_mode_index[self._mode_index] # step seq elif self._mode_index == 3: # mixer modes new_channel = 6 + self._sub_modes.mode() # if (new_channel > 0): # new_channel += 3 return new_channel def update(self): assert self._modes_buttons != None if self.is_enabled(): # for index in range(len(self._modes_buttons)): # self._modes_buttons[index].set_force_next_value() # if index == self._mode_index: # self._modes_buttons[index].turn_on() # else: # self._modes_buttons[index].turn_off() self._update_mode_buttons() # update matrix and side buttons for scene_index in range(8): # update scene button self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): # update matrix self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = self._mode_index == 1 if self._mode_index == 0: # session self._setup_mixer((not as_active)) self._setup_device_controller((not as_active)) self._setup_step_sequencer((not as_active), 0) self._setup_device_controller((not as_active)) self._setup_session(as_active, as_enabled) elif self._mode_index == 1: # user mode + device controller self._setup_mixer((not as_active)) if self._sub_mode_index[self._mode_index] == 0: self._setup_step_sequencer((not as_active), 0) self._setup_device_controller((not as_active)) self._setup_session((not as_active), (as_enabled)) self._setup_user1(True, True, True) else: self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active, 0) self._setup_device_controller(as_active) elif self._mode_index == 2: self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_device_controller((not as_active)) if self._sub_mode_index[self._mode_index] == 0: self._setup_device_controller((not as_active)) self._setup_step_sequencer((not as_active), 0) self._setup_user2(release_buttons) else: self._setup_device_controller((not as_active)) self._setup_step_sequencer(as_active, self._sub_mode_index[self._mode_index]) elif self._mode_index == 3: self._setup_step_sequencer((not as_active), 0) self._setup_device_controller((not as_active)) self._setup_session((not as_active), as_enabled) self._setup_mixer(as_active) else: assert False self._previous_mode_index = self._mode_index self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) # matrix for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) # zoom if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons( self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3] ) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) # nav buttons if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_quick_mix(self, as_active): if self._quick_mix != None: if as_active: for button in range(8): self._side_buttons[button].set_enabled(True) self._quick_mix._is_active = True self._quick_mix.set_enabled(True) else: self._quick_mix._is_active = False self._quick_mix.set_enabled(False) def _setup_step_sequencer(self, as_active, mode): if self._stepseq != None: if self._stepseq._is_active != as_active or self._stepseq._mode != mode: if as_active: self._stepseq._mode = mode self._stepseq._force_update = True self._stepseq._is_active = True self._stepseq.set_enabled(True) self._stepseq._on_notes_changed() self._stepseq.update_buttons() self._config_button.send_value(32) else: self._stepseq._mode = 1 self._stepseq._is_active = False self._stepseq.set_enabled(False) def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: # for button in range(8): # self._side_buttons[button].set_enabled(True) self._device_controller._is_active = True self._device_controller.set_enabled(True) self._device_controller.update() self._config_button.send_value(32) else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active and self._sub_modes.is_enabled(): self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user1(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True): for scene_index in range(8): if release_side_buttons: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: if release_nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if release_matrix: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) def _setup_user2(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = "Scene_" + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) def log_message(self, message): self._parent.log_message(message)
class MainSelectorComponent(ModeSelectorComponent): __module__ = __name__ __doc__ = ' Class that reassigns the button on the launchpad to different functions ' def __init__(self, matrix, top_buttons, side_buttons, config_button, knobs, sliders, script): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._script = script self._session = SpecialSessionComponent(matrix.width(), matrix.height()) for scene in self._session._scenes: for slot in scene._clip_slots: slot._triggered_to_play_value = 4 slot._triggered_to_record_value = 3 slot._started_value = 2 slot._recording_value = 1 slot._stopped_value = 127 self._zooming = SessionZoomingComponent(self._session) self._zooming._stopped_value = 127 self._zooming._playing_value = 2 self._zooming._selected_value = 1 self._matrix = matrix self._knobs = knobs self._sliders = sliders self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._shift_button = top_buttons[5] self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in (self._side_buttons + self._nav_buttons): self._all_buttons.append(button) self._shift_pressed = 0 self._shift_pressed_timer = 0 self._last_normal_mode = 0 self._shift_button = None self.set_shift_button(top_buttons[6]) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:6]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def set_shift_button(self, button): assert ((button == None) or (isinstance(button, FlashingButtonElement))) if self._shift_button != None: self._shift_button.remove_value_listener(self._shift_value) self._shift_button = button if self._shift_button != None: self._shift_button.add_value_listener(self._shift_value) def _shift_value(self, value): self._shift_pressed = int(value != 0) if self._shift_pressed > 0: if (self._shift_pressed_timer + 5) > self._script._timer: if (self._script._host.is_enabled() != True): self.set_mode(4) else: self._script.log_message('here') self.set_mode(self._last_normal_mode) else: self._shift_pressed_timer = self._script._timer % 256 if (self._script._host.is_enabled() != True): if (self._mode_index == 1): if value > 0: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._sub_modes.set_modes_buttons(self._nav_buttons) self._sub_modes.update() else: self._sub_modes.set_modes_buttons(None) self._session.set_track_bank_buttons( self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons( self._nav_buttons[1], self._nav_buttons[0]) self._sub_modes.update() elif (self._mode_index == 0): self._setup_session(True, True) self._session.update() def set_modes_buttons(self, buttons): assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == 2))) identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if (buttons != None): for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def _mode_value(self, value, sender): assert (len(self._modes_buttons) > 0) assert isinstance(value, int) assert isinstance(sender, ButtonElement) assert (self._modes_buttons.count(sender) == 1) if self._script._host.is_enabled() != True: if ((value is not 0) or (not sender.is_momentary())): if self._shift_pressed > 0: if self._modes_buttons.index(sender) == 0: self.set_mode(2) if self._modes_buttons.index(sender) == 1: self.set_mode(3) else: self._last_normal_mode = int( self._modes_buttons.index(sender)) self.set_mode(self._modes_buttons.index(sender)) else: pass def number_of_modes(self): return 5 def on_enabled_changed(self): self.update() def set_mode(self, mode): assert (mode in range(self.number_of_modes())) if ((self._mode_index != mode) or (mode == 1)): self._mode_index = mode self.update() def update(self): assert (self._modes_buttons != None) if self.is_enabled(): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = (self._mode_index == 1) if (self._mode_index < 4): self._script._host.set_enabled(False) self._script._host._set_button_matrix(None) self._script._host._set_alt_button(None) self._script._host._set_shift_button(None) self._script._host._set_nav_buttons(None) if (self._mode_index == 0): #session self._setup_mixer((not as_active)) self._setup_session(as_active, as_enabled) elif (self._mode_index == 1): #mixer self._setup_session((not as_active), as_enabled) self._setup_mixer(as_active) elif (self._mode_index == 2): #user1 self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) elif (self._mode_index == 3): #user2 self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) elif (self._mode_index == 4): #monomodular self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) self._script._host._set_button_matrix(self._matrix) self._script._host._set_shift_button(self._shift_button) self._script._host._set_lock_button(self._modes_buttons[0]) self._script._host._set_alt_button(self._modes_buttons[1]) self._script._host._set_nav_buttons(self._nav_buttons) self._script._host.set_enabled(True) else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() #self._script.request_rebuild_midi_map() def _update_control_channels(self): if self._mode_index < 4: new_channel = (self._mode_index + self._sub_modes.mode()) if (new_channel > 0): new_channel += 3 else: new_channel = 15 for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(127, 0) else: button.set_on_off_values(127, 0) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active and (self._shift_pressed == 1): scene_button = self._matrix.get_button(7, scene_index) scene_button.set_on_off_values(127, 0) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(SHIFT[self._shift_pressed]): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, 0) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) self._config_button.send_value(32) if release_buttons: self._config_button.send_value(2) def _init_session(self): self._session.set_stop_track_clip_value(3) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(1) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(4) clip_slot.set_triggered_to_record_value(3) clip_slot.set_stopped_value(127) clip_slot.set_started_value(2) clip_slot.set_recording_value(1) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(127) self._zooming.set_selected_value(1) self._zooming.set_playing_value(2)
class JAMP_alpha(ControlSurface): __doc__ = " Script for JAMP_alpha in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in JAMP_alpha._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._note_map = [] self._ctrl_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map = None self._ctrl_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in JAMP_alpha._active_instances: JAMP_alpha._active_instances.append(self) JAMP_alpha._combine_active_instances() def _do_uncombine(self): if ((self in JAMP_alpha._active_instances) and JAMP_alpha._active_instances.remove(self)): self._session.unlink() JAMP_alpha._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(4, 4) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT]) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [ self._note_map[SCENELAUNCH[index]] for index in range(4) ] self._track_stop_buttons = [ self._note_map[TRACKSTOP[index]] for index in range(4) ] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons( tuple(self._track_stop_buttons)) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button( self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(4): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(4): button = self._note_map[CLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control( self._ctrl_map[MASTERVOLUME]) for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(8): device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map[DEVICEONOFF]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button( self._note_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button( self._note_map[DETAILVIEW]) detail_view_toggler.set_device_nav_buttons( self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT]) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._note_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = ( col, row, DRUM_PADS[row * 4 + col], PADCHANNEL, ) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note) button.name = 'Note_' + str(note) self._note_map.append(button) self._note_map.append( None) #add None to the end of the list, selectable with [-1] if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for ctrl in range(128): self._ctrl_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) self._ctrl_map.append(None)
class Serato(ControlSurface): def __init__(self, c_instance): publish_in_cs_list = True ControlSurface.__init__(self, c_instance, not publish_in_cs_list) self._device_selection_follows_track_selection = True with self.component_guard(): self._matrix = None self._session = None self._mixer = None self._device = None self._scene_launch_buttons = None self._track_arm_buttons = None self._track_solo_buttons = None self._track_mute_buttons = None self._track_stop_buttons = None self._track_select_buttons = None self._device_on_off_button = None self._shift_button = None self._serato_interface = PySCAClipControl() self._serato_interface.PySCA_InitializeClipControl() self._setup_session_control() self._setup_mixer_control() self._setup_device_control() self._session.set_mixer(self._mixer) self.set_highlighting_session_component(self._session) return def disconnect(self): ControlSurface.disconnect(self) self._serato_interface.PySCA_DeinitializeClipControl() self._serato_interface = None return def connect_script_instances(self, instanciated_scripts): """ Called by the Application as soon as all scripts are initialized. You can connect yourself to other running scripts here, as we do it connect the extension modules (MackieControlXTs). """ for control_surface in self._control_surfaces(): control_surface_session = control_surface.highlighting_session_component() if control_surface_session: self._session.sync_to(control_surface_session) self._on_track_list_changed() break def build_midi_map(self, midi_map_handle): pass def update_display(self): ControlSurface.update_display(self) while self._serato_interface.PySCA_HasIncomingEvent(): new_event = self._serato_interface.PySCA_GetIncomingEvent() if not self._handle_session_event(new_event): if not self._handle_mixer_event(new_event): if not self._handle_device_event(new_event): print 'Unhandled Event: ' + str(new_event) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(NUM_TRACKS, NUM_SCENES) self._session.set_serato_interface(self._serato_interface) self._matrix = ButtonMatrixElement() self._scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_SCENES) ] self._track_stop_buttons = [ ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_TRACKS) ] stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) self._session.set_stop_all_clips_button(stop_all_button) self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons)) for scene_index in range(NUM_SCENES): scene = self._session.scene(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_index(scene_index) scene.set_serato_interface(self._serato_interface) for track_index in range(NUM_TRACKS): button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(button) clip_slot.set_serato_interface(self._serato_interface) self._matrix.add_row(tuple(button_row)) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(NUM_TRACKS) self._mixer.set_serato_interface(self._serato_interface) self._mixer.master_strip().set_serato_interface(self._serato_interface) self._track_arm_buttons = [] self._track_solo_buttons = [] self._track_mute_buttons = [] self._track_select_buttons = [] self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) for track in range(NUM_TRACKS): strip = self._mixer.channel_strip(track) strip.set_serato_interface(self._serato_interface) self._track_arm_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) self._track_solo_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) self._track_mute_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) self._track_select_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) strip.set_arm_button(self._track_arm_buttons[-1]) strip.set_solo_button(self._track_solo_buttons[-1]) strip.set_mute_button(self._track_mute_buttons[-1]) strip.set_select_button(self._track_select_buttons[-1]) strip.set_shift_button(self._shift_button) def _setup_device_control(self): is_momentary = True self._device_on_off_button = ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0) self._device = SpecialDeviceComponent() self._device.set_serato_interface(self._serato_interface) self._device.set_parameter_controls(tuple([ SliderElement(MIDI_CC_TYPE, 0, 0) for index in range(NUM_PARAMS) ])) self._device.set_on_off_button(self._device_on_off_button) self.set_device_component(self._device) def _handle_session_event(self, event): result = False if event.type in CLIP_EVENTS: value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventClipPlayedDown) track_index = event.key1 - 1 scene_index = event.key2 - 1 if track_index in range(NUM_TRACKS) and scene_index in range(NUM_SCENES): self._matrix.get_button(track_index, scene_index).receive_value(value) result = True elif event.type in SCENE_EVENTS: value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventScenePlayedDown) scene_index = event.key1 - 1 if scene_index in range(NUM_SCENES): self._scene_launch_buttons[scene_index].receive_value(value) result = True elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixSizeChanged: new_width = event.key1 new_height = event.key2 self._session.set_size(new_width, new_height) result = True elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixOffsetChanged: x_increment = event.key1 y_increment = event.key2 self._session.move_by(x_increment, y_increment) result = True return result def _handle_mixer_event(self, event): result = True track_index = event.key1 - 1 value = event.key2 if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackMasterGainChange: self._mixer.master_strip().set_track_volume(fixed_value(value)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackStopped: self.song().stop_all_clips() elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackSelect: self.song().view.selected_track = self.song().master_track else: result = track_index in range(NUM_TRACKS) and self._handle_strip_event(event) return result def _handle_strip_event(self, event): result = True track_index = event.key1 - 1 value = event.key2 if value == 0: self._shift_button.receive_value(127) if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSolo: self._track_solo_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackRecord: self._track_arm_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackActive: self._track_mute_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackStopped: self._track_stop_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSelect: self._track_select_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackGainChange: self._mixer.channel_strip(track_index).set_track_volume(fixed_value(value)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendAChange: self._mixer.channel_strip(track_index).set_send(0, fixed_value(value)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendBChange: self._mixer.channel_strip(track_index).set_send(1, fixed_value(value)) else: result = False self._shift_button.receive_value(0) return result def _handle_device_event(self, event): result = True if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceValueChanged: self._device.set_parameter_value(event.key1 - 1, fixed_value(event.key2)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceActivate: self._device_on_off_button.receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceFocusMove: self._move_device_focus(event.key1) else: result = False return result def _move_device_focus(self, increment): 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') else: modifier_pressed = True direction = Live.Application.Application.View.NavDirection.left if increment > 0: direction = Live.Application.Application.View.NavDirection.right self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ #def log(self, message): # self._control_surface.log_message((' ' + message + ' ').center(50, '=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface): #verify matrix dimentions assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) #super constructor #inject ControlSurface and OSD components (M4L) self._osd = osd self._control_surface = control_surface #initialize index variables self._mode_index = 0 #Inherited from parent self._main_mode_index = 0 #LP original modes self._sub_mode_list = [0, 0, 0, 0] for index in range(4): self._sub_mode_list[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS:#session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self._control_surface, self) else:#no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self) #initialize _session variables self._session.set_osd(self._osd) self._session.name = 'Session_Control' #initialize _zooming variables self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning = True) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value("Default.Button.Off") self._matrix = matrix self._side_buttons = side_buttons#launch buttons self._nav_buttons = top_buttons[:4]#arrow buttons self._config_button = config_button#used to reset launchpad self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) #User2 stepSequencer (Drum) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq.set_osd(self._osd) #User2 stepSequencer (Melodic) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq2.set_osd(self._osd) #User1 Instrument controller (Scale) self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._instrument_controller.set_osd(self._osd) #self._instrument_controller = None #User1 Device controller (Fx or Instrument parameters) self._device_controller = DeviceComponent(control_surface = self._control_surface, matrix = self._matrix, side_buttons = self._side_buttons, top_buttons = self._nav_buttons) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer) assert mode in range(self.number_of_modes()) # 8 for this script if self._main_mode_index == mode: if self._main_mode_index == 1: #user mode 1 and device controller and instrument mode self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 2: #user mode 2 and step sequencer self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 3: #Mixer mode self.update() else: #Session mode self._sub_mode_list[self._main_mode_index] = 0 self._mode_index = 0 else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self.__main_mode_index != mode) or (mode == 3) or True): # self._main_mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 1 + 3 + 3 + 1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): self._modes_buttons[0].set_on_off_values("Mode.Session.On","Mode.Session.Off") self._modes_buttons[3].set_on_off_values("Mode.Mixer.On","Mode.Mixer.Off") mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]]) mode2 = self.getSkinName(Settings.USER_MODES[3 + self._sub_mode_list[2]]) self._modes_buttons[1].set_on_off_values("Mode."+mode1+".On","Mode."+mode1+".Off") self._modes_buttons[2].set_on_off_values("Mode."+mode2+".On","Mode."+mode2+".Off") for index in range(4): if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def getSkinName(self, user2Mode): if user2Mode=="instrument": user2Mode = "Note" if user2Mode=="device": user2Mode = "Device" if user2Mode=="user 1": user2Mode = "User" if user2Mode=="user 2": user2Mode = "User2" if user2Mode=="drum stepseq": user2Mode = "StepSequencer" if user2Mode=="melodic stepseq": user2Mode = "StepSequencer2" return user2Mode def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index == 0: new_channel = 0 # session elif self._main_mode_index == 1: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 11 # instrument controller # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 3 # device controller elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 4 # plain user mode 1 elif self._main_mode_index == 2: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 1 # step seq elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 2 # melodic step seq elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 5 # plain user mode 2 elif self._main_mode_index == 3: # mixer modes # mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) #Set LP double buffering mode (investigate this) self._config_button.send_value(1) #Set LP X-Y layout grid mapping mode if self._main_mode_index == 0: # session self._control_surface.show_message("SESSION MODE" ) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() self._mode_index = 0 elif self._main_mode_index == 1 or self._main_mode_index == 2: self._setup_sub_mode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_list[self._main_mode_index] ] ) elif self._main_mode_index == 3: # mixer self._control_surface.show_message("MIXER MODE") self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() self._mode_index = 3 else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) def _setup_sub_mode(self, mode): as_active = True as_enabled = True if mode == "instrument": self._control_surface.show_message("INSTRUMENT MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) self._mode_index = 4 elif mode == "melodic stepseq": self._control_surface.show_message("MELODIC SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) self._update_control_channels() self._mode_index = 7 elif mode == "user 1": self._control_surface.show_message("USER 1 MODE" ) self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() self._mode_index = 1 self._osd.clear() self._osd.mode = "User 1" self._osd.update() elif mode == "drum stepseq": self._control_surface.show_message("DRUM SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) self._update_control_channels() self._mode_index = 6 elif mode == "device": self._control_surface.show_message("DEVICE CONTROLLER MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() self._mode_index = 5 elif mode == "user 2": self._control_surface.show_message("USER 2 MODE" ) self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() self._mode_index = 2 self._osd.clear() self._osd.mode = "User 2" self._osd.update() def _setup_session(self, as_active, as_navigation_enabled): assert isinstance(as_active, type(False))#assert is boolean for button in self._nav_buttons: if as_navigation_enabled: button.set_on_off_values("Mode.Session.On", "Mode.Session.Off") else: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") # matrix self._activate_matrix(True) for scene_index in range(self._session._num_scenes):#iterate over scenes scene = self._session.scene(scene_index) if as_active:#set scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(self._session._num_tracks):#iterate over tracks of a scene -> clip slots if as_active:#set clip slot launch button button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active:#Set up stop clip buttons and stop all clips button if self._session._stop_clip_buttons != None: for button in self._session._stop_clip_buttons: button.set_enabled(as_active) # button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons) self._side_buttons[self._session._num_scenes].set_enabled(as_active) self._side_buttons[self._session._num_scenes].set_on_off_values("Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes]) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) if as_active:# zoom self._zooming.set_zoom_button(self._modes_buttons[0])# Set Session button as zoom button, wrong behavior??? self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_navigation_enabled: # nav buttons (track/scene) self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, as_active): if self._instrument_controller != None: if as_active: self._activate_matrix(False) #Disable matrix buttons (clip slots) self._activate_scene_buttons(True)#Enable side buttons self._activate_navigation_buttons(True)#Enable nav buttons else: for scene_index in range(8):#Restore all matrix buttons and scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.use_default_message() # Reset to original channel scene_button.force_next_send() #Flush for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.use_default_message()# Reset to original channel button.force_next_send()#Flush self._instrument_controller.set_enabled(as_active)#Enable/disable instrument controller def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True): # user1 -> All True but release_nav_buttons / user2 -> All false for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled((not release_side_buttons))#User2 enabled for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled((not release_matrix))#User2 enabled for button in self._nav_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled((not release_nav_buttons)) #User1 & User2 enabled if drum_rack_mode:#User1 enabled self._config_button.send_value(2)#Set LP drum rack layout grid mapping mode self._config_button.send_value(32)#Send enable flashing led config message to LP def _setup_step_sequencer(self, as_active): if(self._stepseq != None): #if(self._stepseq.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if(self._stepseq2 != None): #if(self._stepseq2.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if(self._sub_modes.is_enabled()):# go back to default mode self._sub_modes.set_mode(-1) else: self._sub_modes.release_controls() self._sub_modes.set_enabled(as_active) def _init_session(self): #self._session.set_stop_clip_value("Session.StopClip") #self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop") session_height = self._matrix.height() if self._session._stop_clip_buttons != None: session_height = self._matrix.height()-1 for scene_index in range(session_height): # scene = self._session.scene(scene_index) # scene.set_triggered_value("Session.SceneTriggered") # scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): # clip_slot = scene.clip_slot(track_index) # clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay") # clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord") # clip_slot.set_stopped_value("Session.ClipStopped") # clip_slot.set_started_value("Session.ClipStarted") # clip_slot.set_recording_value("Session.ClipRecording") # clip_slot.set_record_button_value("Session.RecordButton") # clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) #self._zooming.set_stopped_value("Zooming.Stopped") #self._zooming.set_selected_value("Zooming.Selected") #self._zooming.set_playing_value("Zooming.Playing") def _activate_navigation_buttons(self, active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self, active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self, active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._control_surface.log_message(msg) # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.force_next_send()
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button, parent): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._parent = parent self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = SessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._stepseq = StepSequencerComponent(self, self._matrix, self._side_buttons, self._nav_buttons) self._quick_mix = None #QuickMixerComponent(self._nav_buttons,self._side_buttons,self) self._device_controller = DeviceControllerComponent( self._matrix, self._side_buttons, self._nav_buttons, self) self._init_session() self._all_buttons = tuple(self._all_buttons) self._previous_mode_index = -1 self._sub_mode_index = [0, 0, 0, 0] for index in range(4): self._sub_mode_index[index] = 0 self.set_mode_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def set_mode(self, mode): assert mode in range(self.number_of_modes()) if ((self._mode_index != mode) or (mode == 3) or True): self._mode_index = mode self.update() def number_of_modes(self): return 4 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): if self._mode_index == self._previous_mode_index: if self._mode_index == 1: #user mode 1 and device controller self._sub_mode_index[self._mode_index] = ( self._sub_mode_index[self._mode_index] + 1) % 2 elif self._mode_index == 2: #user mode 2 and step sequencer self._sub_mode_index[self._mode_index] = ( self._sub_mode_index[self._mode_index] + 1) % 3 else: self._sub_mode_index[self._mode_index] = 0 for index in range(4): if (self._sub_mode_index[index] == 0): self._modes_buttons[index].set_on_off_values( AMBER_FULL, AMBER_THIRD) if (self._sub_mode_index[index] == 1): self._modes_buttons[index].set_on_off_values( GREEN_FULL, GREEN_THIRD) if (self._sub_mode_index[index] == 2): self._modes_buttons[index].set_on_off_values( RED_FULL, RED_THIRD) if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def channel_for_current_mode(self): #trying to keep if self._mode_index == 0: return 0 elif self._mode_index == 1: if self._sub_mode_index[self._mode_index] == 0: new_channel = 4 #user 1 else: new_channel = 1 #device ctrl elif self._mode_index == 2: if self._sub_mode_index[self._mode_index] == 0: new_channel = 5 #user 2 else: new_channel = 1 + self._sub_mode_index[ self._mode_index] #step seq elif self._mode_index == 3: #mixer modes new_channel = 6 + self._sub_modes.mode() #if (new_channel > 0): # new_channel += 3 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): #for index in range(len(self._modes_buttons)): # self._modes_buttons[index].set_force_next_value() # if index == self._mode_index: # self._modes_buttons[index].turn_on() # else: # self._modes_buttons[index].turn_off() self._update_mode_buttons() #update matrix and side buttons for scene_index in range(8): #update scene button self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): #update matrix self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = (self._mode_index == 1) if (self._mode_index == 0): #session self._setup_mixer((not as_active)) self._setup_device_controller((not as_active)) self._setup_step_sequencer((not as_active), 0) self._setup_device_controller((not as_active)) self._setup_session(as_active, as_enabled) elif (self._mode_index == 1): #user mode + device controller self._setup_mixer((not as_active)) if (self._sub_mode_index[self._mode_index] == 0): self._setup_step_sequencer((not as_active), 0) self._setup_device_controller((not as_active)) self._setup_session((not as_active), (as_enabled)) self._setup_user1(True, True, True) else: self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active, 0) self._setup_device_controller(as_active) elif (self._mode_index == 2): self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_device_controller((not as_active)) if (self._sub_mode_index[self._mode_index] == 0): self._setup_device_controller((not as_active)) self._setup_step_sequencer((not as_active), 0) self._setup_user2(release_buttons) else: self._setup_device_controller((not as_active)) self._setup_step_sequencer( as_active, self._sub_mode_index[self._mode_index]) elif (self._mode_index == 3): self._setup_step_sequencer((not as_active), 0) self._setup_device_controller((not as_active)) self._setup_session((not as_active), as_enabled) self._setup_mixer(as_active) else: assert False self._previous_mode_index = self._mode_index self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() #Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) #matrix for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) #zoom if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) #nav buttons if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_quick_mix(self, as_active): if self._quick_mix != None: if as_active: for button in range(8): self._side_buttons[button].set_enabled(True) self._quick_mix._is_active = True self._quick_mix.set_enabled(True) else: self._quick_mix._is_active = False self._quick_mix.set_enabled(False) def _setup_step_sequencer(self, as_active, mode): if (self._stepseq != None): if (self._stepseq._is_active != as_active or self._stepseq._mode != mode): if as_active: self._stepseq._mode = mode self._stepseq._force_update = True self._stepseq._is_active = True self._stepseq.set_enabled(True) self._stepseq._on_notes_changed() self._config_button.send_value(32) else: self._stepseq._mode = 1 self._stepseq._is_active = False self._stepseq.set_enabled(False) def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: #for button in range(8): # self._side_buttons[button].set_enabled(True) self._device_controller._is_active = True self._device_controller.set_enabled(True) self._device_controller.update() self._config_button.send_value(32) else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if (as_active and self._sub_modes.is_enabled()): self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user1(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True): for scene_index in range(8): if (release_side_buttons): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: if (release_nav_buttons): button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if release_matrix: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) def _setup_user2(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) def log_message(self, message): self._parent.log_message(message)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def log(self, message): self._parent.log_message((' ' + message + ' ').center(50, '=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, parent): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._osd = osd self._parent = parent self._mode_index = 0 self._previous_mode_index = -1 self._main_mode_index = 0 self._sub_mode_index = [0, 0, 0, 0] for index in range(4): self._sub_mode_index[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS: #session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append( matrix.get_button(column, matrix.height() - 1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height() - 1, clip_stop_buttons, self) else: #no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self) self._session.set_osd(self._osd) self._session.name = 'Session_Control' self._zooming = DeprecatedSessionZoomingComponent(self._session) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value(LED_OFF) self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self) self._stepseq.set_osd(self._osd) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self) self._stepseq2.set_osd(self._osd) self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons, self) self._instrument_controller.set_osd(self._osd) self._device_controller = DeviceControllerComponent( self._matrix, self._side_buttons, self._nav_buttons, self) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] assert mode in range(self.number_of_modes()) if self._main_mode_index == mode: if self._main_mode_index == 1: # user mode 1 and device controller and instrument mode self._sub_mode_index[self._main_mode_index] = ( self._sub_mode_index[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 2: # user mode 2 and step sequencer self._sub_mode_index[self._main_mode_index] = ( self._sub_mode_index[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 3: self.update() else: self._sub_mode_index[self._main_mode_index] = 0 self._mode_index = 0 self._previous_mode_index = self._main_mode_index else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self.__main_mode_index != mode) or (mode == 3) or True): # self._main_mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 1 + 3 + 3 + 1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): for index in range(4): if (self._sub_mode_index[index] == 0): self._modes_buttons[index].set_on_off_values( AMBER_FULL, AMBER_THIRD) if (self._sub_mode_index[index] == 1): self._modes_buttons[index].set_on_off_values( GREEN_FULL, GREEN_THIRD) if (self._sub_mode_index[index] == 2): self._modes_buttons[index].set_on_off_values( RED_FULL, RED_THIRD) if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index == 0: new_channel = 0 # session elif self._main_mode_index == 1: if self._sub_mode_index[self._main_mode_index] == 0: new_channel = 11 # instrument controller # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_index[self._main_mode_index] == 1: new_channel = 3 # device controller elif self._sub_mode_index[self._main_mode_index] == 2: new_channel = 4 # plain user mode 1 elif self._main_mode_index == 2: if self._sub_mode_index[self._main_mode_index] == 0: new_channel = 1 # step seq elif self._sub_mode_index[self._main_mode_index] == 1: new_channel = 2 # melodic step seq elif self._sub_mode_index[self._main_mode_index] == 2: new_channel = 5 # plain user mode 2 elif self._main_mode_index == 3: # mixer modes # mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) if self._main_mode_index == 0: # session self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() self._mode_index = 0 elif self._main_mode_index == 1 or self._main_mode_index == 2: self._setup_usermode(Settings.USER_MODES[ (self._main_mode_index - 1) * 3 + self._sub_mode_index[self._main_mode_index]]) #if self._sub_mode_index[self._main_mode_index] == 0: # self._setup_usermode(Settings.USER_MODES[0]) #elif self._sub_mode_index[self._main_mode_index] == 1: # self._setup_usermode(Settings.USER_MODES[1]) #else: # self._setup_usermode(Settings.USER_MODES[2]) #elif self._main_mode_index == 2: # if self._sub_mode_index[self._main_mode_index] == 0: # self._setup_usermode(Settings.USER_MODES[3]) # elif self._sub_mode_index[self._main_mode_index] == 1: # self._setup_usermode(Setting.USER_MODES[4]) # else: # self._setup_usermode(Settings.USER_MODES[5]) elif self._main_mode_index == 3: # mixer self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() self._mode_index = 3 else: assert False self._previous_mode_index = self._main_mode_index self._session.set_allow_update(True) self._zooming.set_allow_update(True) #self.log_message("main selector update") #for line in traceback.format_stack(): # self.log_message(line.strip()) def _setup_usermode(self, mode): as_active = True as_enabled = True if mode == "instrument": self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) self._mode_index = 4 elif mode == "melodic stepseq": self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) self._update_control_channels() self._mode_index = 7 elif mode == "user 1": self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() self._mode_index = 1 self._osd.clear() self._osd.mode = "User 1" self._osd.update() elif mode == "drum stepseq": self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) self._update_control_channels() self._mode_index = 6 elif mode == "device": self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() self._mode_index = 5 elif mode == "user 2": self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() self._mode_index = 2 self._osd.clear() self._osd.mode = "User 2" self._osd.update() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) # matrix self._activate_matrix(True) for scene_index in range(self._session._num_scenes): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(self._session._num_tracks): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: if self._session._stop_clip_buttons != None: for button in self._session._stop_clip_buttons: button.set_enabled(as_active) button.set_on_off_values(AMBER_THIRD, LED_OFF) self._session.set_stop_track_clip_buttons( self._session._stop_clip_buttons) self._side_buttons[self._session._num_scenes].set_enabled( as_active) self._side_buttons[ self._session._num_scenes].set_on_off_values( AMBER_THIRD, LED_OFF) self._session.set_stop_all_clips_button( self._side_buttons[self._session._num_scenes]) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) # zoom if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) # nav buttons if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, enabled): if self._instrument_controller != None: if enabled: self._activate_matrix(False) self._activate_scene_buttons(True) self._activate_navigation_buttons(True) else: for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.use_default_message() scene_button.force_next_send() for track_index in range(8): button = self._matrix.get_button( track_index, scene_index) button.use_default_message() button.force_next_send() self._instrument_controller.set_enabled(enabled) def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if drum_rack_mode: self._config_button.send_value(2) self._config_button.send_value(32) def _setup_step_sequencer(self, as_active): if (self._stepseq != None): #if(self._stepseq.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if (self._stepseq2 != None): #if(self._stepseq2.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if (self._sub_modes.is_enabled()): # go back to default mode self._sub_modes.set_mode(-1) else: self._sub_modes.release_controls() self._sub_modes.set_enabled(as_active) def _init_session(self): major = self._parent._live_major_version minor = self._parent._live_minor_version bugfix = self._parent._live_bugfix_version if (major >= 9 and minor > 1) or (major >= 9 and minor >= 1 and bugfix >= 2): # api changed in 9.1.2 self._session.set_stop_clip_value(AMBER_THIRD) self._session.set_stop_clip_triggered_value(AMBER_BLINK) else: # api for 9.1.1 below self._session.set_stop_track_clip_value(AMBER_BLINK) session_height = self._matrix.height() if self._session._stop_clip_buttons != None: session_height = self._matrix.height() - 1 for scene_index in range(session_height): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.set_record_button_value(RED_THIRD) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) def _activate_navigation_buttons(self, active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self, active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self, active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._parent.log_message(msg) # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value()
class MF3D_Color_Clip(ControlSurface): __doc__ = " Script for Mad Zach's Weekly soundpacks " _active_instances = [] def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log opened =--------------" ) # Writes message into Live's main log file. This is a ControlSurface method. self.set_suppress_rebuild_requests(True) self._session = None self._session_zoom = None self._last_tr_off = 0 self._last_sc_off = 0 self._scenedir = 1 # direction of scene movement self._last_scenedir = 1 self._setup_session_control() self.set_suppress_rebuild_requests(False) def disconnect(self): self._session = None self._session_zoom = None self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log closed =--------------" ) # Writes message into Live's main log file. This is a ControlSurface method. ControlSurface.disconnect(self) def _setup_session_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' self._session = SpecialSessionComponent(4, 4) self._session.name = 'Session_Control' self._session.set_track_bank_buttons( self._set_button(BUTTONCHANNEL + 1, SESSIONRIGHT), self._set_button(BUTTONCHANNEL + 1, SESSIONLEFT)) self._session.set_scene_bank_buttons( self._set_button(BUTTONCHANNEL + 1, SESSIONDOWN), self._set_button(BUTTONCHANNEL + 1, SESSIONUP)) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons( self._set_button(BUTTONCHANNEL + 1, ZOOMUP), self._set_button(BUTTONCHANNEL + 1, ZOOMDOWN), self._set_button(BUTTONCHANNEL + 1, ZOOMLEFT), self._set_button(BUTTONCHANNEL + 1, ZOOMRIGHT)) tracks = self.getslots() #get clip slots to access clip colors for scene_index in range(4): scene_off = self._session._scene_offset scene = self._session.scene(scene_index + scene_off) scene.name = 'Scene_' + str(scene_index + scene_off) button_row = [] for track_index in range(4): button = self._set_button( BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF) button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index + scene_off) clip_slot.set_launch_button(button) c = tracks[track_index][scene_index + scene_off] #get clip for color clip_slot.set_stopped_value(LOWYELLOW) if c.clip != None: cval = self._get_MF3D_color(self.int_to_rgb(c.clip.color)) self.log_message("Clip: tr: " + str(track_index) + " clip: " + str(scene_index + scene_off) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval)) clip_slot.set_stopped_value(cval) ## clip_slot.set_triggered_to_launch_value(1) clip_slot.set_triggered_to_play_value(PLAYTRIG_COL) clip_slot.set_started_value(TRIGD_COL) clip_slot.set_triggered_to_record_value(RECTRIG_COL) clip_slot.set_recording_value(RECD_COL) def int_to_rgb(self, rgbint): return (rgbint / 256 / 256 % 256, rgbint / 256 % 256, rgbint % 256) def getslots(self): tracks = self.song().visible_tracks clipSlots = [] for track in tracks: clipSlots.append(track.clip_slots) return clipSlots def _set_button(self, _channel, _note, _on_color=118, _off_color=0): _button = None if not _note is -1: _button = ConfigurableButtonElement(True, MESSAGETYPE, _channel, _note, _on_color, _off_color) return _button def _set_colors(self, scene_dir): tracks = self.getslots() #get clip slots to access clip colors scene_off = self._session.scene_offset() track_off = self._session.track_offset() for scene_index in range(4): sc = scene_index #self._session._reassign_scenes() scene = self._session.scene(sc) self.log_message("scene index :" + str(scene_index) + " scene offset " + str(scene_off)) scene.name = 'Scene_' + str(scene_index) button_row = [] for track_index in range(4): #button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF) #button_row.append(button) tr = track_index clip_slot = scene.clip_slot(tr) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) #clip_slot.set_launch_button(button) c = tracks[track_index][scene_index + scene_off + scene_dir] #get clip for color clip_slot.set_stopped_value(LOWYELLOW) if c.clip != None: cval = self._get_MF3D_color(self.int_to_rgb(c.clip.color)) clip_slot.set_stopped_value(cval) self.log_message("Clip: scene: " + str(scene_index + scene_off) + " track: " + str(track_index) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval)) def update_display(self): ControlSurface.update_display(self) scene_off = self._session.scene_offset() track_off = self._session.track_offset() if (scene_off != self._last_sc_off): self.log_message("moved : " + str(self._session._track_offset) + " " + str(self._session._scene_offset)) if (scene_off > self._last_sc_off): if self._scenedir is not self._last_scenedir: self._scenedir = -1 else: self._scenedir = 1 elif (scene_off < self._last_sc_off): if self._scenedir is not self._last_scenedir: self._scenedir = 1 else: self._scenedir = -1 #else: # self._scenedir=0 self._last_tr_off = track_off self._last_sc_off = scene_off self._last_scenedir = self._scenedir self._set_colors(self._scenedir) def _get_MF3D_color(self, colors): red = colors[0] green = colors[1] blue = colors[2] color_table = ((255, 0, 0, RED), (125, 0, 0, LOWRED), (255, 127, 0, ORANGE), (127, 64, 0, LOWORANGE), (255, 255, 0, YELLOW), (127, 127, 0, LOWYELLOW), (127, 255, 0, CHARTREUSSE), (64, 127, 0, LOWCHARTREUSSE), (0, 255, 0, GREEN), (0, 127, 0, LOWGREEN), (0, 255, 255, CYAN), (0, 127, 127, LOWCYAN), (0, 0, 255, BLUE), (0, 0, 127, LOWBLUE), (0, 255, 127, PURPLE), (0, 127, 64, LOWPURPLE), (0, 255, 255, PINK), (0, 127, 127, LOWPINK), (255, 255, 255, WHITE)) min_dist = 9999999 color_node = (0, 0, 0, 119) for index in range(len(color_table)): if (min_dist > self._get_distance(colors, color_table[index])): min_dist = self._get_distance(colors, color_table[index]) #self.log_message("colors " + str(color_node) + " and " + str(color_table[index])) color_node = color_table[index] #self.log_message("red " + str(red) + " green " + str(green) + " blue " + str(blue) + " distance to" + str(color_node[3]) + " :: " + str(self._get_distance(colors,color_node))) return color_node[3] def _get_distance(self, color1, color2): r1 = color1[0] g1 = color1[1] b1 = color1[2] r2 = color2[0] g2 = color2[1] b2 = color2[2] #self.log_message("got " + str(color1) + " and " + str(color2)) return (abs((r1 - r2)) + abs((g1 - g2)) + abs((b1 - b2)))
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the buttons on the Spark to different functions """ def __init__(self, launch_buttons, mode_buttons, pads, transport_buttons, select_button, translate_button, mute_button, solo_button, tempo_control, volume_control, param_controls, copy_button, erase_button, rewind_button, forward_button, browser_control, browser_button, pattern_leds, track_leds, divide_control, move_control, parent): "verifies that the buttons given are compatible with the selector component" assert isinstance(launch_buttons, tuple) assert (len(launch_buttons) == 16) assert isinstance(mode_buttons, tuple) assert (len(mode_buttons) == 4) assert isinstance(pads, tuple) assert (len(pads) == 8) assert (len(transport_buttons) == 4) assert (len(param_controls) == 3) ModeSelectorComponent.__init__(self) "the parent atribute allows us to control the control surface component" "it can be used for example to get the currently selected track" self._parent = parent "definition of all the components we will map buttons with" self._session = SpecialSessionComponent(8, 16) self._session.name = 'Session_Control' self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer_Control' self._transport = SpecialTransportComponent(self) self._transport.name = 'Transport_Control' self._device = DeviceComponent() self._device.name = 'Device_Control' "definition of all the buttons that will be used" self._launch_buttons = launch_buttons self._mode_buttons = mode_buttons self._pads = pads self._all_buttons = [] self._select_button = select_button self._translate_button = translate_button self._mute_button = mute_button self._solo_button = solo_button self._transport_buttons = transport_buttons self._copy_button = copy_button self._erase_button = erase_button self._rewind_button = rewind_button self._forward_button = forward_button self._browser_control = browser_control self._browser_button = browser_button self._divide_control = divide_control self._move_control = move_control self._track_leds = track_leds self._pattern_leds = pattern_leds "definition of all the controls that will be used" self._tempo_control = tempo_control self._volume_control = volume_control self._param_controls = param_controls for button in self._launch_buttons + self._mode_buttons + self._pads + self._transport_buttons + self._track_leds + self._pattern_leds: self._all_buttons.append(button) self._all_buttons.append(self._select_button) self._all_buttons.append(self._translate_button) self._all_buttons.append(self._mute_button) self._all_buttons.append(self._solo_button) self._all_buttons.append(self._copy_button) self._all_buttons.append(self._erase_button) self._all_buttons.append(self._rewind_button) self._all_buttons.append(self._forward_button) self._stepseq = StepSequencerComponent(self, self._launch_buttons,self._pads, self._translate_button, self._select_button, self._mute_button, self._solo_button, tuple(self._transport_buttons), forward_button, rewind_button, pattern_leds) self._translation_selector = TranslationSelectorComponent(tuple(self._launch_buttons), tuple(self._pads), self._translate_button, self) self._init_session() self._all_buttons = tuple(self._all_buttons) self._mode_index=0 self._previous_mode_index=-1 self.set_mode_buttons(mode_buttons) self._parent = parent self._selected_track_index=0 self._previous_track_index=0 self._parent.set_device_component(self._device) for button in self._all_buttons: button.send_value(0,True) def disconnect(self): for button in self._mode_buttons: button.remove_value_listener(self._mode_value) for button in self._all_buttons: button.send_value(0,True) self._session = None self._mixer = None self._transport = None self._launch_buttons = None self._mode_buttons = None self._pads = None self._transport_buttons = None ModeSelectorComponent.disconnect(self) def _update_mode(self): """check if the mode selected is a new mode and if so update the controls""" mode = self._modes_heap[-1][0] assert mode in range(self.number_of_modes()) if self._mode_index==mode or (mode == 2 and not self.song().view.selected_track.has_midi_input): self._previous_mode_index=self._mode_index else: self._mode_index = mode for button in self._all_buttons: button.send_value(0,True) self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] def number_of_modes(self): return 4 def _update_mode_buttons(self): """lights up the mode buttons if selected""" for index in range(4): if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def update(self): """main method of the class that calls the assignation methods corresponding to the current mode""" """it is called when the mode changes and when the selected track changes""" assert (self._modes_buttons != None) "links the session to the mixer, so that when change the selected track the session also changes position" self._session.set_mixer(self._mixer) if self.is_enabled(): self._update_mode_buttons() self._translation_selector.update() as_active = True as_enabled = True self._session.set_allow_update(False)#we dont want the controlls to change while we are updating the assignations if (self._mode_index == 0): "A: Transport mode" "we activate the transport buttons and tha launch scenes buttons" #self._parent.log_message("Launching mode") self._setup_step_sequencer(not as_active) self._setup_launch_clips(not as_active,not as_enabled) self._setup_track_controls(not as_active) self._setup_device_buttons(not as_active) self._set_scale_control(not as_active) self._setup_transport_buttons(as_active) self._setup_launch_scenes(as_active, as_enabled) self._setup_master_controls(as_active) self._set_browser_control(as_active) self._set_browser_button(as_active) self._setup_select_buttons(as_active) elif (self._mode_index == 1): "B: Mixer mode" "we activate the track selection, arm, and mute buttons and the launch clips buttons" #self._parent.log_message("Launching clips mode") self._setup_step_sequencer(not as_active) self._setup_launch_scenes(not as_active, not as_enabled) self._setup_master_controls(not as_active) self._setup_device_buttons(not as_active) self._set_scale_control(not as_active) self._setup_transport_buttons(as_active) self._setup_launch_clips(as_active, as_enabled) self._setup_track_controls(as_active) self._setup_select_buttons(as_active) self._set_browser_control(as_active) self._set_browser_button(as_active) elif (self._mode_index == 2): "C: Step sequencer mode" self._setup_launch_scenes(not as_active, not as_enabled) self._setup_launch_clips(not as_active,not as_enabled) self._setup_track_controls(not as_active) self._setup_master_controls(not as_active) self._setup_select_buttons(not as_active) self._setup_device_buttons(not as_active) self._setup_transport_buttons(not as_active) self._set_scale_control(not as_active) self._setup_step_sequencer(as_active) self._set_browser_control(as_active) self._set_browser_button(as_active) else: "D: Instrument mode" "the keyboard now control the selected midi instrument" self._setup_step_sequencer(not as_active) self._setup_launch_clips(not as_active,not as_enabled) self._setup_launch_scenes(not as_active, not as_enabled) self._setup_track_controls(not as_active) self._setup_master_controls(not as_active) self._setup_select_buttons(not as_active) self._set_browser_control(as_active) self._set_browser_button(as_active) self._setup_device_buttons(as_active) self._setup_transport_buttons(as_active) self._set_scale_control(as_active) self._update_session_translation() self._session.set_allow_update(True) self._previous_mode_index=self._mode_index #self._parent.log_message("Updated") def _setup_launch_scenes(self, as_active, as_enabled): "if as_active, we'll assignate the keyboard notes to the launch scene buttons" assert isinstance(as_active, type(False)) #launch_buttons for scene_index in range(16): scene = self._session.scene(scene_index) if as_active: scene_button = self._launch_buttons[scene_index] scene_button.turn_off() scene.set_launch_button(scene_button) else: scene.set_launch_button(None) def _setup_launch_clips(self, as_active, as_enabled): "if as_active, we'll assignate the keyboard notes to the launch clip buttons" assert isinstance(as_active, type(False)) #launch_buttons for scene_index in range(16): scene = self._session.scene(scene_index) for track_index in range(8): if as_active and track_index==self._selected_track_index: clip_button = self._launch_buttons[scene_index] clip_button.turn_off() scene.clip_slot(track_index).set_launch_button(clip_button) else: scene.clip_slot(track_index).set_launch_button(None) def _setup_select_buttons(self, as_active): "if as_active, we'll assign the pads to track selection and track control buttons" "pads 15 and 16 will shift and arm tha selected track" for index in range(8): select_button = self._pads[index] if as_active: if self._selected_track_index == index: "we only assign the arm and mute buttons of the selected track" #self._parent.log_message("set arm on "+str(index)) self._mixer.channel_strip(index).set_arm_button(select_button) self._mixer.channel_strip(index).set_mute_button(self._mute_button) self._mixer.channel_strip(index).set_solo_button(self._solo_button) self._mixer.channel_strip(index).set_select_button(None) self._mixer.channel_strip(index).set_shift_button(self._select_button) self._track_leds[index].send_value(127,True) else: self._mixer.channel_strip(index).set_arm_button(None) self._mixer.channel_strip(index).set_select_button(select_button) self._mixer.channel_strip(index).set_mute_button(None) self._mixer.channel_strip(index).set_solo_button(None) self._mixer.channel_strip(index).set_shift_button(None) self._track_leds[index].send_value(0,True) else: self._mixer.channel_strip(index).set_select_button(None) self._mixer.channel_strip(index).set_arm_button(None) self._mixer.channel_strip(index).set_mute_button(None) self._mixer.channel_strip(index).set_mute_button(None) self._mixer.channel_strip(index).set_solo_button(None) self._track_leds[index].turn_off() def _setup_transport_buttons(self, as_active): "if as_active, we'll assign the pads to the transport buttons" if as_active: self._transport.set_play_button(self._transport_buttons[2]) self._transport.set_stop_button(self._transport_buttons[1]) self._transport.set_record_button(self._transport_buttons[0]) self._transport.set_loop_button(self._transport_buttons[3]) self._transport.set_tempo_encoder(self._tempo_control) self._transport.set_undo_button(self._erase_button) self._transport.set_redo_button(self._copy_button) else: self._transport.set_play_button(None) self._transport.set_stop_button(None) self._transport.set_record_button(None) self._transport.set_loop_button(None) self._transport.set_tempo_encoder(None) self._transport.set_undo_button(None) self._transport.set_redo_button(None) def _setup_master_controls(self, as_active): "if as_active, we'll assign the control knobs to the master track parameters" if as_active: self._mixer.master_strip().set_volume_control(self._volume_control) self._mixer.master_strip().set_pan_control(self._param_controls[0]) self._mixer.set_prehear_volume_control(self._param_controls[1]) self._mixer.set_crossfader_control(self._param_controls[2]) self._transport.set_seek_buttons(self._forward_button,self._rewind_button) else: self._mixer.master_strip().set_volume_control(None) self._mixer.master_strip().set_pan_control(None) self._mixer.set_prehear_volume_control(None) self._mixer.set_crossfader_control(None) self._transport.set_seek_buttons(None,None) def _setup_track_controls(self, as_active): "if as_active, we'll assign the control knobs to the master track parameters" if as_active: self._parent.log_message(self._previous_track_index) self._mixer.channel_strip(self._previous_track_index).set_volume_control(None) self._mixer.channel_strip(self._previous_track_index).set_pan_control(None) self._mixer.channel_strip(self._previous_track_index).set_send_controls(None) self._parent.log_message(self._selected_track_index) self._mixer.channel_strip(self._selected_track_index).set_volume_control(self._volume_control) self._mixer.channel_strip(self._selected_track_index).set_pan_control(self._param_controls[0]) self._mixer.channel_strip(self._selected_track_index).set_send_controls(self._param_controls[1:]) else: self._mixer.channel_strip(self._selected_track_index).set_volume_control(None) self._mixer.channel_strip(self._selected_track_index).set_pan_control(None) self._mixer.channel_strip(self._selected_track_index).set_send_controls(None) def _setup_device_buttons(self, as_active): "if as_active, we'll assign the pads to the device selection and activation buttons" if as_active: self._device.set_parameter_controls(self._param_controls) self._device.set_bank_nav_buttons(self._rewind_button, self._forward_button) else: self._device.set_parameter_controls(None) self._device.set_bank_nav_buttons(None, None) def _init_session(self): for scene_index in range(len(self._launch_buttons)): scene = self._session.scene(scene_index) scene.set_triggered_value(127) scene.name = 'Scene_' + str(scene_index) for track_index in range(8): "TODO: this still doesn't light the launch clip buttons when supposed to..." clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(127) clip_slot.set_triggered_to_record_value(127) clip_slot.set_stopped_value(0) clip_slot.set_started_value(127) clip_slot.set_recording_value(127) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) def _mode_value(self, value, sender): "method called each time the value of the mode selection changed" "it's been momentary overriden to avoid dysfunctionnement in the framework method" new_mode = self._modes_buttons.index(sender) if sender.is_momentary(): #self._parent.log_message(sender.message_identifier()) if value > 0: #self._parent.log_message("value = "+str(value)) mode_observer = MomentaryModeObserver() mode_observer.set_mode_details(new_mode, self._controls_for_mode(new_mode), self._get_public_mode_index) self._modes_heap.append((new_mode, sender, mode_observer)) self._update_mode() elif self._modes_heap[-1][1] == sender and not self._modes_heap[-1][2].is_mode_momentary(): #self._parent.log_message("sender trouve") self.set_mode(new_mode) else: #TODO: comprendre comment le framework est sense fonctionner et remplacer supprimer cet modif du framework self.set_mode(new_mode) self._update_mode() else: #self._parent.log_message("boutton pas trouve") self.set_mode(new_mode) def _setup_step_sequencer(self, as_active): if(self._stepseq!=None): if as_active: self._stepseq._force_update = True self._stepseq._is_active = True self._stepseq.set_enabled(True) self._stepseq._on_notes_changed() self._stepseq._update_seq_buttons() else: self._stepseq._is_active = False self._stepseq.set_enabled(False) def _set_browser_control(self, as_active): self._browser_control.remove_value_listener(self._browser_control_value) if as_active: self._browser_control.add_value_listener(self._browser_control_value) def _browser_control_value(self, value): if value != 64: all_scenes = self.song().scenes selected_scene = self.song().view.selected_scene selected_scene_index = list(all_scenes).index(selected_scene) new_selected_scene_index = max(0, min(selected_scene_index + (value-64), len(list(all_scenes))-1) ) self.song().view.selected_scene = all_scenes[new_selected_scene_index] session_offset = self._session.scene_offset() if new_selected_scene_index > session_offset + 15: self._session.set_offsets(self._session.track_offset(), new_selected_scene_index - 15) if new_selected_scene_index < session_offset: self._session.set_offsets(self._session.track_offset(), new_selected_scene_index) def _set_browser_button(self, as_active): self._browser_button.remove_value_listener(self._browser_button_value) if as_active: self._browser_button.add_value_listener(self._browser_button_value) def _browser_button_value(self, value): if value != 0: if self._mode_index == 2: self.song().view.highlighted_clip_slot.fire() else: self.song().view.selected_scene.fire_as_selected() def _set_scale_control(self, as_active): self._divide_control.remove_value_listener(self._translation_selector._scale_index_value) self._move_control.remove_value_listener(self._translation_selector._scale_offset_value) if as_active: self._divide_control.add_value_listener(self._translation_selector._scale_index_value) self._move_control.add_value_listener(self._translation_selector._scale_offset_value) def _update_session_translation(self): if self._mode_index == 0 or self._mode_index == 1: if self._translation_selector.mode(): self._session.set_offsets(8,self._session.scene_offset()) else: self._session.set_offsets(0,self._session.scene_offset()) def on_selected_track_changed(self): all_tracks = ((self.song().tracks + self.song().return_tracks)) selected_track = self.song().view.selected_track self._previous_track_index = self._selected_track_index self._selected_track_index = list(all_tracks).index(selected_track) self.update()
class MainSelectorComponent(ModeSelectorComponent): " CLASS THAT REASSIGNS THE BUTTON ON THE LAUNCHPAD TO DIFFERENT FUNCTIONS " " INIT " def __init__(self, matrix, top_buttons, side_buttons, config_button): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._session = SpecialSessionComponent(self, len(self.song().tracks), matrix.height(), side_buttons) self._session.name = "Session_Control" self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._all_buttons = [] for button in (self._side_buttons + self._nav_buttons): self._all_buttons.append(button) self._sub_modes = SpecialMixerSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = "Mixer_Modes" self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) # mixer-session hack self._buttons_for_mixer = [] for button in (self._side_buttons[5:]): self._buttons_for_mixer.append(button) for scene_index in range(self._matrix.height()): for track_index in range(self._matrix.width()): if scene_index > SESSION_HEIGHT_FOR_MIXER: self._buttons_for_mixer.append(self._matrix.get_button(track_index, scene_index)) " DISCONNECT " def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None self._buttons_for_mixer = None ModeSelectorComponent.disconnect(self) " GET SESSION COMPONENT " def session_component(self): return self._session " SET THE MODE BUTTONS " def set_modes_buttons(self, buttons): assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == self.number_of_modes()))) identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if (buttons != None): for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) " GET AMOUNT OF MODES " def number_of_modes(self): return 4 " CHANGE CALLBACK " def on_enabled_changed(self): self.update() " SET THE MODE " def set_mode(self, mode): assert (mode in range(self.number_of_modes())) if ((self._mode_index != mode) or (mode == 3) or True): self._mode_index = mode self.update() " UPDATE MODE BUTTONS " def _update_mode_buttons(self): for index in range(4): if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() " SET CHANNEL FOR THE CURRONT MODE " def channel_for_current_mode(self): #trying to keep if self._mode_index==0: return 0 elif self._mode_index==1: new_channel=4#user 1 elif self._mode_index==2: new_channel=5#user 2 elif self._mode_index==3: new_channel = 6 + self._sub_modes.mode() #mixer modes return new_channel " UPDATE THE SHIT " def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() #update matrix and side buttons for scene_index in range(self._matrix.height()): #update scene button self._side_buttons[scene_index].set_enabled(True) for track_index in range(self._matrix.width()): #update matrix self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = (self._mode_index == 1) if (self._mode_index == 0): #session self._setup_mixer((not as_active)) self._setup_session(as_active, as_enabled, False) elif (self._mode_index == 1): #user mode 1 self._setup_mixer((not as_active)) self._setup_session((not as_active), (not as_enabled), False) self._setup_user1(True,True,True) elif (self._mode_index == 2): #user mode 2 self._setup_mixer((not as_active)) self._setup_session((not as_active), (not as_enabled), False) self._setup_user2(release_buttons) elif (self._mode_index == 3): #mixer self._setup_session((as_active), as_enabled, True) self._setup_mixer(as_active) else: assert False self._session.set_allow_update(True) self._update_control_channels() " UPDATE THE CHANNELS OF THE BUTTONS IN THE USER MODES.. " def _update_control_channels(self): new_channel = self.channel_for_current_mode() if self._mode_index == 3: # skip the upper part of the matrix and buttons for button in self._buttons_for_mixer: button.set_channel(new_channel) button.set_force_next_value() else: for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() " SETUP THE SESSION " def _setup_session(self, as_active, as_enabled, for_mixer): #log("setup_session (active: " + str(as_active) + ", enabled: " + str(as_enabled) + ", forMixer: " + str(for_mixer) + ")") assert isinstance(as_active, type(False)) assert isinstance(as_enabled, type(False)) assert isinstance(for_mixer, type(False)) # --------------------------------------------------------------------- nav button color for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) # --------------------------------------------------------------------- matrix for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) if for_mixer: if scene_index <= SESSION_HEIGHT_FOR_MIXER: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, GREEN_THIRD) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) elif as_active and (not for_mixer): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, GREEN_THIRD) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) # SLOT BUTTONS button_index = 0 for track_index in range(len(self.song().tracks)): if self.song().tracks[track_index].is_foldable: if button_index < GROUPS_CONSIDERED: if for_mixer: if scene_index <= SESSION_HEIGHT_FOR_MIXER: button = self._matrix.get_button(button_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) elif as_active and (not for_mixer): button = self._matrix.get_button(button_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) button_index = button_index + 1 else: scene.clip_slot(track_index).set_launch_button(None) # --------------------------------------------------------------------- nav buttons if as_enabled or for_mixer: self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_scene_bank_buttons(None, None) " SETUP THE MIXER " def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) self._sub_modes.set_enabled(as_active) " SETUP USER 1 " def _setup_user1(self, release_matrix=True,release_side_buttons =True,release_nav_buttons = True): for scene_index in range(8): if(release_side_buttons): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: if(release_nav_buttons): button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if release_matrix: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) " SETUP USER 2 " def _setup_user2(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) " INIT THE SESSION " def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) # SCENES for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = ("Scene_" + str(scene_index)) # SLOTS button_index = 0 for track_index in range(len(self.song().tracks)): if button_index < GROUPS_CONSIDERED: if self.song().tracks[track_index].is_foldable: clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = ((str(track_index) + "_Clip_Slot_") + str(scene_index)) self._all_buttons.append(self._matrix.get_button(button_index, scene_index)) button_index = button_index + 1
class X1MK2(ControlSurface): __doc__ = " Script for Traktor X1MK2 in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in X1MK2._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self._color_skin = make_rgb_skin() #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._to_notify = [] self._clip_map = [] self._note_map = [] self._ctrl_map = [] self._enc_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._clip_map = None self._note_map = None self._ctrl_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in X1MK2._active_instances: X1MK2._active_instances.append(self) X1MK2._combine_active_instances() def _do_uncombine(self): if ((self in X1MK2._active_instances) and X1MK2._active_instances.remove(self)): self._session.unlink() X1MK2._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(SESSION_WIDTH, SESSION_HEIGHT, self.log_message, enable_skinning = True) self._session.set_rgb_mode(color_palette = CLIP_COLOR_TABLE(self.log_message), color_table = None, clip_slots_only = True) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT]) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ] self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(SESSION_WIDTH)] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons)) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(SESSION_HEIGHT): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(SESSION_WIDTH): button = self._clip_map[CLIPNOTEMAP[scene_index][track_index]] button.num_delayed_messages = 3 delete_button = self._note_map[DELETECLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) clip_slot.set_launch_button(button) self._to_notify.append(clip_slot) clip_slot.set_delete_button(delete_button) # # clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY[self._rgb]) #set its triggered to play color # # clip_slot.set_triggered_to_record_value(CLIP_TRG_REC[self._rgb])#set its triggered to record color # # clip_slot.set_stopped_value(CLIP_STOP[self._rgb]) #set its stop color # clip_slot.set_started_value(13) #set its started color # clip_slot.set_recording_value(11) #set its recording value self.log_message('Clip %s:%s' % (clip_slot.name, clip_slot._launch_button_value.subject.message_identifier())) #self._session_zoom = SpecialZoomingComponent(self._session) #self._session_zoom.name = 'Session_Overview' #self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True #Setup mixer using the VCM600's MixerComponent which includes EQ and Filter components for tracks self._mixer = MixerComponent(SESSION_WIDTH, self) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME]) for track in range(SESSION_WIDTH): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) #Setup EQs using the VCM600s TrackEQComponent eq = self._mixer.track_eq(track) eq.name = 'Mixer_EQ_' + str(track) eq.set_gain_controls(tuple([self._enc_map[EQGAINS[track][0]],self._enc_map[EQGAINS[track][1]],self._enc_map[EQGAINS[track][2]]])) #set the encoders for eq gains eq.set_cut_buttons(tuple([self._note_map[EQCUTS[track][0]],self._note_map[EQCUTS[track][1]],self._note_map[EQCUTS[track][2]]])) eq.set_enabled(True) #setup filters using VCM600s TrackFilterComponent filter = self._mixer.track_filter(track) filter.name = 'Mixer_Filter_' + str(track) filter.set_filter_controls(self._enc_map[FILTERS[track][0]],self._enc_map[FILTERS[track][1]]) filter.set_device_on_off(self._note_map[FILTER_ON[track]],self.log_message) filter.set_enabled(True) # for index in range(len(filter._track.devices)): # device = filter._track.devices[-1 * (index + 1)] # self.log_message('Device %s: %s / %s' % (index, device.class_name, device.name)) # fx1 = self._mixer.track_fx1(track) fx1.name = 'Mixer_FX1_' + str(track) fx1.set_on_off_button(self._note_map[FX1_ON[track]]) fx1.set_enabled(True) fx2 = self._mixer.track_fx2(track) fx2.set_on_off_button(self._note_map[FX2_ON[track]]) fx2.set_enabled = True #Set strip buttons strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(8): device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map[DEVICEONOFF]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW]) detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] ) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._note_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) # self.log_message('Track %s' % track) # self.log_message('EQ Track %s' % self._mixer.track_eq(track.)._track) # self.log_message('EQ Track Devices' % self._mixer.track_eq(0)._device.class_name) # def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True rgb_skin = make_rgb_skin() for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note,) button.name = 'Button Note_' + str(note) button.is_rgb = True self._note_map.append(button) self._note_map.append(None) #add None to the end of the list, selectable with [-1] for note in range(128): clip_button = ColorButtonElement(self.log_message,is_momentary, MESSAGETYPE, BUTTONCHANNEL, note, skin = rgb_skin) clip_button.name = 'Clip Note_' + str(note) button.num_delayed_messages = 3 self._clip_map.append(clip_button) self._clip_map.append(None) #add None if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for i in range(128): self._ctrl_map.append(None) self._enc_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) self._ctrl_map.append(None) for enc in range(128): encoder = EncoderElement(MIDI_CC_TYPE, SLIDERCHANNEL, enc, Live.MidiMap.MapMode.absolute) encoder.name = "Encoder_" + str(enc) self._enc_map.append(encoder) self._enc_map.append(None) self.log_message('Note Map: %s' % self._note_map) self.log_message('Ctrl Map: %s' % self._ctrl_map) self.log_message('Enc Map: %s' % self._enc_map) def notify(self): for component in self._to_notify: component.update() def update_display(self): with self.component_guard(): with self._is_sending_scheduled_messages(): self._task_group.update(0.1) self.notify()
class MainSelectorComponent(ModeSelectorComponent): __module__ = __name__ __doc__ = ' Class that reassigns the button on the launchpad to different functions ' def __init__(self, matrix, top_buttons, side_buttons, config_button, knobs, sliders, script): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._script = script self._session = SpecialSessionComponent(matrix.width(), matrix.height()) for scene in self._session._scenes: for slot in scene._clip_slots: slot._triggered_to_play_value = 4 slot._triggered_to_record_value = 3 slot._started_value = 2 slot._recording_value = 1 slot._stopped_value = 127 self._zooming = SessionZoomingComponent(self._session) self._zooming._stopped_value = 127 self._zooming._playing_value = 2 self._zooming._selected_value = 1 self._matrix = matrix self._knobs = knobs self._sliders = sliders self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._shift_button = top_buttons[5] self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in (self._side_buttons + self._nav_buttons): self._all_buttons.append(button) self._shift_pressed = 0 self._shift_pressed_timer = 0 self._last_normal_mode = 0 self._shift_button = None self.set_shift_button(top_buttons[6]) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:6]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def set_shift_button(self, button): assert ((button == None) or (isinstance(button, FlashingButtonElement))) if self._shift_button != None: self._shift_button.remove_value_listener(self._shift_value) self._shift_button = button if self._shift_button != None: self._shift_button.add_value_listener(self._shift_value) def _shift_value(self, value): self._shift_pressed = int(value != 0) if self._shift_pressed > 0: if (self._shift_pressed_timer + 5) > self._script._timer: if(self._script._host.is_enabled() != True): self.set_mode(4) else: self._script.log_message('here') self.set_mode(self._last_normal_mode) else: self._shift_pressed_timer = self._script._timer % 256 if(self._script._host.is_enabled() != True): if(self._mode_index == 1): if value > 0: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._sub_modes.set_modes_buttons(self._nav_buttons) self._sub_modes.update() else: self._sub_modes.set_modes_buttons(None) self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) self._sub_modes.update() elif(self._mode_index == 0): self._setup_session(True, True) self._session.update() def set_modes_buttons(self, buttons): assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == 2))) identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if (buttons != None): for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def _mode_value(self, value, sender): assert (len(self._modes_buttons) > 0) assert isinstance(value, int) assert isinstance(sender, ButtonElement) assert (self._modes_buttons.count(sender) == 1) if self._script._host.is_enabled() != True: if ((value is not 0) or (not sender.is_momentary())): if self._shift_pressed > 0: if self._modes_buttons.index(sender) == 0: self.set_mode(2) if self._modes_buttons.index(sender) == 1: self.set_mode(3) else: self._last_normal_mode = int(self._modes_buttons.index(sender)) self.set_mode(self._modes_buttons.index(sender)) else: pass def number_of_modes(self): return 5 def on_enabled_changed(self): self.update() def set_mode(self, mode): assert (mode in range(self.number_of_modes())) if ((self._mode_index != mode) or (mode == 1)): self._mode_index = mode self.update() def update(self): assert (self._modes_buttons != None) if self.is_enabled(): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = (self._mode_index == 1) if (self._mode_index < 4): self._script._host.set_enabled(False) self._script._host._set_button_matrix(None) self._script._host._set_alt_button(None) self._script._host._set_shift_button(None) self._script._host._set_nav_buttons(None) if (self._mode_index == 0): #session self._setup_mixer((not as_active)) self._setup_session(as_active, as_enabled) elif (self._mode_index == 1): #mixer self._setup_session((not as_active), as_enabled) self._setup_mixer(as_active) elif (self._mode_index == 2): #user1 self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) elif (self._mode_index == 3): #user2 self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) elif (self._mode_index == 4): #monomodular self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) self._script._host._set_button_matrix(self._matrix) self._script._host._set_shift_button(self._shift_button) self._script._host._set_lock_button(self._modes_buttons[0]) self._script._host._set_alt_button(self._modes_buttons[1]) self._script._host._set_nav_buttons(self._nav_buttons) self._script._host.set_enabled(True) else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() #self._script.request_rebuild_midi_map() def _update_control_channels(self): if self._mode_index < 4: new_channel = (self._mode_index + self._sub_modes.mode()) if (new_channel > 0): new_channel += 3 else: new_channel = 15 for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(127, 0) else: button.set_on_off_values(127, 0) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active and (self._shift_pressed == 1): scene_button = self._matrix.get_button(7, scene_index) scene_button.set_on_off_values(127, 0) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(SHIFT[self._shift_pressed]): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, 0) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) self._config_button.send_value(32) if release_buttons: self._config_button.send_value(2) def _init_session(self): self._session.set_stop_track_clip_value(3) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(1) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(4) clip_slot.set_triggered_to_record_value(3) clip_slot.set_stopped_value(127) clip_slot.set_started_value(2) clip_slot.set_recording_value(1) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(127) self._zooming.set_selected_value(1) self._zooming.set_playing_value(2)
class Midi_Fighter_Twister(ControlSurface): __doc__ = " Script for Midi_Fighter_Twister in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in Midi_Fighter_Twister._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._note_map = [] self._ctrl_map = [] self._shift_encoder_map = [] self._shift_bank_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map = None self._ctrl_map = None self._shift_encoder_map = None self._shift_bank_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None self._device = None ControlSurface.disconnect(self) def _do_combine(self): if self not in Midi_Fighter_Twister._active_instances: Midi_Fighter_Twister._active_instances.append(self) Midi_Fighter_Twister._combine_active_instances() def _do_uncombine(self): if ((self in Midi_Fighter_Twister._active_instances) and Midi_Fighter_Twister._active_instances.remove(self)): self._session.unlink() Midi_Fighter_Twister._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True # sessionRight = ButtonElement(is_momentary, 1, 3, 11) # sessionLeft = ButtonElement(is_momentary, 1, 3, 8) self._session = SpecialSessionComponent(4, 4) self._session.name = 'Session_Control' self._session.set_track_bank_buttons( self._shift_bank_map[SESSIONRIGHT], self._shift_bank_map[SESSIONLEFT]) # self._session.set_track_bank_buttons(sessionRight, sessionLeft) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [ self._note_map[SCENELAUNCH[index]] for index in range(4) ] self._track_stop_buttons = [ self._note_map[TRACKSTOP[index]] for index in range(4) ] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons( tuple(self._track_stop_buttons)) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button( self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(4): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(4): button = self._note_map[CLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True MasterVol = ButtonElement(is_momentary, 1, 4, 3) self._mixer = SpecialMixerComponent(4) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control( self._shift_encoder_map[MASTERVOLUME]) for track in range(4): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) # have right side btns act as device next/prev & toggle on/off? def _setup_device_and_transport_control(self): is_momentary = True # self._device = DeviceComponent() # self._device.name = 'Device_Component' # uses BestBankDeviceComponent as pseudo for Device_Component self._device = BestBankDeviceComponent( device_selection_follows_track_selection=True) self._device.name = u'Device_Component' # device_bank_buttons = [] device_param_controls = [] # Accounts for mappings on top two rows of MFT for index in range(16): # handles all 16 encoder knobs device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) for index in range(4): # 1st row, shift encoder hold device_param_controls.append( self._shift_encoder_map[PARAMCONTROL[index]]) for index in range(6): # 2nd row & left-half of 3rd row, CC hold device_param_controls.append(self._note_map[PARAMCONTROL[index + 4]]) # Accounts for mappings on third row of MFT # for index in range(4): # device_param_controls.append(self._shift_encoder_map[PARAMCONTROL[index + 8]]) # device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) # if None not in device_bank_buttons: # self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._shift_bank_map[DEVICEONOFF]) # self._device.set_bank_nav_buttons(self._shift_bank_map[DEVICEBANKNAVLEFT], self._shift_bank_map[DEVICEBANKNAVRIGHT]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button( self._shift_bank_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button( self._shift_bank_map[DETAILVIEW]) # detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] ) detail_view_toggler.set_device_nav_buttons( self._shift_bank_map[DEVICENAVLEFT], self._shift_bank_map[DEVICENAVRIGHT]) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._shift_bank_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) # From Axiom_AIR_25_49_61.py line 202 track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) # BEGIN update(self) FROM EncoderModeSelector.py # # todo: Move this block to a file where 'self._ctrl_map[PARAMCONTROL[index]]' # is accessible (MFT see line 164 for example) # if self.is_enabled(): # self._device.set_allow_update(False) # self._mixer.set_allow_update(False) # self._device.set_parameter_controls(()) # self._mixer.set_send_controls(()) # for index in range(len(self._encoders)): # strip = self._mixer.channel_strip(index) # encoder = self._encoders[index] # strip.set_volume_control(None) # strip.set_pan_control(None) # encoder.release_parameter() # if self._mode_index == 0: # strip.set_volume_control(encoder) # encoder.set_on_off_values(AMB_FULL, LED_OFF) # elif self._mode_index == 1: # strip.set_pan_control(encoder) # encoder.set_on_off_values(RED_FULL, LED_OFF) # elif self._mode_index == 2: # encoder.set_on_off_values(GRN_FULL, LED_OFF) # elif self._mode_index == 3: # encoder.set_on_off_values(RED_FULL, LED_OFF) # if self._mode_index == 0: # self._modes_buttons[0].send_value(AMB_FULL, True) # self._modes_buttons[1].send_value(LED_OFF, True) # elif self._mode_index == 1: # self._modes_buttons[0].send_value(RED_FULL, True) # self._modes_buttons[1].send_value(LED_OFF, True) # elif self._mode_index == 2: # self._modes_buttons[0].send_value(GRN_FULL, True) # self._modes_buttons[1].send_value(LED_OFF, True) # self._mixer.set_send_controls(self._encoders) # elif self._mode_index == 3: # self._modes_buttons[0].send_value(LED_OFF, True) # self._modes_buttons[1].send_value(RED_FULL, True) # self._device.set_parameter_controls(self._encoders) # self._device.set_allow_update(True) # # END update(self) FROM EncoderModeSelector.py def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = ( col, row, DRUM_PADS[row * 4 + col], PADCHANNEL, ) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note) button.name = 'Note_' + str(note) self._note_map.append(button) # CC Hold, CC Toggle shift_bank_button = ButtonElement(is_momentary, MESSAGETYPE, SHIFTBANKCHANNEL, note) shift_bank_button.name = 'Note_' + str(note) self._shift_bank_map.append(shift_bank_button) # Shift Bank shift_encoder = ButtonElement(is_momentary, 1, ENCODERSHIFTCHANNEL, note) shift_encoder.name = 'Note_' + str(note) self._shift_encoder_map.append(shift_encoder) # Shift Encoder Hold self._note_map.append( None) #add None to the end of the list, selectable with [-1] self._shift_encoder_map.append(None) self._shift_bank_map.append(None) if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for ctrl in range(128): self._ctrl_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) # Standard Encoder self._ctrl_map.append(None)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button): raise isinstance(matrix, ButtonMatrixElement) or AssertionError raise matrix.width() == 8 and matrix.height() == 8 or AssertionError raise isinstance(top_buttons, tuple) or AssertionError raise len(top_buttons) == 8 or AssertionError raise isinstance(side_buttons, tuple) or AssertionError raise len(side_buttons) == 8 or AssertionError raise isinstance(config_button, ButtonElement) or AssertionError ModeSelectorComponent.__init__(self) self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = DeprecatedSessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) return def session_component(self): return self._session def set_modes_buttons(self, buttons): raise buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes() or AssertionError identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if buttons != None: for button in buttons: raise isinstance(button, ButtonElement) or AssertionError self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) return def number_of_modes(self): return 4 def on_enabled_changed(self): self.update() def set_mode(self, mode): if not mode in range(self.number_of_modes()): raise AssertionError self._mode_index = (self._mode_index != mode or mode == 3) and mode self.update() def channel_for_current_mode(self): new_channel = self._mode_index + self._sub_modes.mode() if new_channel > 0: new_channel += 3 return new_channel def update(self): super(MainSelectorComponent, self).update() if not self._modes_buttons != None: raise AssertionError if self.is_enabled(): for index in range(len(self._modes_buttons)): self._modes_buttons[index].set_force_next_value() if index == self._mode_index: self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() for scene_index in range(8): self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = self._mode_index == 1 self._mode_index == 0 and self._setup_mixer(not as_active) self._setup_session(as_active, as_enabled) elif self._mode_index == 1: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 2: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 3: self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) else: raise False or AssertionError self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() return def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): if not isinstance(as_active, type(False)): raise AssertionError for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) as_enabled and self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) return def _setup_mixer(self, as_active): if not isinstance(as_active, type(False)): raise AssertionError as_active and self._sub_modes.is_enabled() and self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force=True) def _init_session(self): self._session.set_stop_clip_value(AMBER_THIRD) self._session.set_stop_clip_triggered_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL)
class KontrolF1(ControlSurface): __module__ = __name__ __doc__ = " Script for Native Instruments Traktor Kontrol F1 Controller " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.set_suppress_rebuild_requests(True) self._suppress_send_midi = True self._suppress_session_highlight = True self._suggested_input_port = 'Traktor Kontrol F1' self._suggested_output_port = 'Traktor Kontrol F1' self._blink_state = False self._matrix = ButtonMatrixElement() for row in range(HEIGHT): button_row = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 2, ((row * HEIGHT) + column)) for column in range(WIDTH) ] self._matrix.add_row(tuple(button_row)) self._nav_buttons = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, NAV_ENCODER), ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, TOGGLE_LEFT_DOWN) ] self._scene_buttons = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, SCENE_LAUNCH[index]) for index in range(HEIGHT) ] self._stop_buttons = [] for index in range(WIDTH): self._stop_buttons.append(ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, STOP_LAUNCH[index])) self._session = SpecialSessionComponent(self._matrix.width(), self._matrix.height()) self._all_buttons = [] for button in (self._scene_buttons + self._nav_buttons + self._stop_buttons): self._all_buttons.append(button) for scene_index in range(self._matrix.height()): for track_index in range(self._matrix.width()): self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._all_buttons = tuple(self._all_buttons) self._suppress_session_highlight = False self.set_suppress_rebuild_requests(False) self._suppress_send_midi = False self.set_enabled(True) self.update() self._set_session_highlight(0,0,WIDTH,HEIGHT,True) def disconnect(self): self._suppress_send_midi = True self._session = None for button in self._all_buttons: button.set_on_off_values(127, 0) self._matrix = None self._stop_buttons = None self._scene_buttons = None self._nav_buttons = None ControlSurface.disconnect(self) self._suppress_send_midi = False def update_display(self): tracks = self.song().visible_tracks number_tracks = len(tracks) if self._blink_state: self._blink_state = False else: self._blink_state = True for track in range(WIDTH): to = track + self._session._track_offset if (to < number_tracks): for y in range(HEIGHT): ys = self._session._scene_offset+y yx = (y*4)+track slot = tracks[to].clip_slots[ys] if (slot.controls_other_clips) or (slot.has_clip): if slot.is_triggered: if self._blink_state: self._send_midi(tuple([178,yx,40])) else: self._send_midi(tuple([178,yx,127])) def refresh_state(self): ControlSurface.refresh_state(self) def _send_midi(self, midi_bytes): if (not self._suppress_send_midi): ControlSurface._send_midi(self, midi_bytes) def _update_hardware(self): pass def _send_challenge(self): pass def _config_value(self, value): assert (value in range(128)) def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks): ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks) def _install_forwarding(self, control): result = ControlSurface._install_forwarding(self, control) return result def _translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel): ControlSurface._translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel) def on_enabled_changed(self): self.update() def update(self): for scene_index in range(HEIGHT): self._scene_buttons[scene_index].set_enabled(True) self._stop_buttons[scene_index].set_enabled(True) for track_index in range(WIDTH): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) self._session.set_allow_update(False) for scene_index in range(HEIGHT): scene = self._session.scene(scene_index) scene.set_launch_button(self._scene_buttons[scene_index]) for track_index in range(WIDTH): scene.clip_slot(track_index).set_launch_button(self._matrix.get_button(track_index, scene_index)) #self.log_message(str(tuple(self._stop_buttons))) self._session.set_stop_track_clip_buttons(tuple(self._stop_buttons)) self._session.set_track_bank_buttons(self._nav_buttons[1], self._nav_buttons[1]) self._session.set_scene_bank_buttons(self._nav_buttons[0], self._nav_buttons[0]) self._session.set_allow_update(True)
class Orsi(ControlSurface): __doc__ = " Script for FCB1010 in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in Orsi._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._note_map_scenes = [] self._note_map_buttons = [] self._ctrl_map_sliders = [] self._note_map_trk_stop_buttons = [] self._note_map_trk_sel_buttons = [] self._note_map_trk_mute_buttons = [] self._note_map_trk_solo_buttons = [] self._note_map_trk_rec_buttons = [] self._ctrl_map_trk_volume = [] self._ctrl_map_trk_pan = [] self._ctrl_map_senda = [] self._ctrl_map_sendb = [] self._ctrl_map_sendc = [] self._note_map_bank_buttons = [] self._ctrl_map_parameter = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map_scenes = None self._note_map_buttons = None self._ctrl_map_sliders = None self._note_map_trk_stop_buttons = None self._note_map_trk_sel_buttons = None self._note_map_trk_mute_buttons = None self._note_map_trk_solo_buttons = None self._note_map_trk_rec_buttons = None self._ctrl_map_trk_volume = None self._ctrl_map_trk_pan = None self._ctrl_map_senda = None self._ctrl_map_sendb = None self._ctrl_map_sendc = None self._note_map_bank_buttons = None self._ctrl_map_parameter = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in Orsi._active_instances: Orsi._active_instances.append(self) Orsi._combine_active_instances() def _do_uncombine(self): if ((self in Orsi._active_instances) and Orsi._active_instances.remove(self)): self._session.unlink() Orsi._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(TRACK_NUMBER, MATRIX_DEPTH) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map_buttons[25], self._note_map_buttons[24]) self._session.set_scene_bank_buttons(self._note_map_buttons[27], self._note_map_buttons[26]) self._session.set_select_buttons(self._note_map_buttons[34], self._note_map_buttons[35]) self._scene_launch_buttons = [ self._note_map_scenes[index] for index in range(MATRIX_DEPTH) ] self._track_stop_buttons = [ self._note_map_trk_stop_buttons[index] for index in range(TRACK_NUMBER) ] self._session.set_stop_all_clips_button(self._note_map_buttons[38]) self._session.set_stop_track_clip_buttons( tuple(self._track_stop_buttons)) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button( self._note_map_buttons[36]) self._session.set_slot_launch_button(self._note_map_buttons[37]) for scene_index in range(MATRIX_DEPTH): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(TRACK_NUMBER): if (CLIPNOTEMAP[scene_index][track_index] == -1): button = None else: button = ButtonElement( is_momentary, CLIPNOTEMAP_TYPE[scene_index][track_index], CLIPNOTEMAP_CH[scene_index][track_index], CLIPNOTEMAP[scene_index][track_index]) button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map_buttons[28], self._note_map_buttons[29], self._note_map_buttons[30], self._note_map_buttons[31]) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(TRACK_NUMBER) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button( self._note_map_buttons[39]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map_buttons[33], self._note_map_buttons[32]) self._mixer.set_crossfader_control(self._ctrl_map_sliders[2]) self._mixer.set_prehear_volume_control(self._ctrl_map_sliders[1]) self._mixer.master_strip().set_volume_control( self._ctrl_map_sliders[0]) for track in range(TRACK_NUMBER): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map_trk_rec_buttons[track]) strip.set_solo_button(self._note_map_trk_solo_buttons[track]) strip.set_mute_button(self._note_map_trk_mute_buttons[track]) strip.set_select_button(self._note_map_trk_sel_buttons[track]) strip.set_volume_control(self._ctrl_map_trk_volume[track]) strip.set_pan_control(self._ctrl_map_trk_pan[track]) strip.set_send_controls( (self._ctrl_map_senda[track], self._ctrl_map_sendb[track], self._ctrl_map_sendc[track])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(PARAMS_NUMBER): device_param_controls.append(self._ctrl_map_parameter[index]) for index in range(BANKS_NUMBER): device_bank_buttons.append(self._note_map_bank_buttons[index]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map_buttons[17]) self._device.set_bank_nav_buttons(self._note_map_buttons[20], self._note_map_buttons[21]) self._device.set_lock_button(self._note_map_buttons[16]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button( self._note_map_buttons[15]) detail_view_toggler.set_detail_toggle_button( self._note_map_buttons[14]) detail_view_toggler.set_device_nav_buttons(self._note_map_buttons[18], self._note_map_buttons[19]) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map_buttons[0]) transport.set_stop_button(self._note_map_buttons[1]) transport.set_record_button(self._note_map_buttons[2]) transport.set_nudge_buttons(self._note_map_buttons[4], self._note_map_buttons[5]) transport.set_undo_button(self._note_map_buttons[6]) transport.set_redo_button(self._note_map_buttons[7]) transport.set_tap_tempo_button(self._note_map_buttons[3]) transport.set_quant_toggle_button(self._note_map_buttons[13]) transport.set_overdub_button(self._note_map_buttons[11]) transport.set_metronome_button(self._note_map_buttons[12]) transport.set_tempo_control(self._ctrl_map_sliders[3]) transport.set_loop_button(self._note_map_buttons[8]) transport.set_seek_buttons(self._note_map_buttons[22], self._note_map_buttons[23]) transport.set_punch_buttons(self._note_map_buttons[9], self._note_map_buttons[10]) def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(PAD_Y_NUMBER): for col in range(PAD_X_NUMBER): pad = ( col, row, DRUM_PADS[row * 4 + col], PADCHANNEL, ) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True # SCENELAUNCH Buttons for scene_id in range(MATRIX_DEPTH): if (SCENELAUNCH[scene_id] == -1): button = None else: button = ButtonElement(is_momentary, SCENELAUNCH_TYPE[scene_id], SCENELAUNCH_CH[scene_id], SCENELAUNCH[scene_id]) button.name = 'Scene_' + str(scene_id) self._note_map_scenes.append(button) # BUTTON_VECTOR Buttons for button_id in range(NUMBER_BUTTONS): if (BUTTON_VECTOR[button_id] == -1): button = None else: button = ButtonElement(is_momentary, BUTTON_VECTOR_TYPE[button_id], BUTTON_VECTOR_CH[button_id], BUTTON_VECTOR[button_id]) button.name = 'Global_Button_' + str(button_id) self._note_map_buttons.append(button) # SLIDER_VECTOR Sliders for slider_id in range(NUMBER_SLIDERS): if (SLIDER_VECTOR[slider_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, SLIDER_VECTOR_CH[slider_id], SLIDER_VECTOR[slider_id]) control.name = 'Global_Slider_' + str(slider_id) self._ctrl_map_sliders.append(control) # TRACKSTOP Buttons for track_id in range(TRACK_NUMBER): if (TRACKSTOP[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKSTOP_TYPE[track_id], TRACKSTOP_CH[track_id], TRACKSTOP[track_id]) button.name = 'Trk_Stop_Button_' + str(track_id) self._note_map_trk_stop_buttons.append(button) # TRACKSEL Buttons for track_id in range(TRACK_NUMBER): if (TRACKSEL[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKSEL_TYPE[track_id], TRACKSEL_CH[track_id], TRACKSEL[track_id]) button.name = 'Trk_Sel_Button_' + str(track_id) self._note_map_trk_sel_buttons.append(button) # TRACKMUTE Buttons for track_id in range(TRACK_NUMBER): if (TRACKMUTE[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKMUTE_TYPE[track_id], TRACKMUTE_CH[track_id], TRACKMUTE[track_id]) button.name = 'Trk_Mute_Button_' + str(track_id) self._note_map_trk_mute_buttons.append(button) # TRACKSOLO Buttons for track_id in range(TRACK_NUMBER): if (TRACKSOLO[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKSOLO_TYPE[track_id], TRACKSOLO_CH[track_id], TRACKSOLO[track_id]) button.name = 'Trk_Solo_Button_' + str(track_id) self._note_map_trk_solo_buttons.append(button) # TRACKREC Buttons for track_id in range(TRACK_NUMBER): if (TRACKREC[track_id] == -1): button = None else: button = ButtonElement(is_momentary, TRACKREC_TYPE[track_id], TRACKREC_CH[track_id], TRACKREC[track_id]) button.name = 'Trk_Rec_Button_' + str(track_id) self._note_map_trk_rec_buttons.append(button) # TRACKVOL Sliders for track_id in range(TRACK_NUMBER): if (TRACKVOL[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKVOL_CH[track_id], TRACKVOL[track_id]) control.name = 'Trk_Vol_Slider_' + str(track_id) self._ctrl_map_trk_volume.append(control) # TRACKPAN Sliders for track_id in range(TRACK_NUMBER): if (TRACKPAN[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKPAN_CH[track_id], TRACKPAN[track_id]) control.name = 'Trk_Pan_Slider_' + str(track_id) self._ctrl_map_trk_pan.append(control) # TRACKSENDA Sliders for track_id in range(TRACK_NUMBER): if (TRACKSENDA[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKSENDA_CH[track_id], TRACKSENDA[track_id]) control.name = 'Trk_SendA_Slider_' + str(track_id) self._ctrl_map_senda.append(control) # TRACKSENDB Sliders for track_id in range(TRACK_NUMBER): if (TRACKSENDB[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKSENDB_CH[track_id], TRACKSENDB[track_id]) control.name = 'Trk_SendB_Slider_' + str(track_id) self._ctrl_map_sendb.append(control) # TRACKSENDC Sliders for track_id in range(TRACK_NUMBER): if (TRACKSENDC[track_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, TRACKSENDC_CH[track_id], TRACKSENDC[track_id]) control.name = 'Trk_SendC_Slider_' + str(track_id) self._ctrl_map_sendc.append(control) # DEVICEBANK Buttons for bank_id in range(BANKS_NUMBER): if (DEVICEBANK[bank_id] == -1): button = None else: button = ButtonElement(is_momentary, DEVICEBANK_TYPE[bank_id], DEVICEBANK_CH[bank_id], DEVICEBANK[bank_id]) button.name = 'Bank_Button_' + str(bank_id) self._note_map_bank_buttons.append(button) # PARAMCONTROL Sliders for param_id in range(PARAMS_NUMBER): if (PARAMCONTROL[param_id] == -1): control = None else: control = SliderElement(MIDI_CC_TYPE, PARAMCONTROL_CH[param_id], PARAMCONTROL[param_id]) control.name = 'Slider_Param_' + str(param_id) self._ctrl_map_parameter.append(control)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button, script): assert isinstance(matrix, ButtonMatrixElement) assert matrix.width() == 8 and matrix.height() == 8 assert isinstance(top_buttons, tuple) assert len(top_buttons) == 8 assert isinstance(side_buttons, tuple) assert len(side_buttons) == 8 assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._script = script self._session = SpecialSessionComponent(matrix.width(), matrix.height()) for scene in self._session._scenes: for slot in scene._clip_slots: slot._triggered_to_play_value = 24 slot._triggered_to_record_value = 27 slot._started_value = 7 slot._recording_value = 9 slot._stopped_value = 8 self._zooming = SessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._zooming._stopped_value = 9 self._zooming._playing_value = 7 self._zooming._selected_value = 8 self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def set_modes_buttons(self, buttons): assert buttons == None or isinstance( buttons, tuple) or len(buttons) == self.number_of_modes() identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if buttons != None: for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def number_of_modes(self): return 5 def on_enabled_changed(self): self.update() def set_mode(self, mode): assert (mode in range(self.number_of_modes())) if ((self._mode_index != mode) or (mode == 3)): self._mode_index = mode self.update() def channel_for_current_mode(self): new_channel = self._mode_index + self._sub_modes.mode() if new_channel > 0: new_channel += 3 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): #for index in range(len(self._modes_buttons)): # self._modes_buttons[index].set_force_next_value() # if index == self._mode_index: # self._modes_buttons[index].turn_on() # else: # self._modes_buttons[index].turn_off() for scene_index in range(8): self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = self._mode_index == 1 if (self._mode_index < 4): self._script._host._set_key_buttons(None) self._script._host.set_enabled(False) self._script._host._set_button_matrix(None) self._script._host._set_alt_button(None) self._script._host._set_shift_button(None) self._script._host._set_nav_buttons(None) for button in self._modes_buttons: button.set_on_off_values(5, 0) if self._mode_index == 0: self._setup_mixer(not as_active) self._setup_session(as_active, as_enabled) elif self._mode_index == 1: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 2: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 3: self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) elif (self._mode_index == 4): self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) self._script._host._set_button_matrix(self._matrix) self._script._host._set_key_buttons(self._side_buttons) self._script._host._set_shift_button(self._modes_buttons[0]) self._script._host._set_lock_button(self._modes_buttons[1]) self._script._host._set_alt_button(self._modes_buttons[2]) self._modes_buttons[3].send_value(9) self._script._host._set_nav_buttons(self._nav_buttons) self._script._host.set_enabled(True) else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() if (self._mode_index < 4): for index in range(len(self._modes_buttons)): if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() #self._script.request_rebuild_midi_map() self._script.schedule_message(1, self._session.update) def _update_control_channels(self): if self._mode_index < 4: new_channel = self.channel_for_current_mode() else: new_channel = 15 for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) #self._session.set_show_highlight(True) #Needs to be replaced with L9 equivalent else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) #self._session.set_show_highlight(False) #Needs to be replaced with L9 equivalent def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) as_active and self._sub_modes.is_enabled( ) and self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force_send=True) def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) """Mono Overrides and Additions""" def _mode_value(self, value, sender): assert (len(self._modes_buttons) > 0) assert isinstance(value, int) assert isinstance(sender, ButtonElement) assert (self._modes_buttons.count(sender) == 1) if self._script._host.is_enabled() != True: if ((value is not 0) or (not sender.is_momentary())): if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or ( (self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1)): if (self._script._host._active_client != None): self.set_mode(4) else: self._script.show_message( 'Monomodular Script not inserted') else: self.set_mode(self._modes_buttons.index(sender)) else: if self._modes_buttons.index(sender) == 3 and value > 0: self.set_mode(0)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button, script): assert isinstance(matrix, ButtonMatrixElement) assert matrix.width() == 8 and matrix.height() == 8 assert isinstance(top_buttons, tuple) assert len(top_buttons) == 8 assert isinstance(side_buttons, tuple) assert len(side_buttons) == 8 assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._script = script self._session = SpecialSessionComponent(matrix.width(), matrix.height()) """for scene in self._session._scenes: for slot in scene._clip_slots: slot._triggered_to_play_value = 24 slot._triggered_to_record_value = 27 slot._started_value = 7 slot._recording_value = 9 slot._stopped_value = 8""" self._zooming = SessionZoomingComponent(self._session) self._session.name = "Session_Control" self._zooming.name = "Session_Overview" """self._zooming._stopped_value = 9 self._zooming._playing_value = 7 self._zooming._selected_value = 8""" self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = "Mixer_Modes" self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) if START_IN_MOD is True: self._set_protected_mode_index(4) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def set_modes_buttons(self, buttons): assert buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes() identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if buttons != None: for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def number_of_modes(self): return 5 def on_enabled_changed(self): self.update() def set_mode(self, mode): assert mode in range(self.number_of_modes()) if (self._mode_index != mode) or (mode == 3): self._mode_index = mode self.update() def channel_for_current_mode(self): new_channel = self._mode_index + self._sub_modes.mode() if new_channel > 0: new_channel += 3 return new_channel def update(self): assert self._modes_buttons != None if self.is_enabled(): # for index in range(len(self._modes_buttons)): # self._modes_buttons[index].set_force_next_value() # if index == self._mode_index: # self._modes_buttons[index].turn_on() # else: # self._modes_buttons[index].turn_off() for scene_index in range(8): self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = self._mode_index == 1 if self._mode_index < 4: self._script._suppress_session_highlight = False self._session.set_show_highlight(True) # self._script.set_highlighting_session_component(self.session_component()) self._script._host._set_key_buttons(None) self._script._host.set_enabled(False) self._script._host._set_button_matrix(None) self._script._host._set_alt_button(None) self._script._host._set_shift_button(None) self._script._host._set_nav_buttons(None) for button in self._modes_buttons: button.set_on_off_values(127, 4) if self._mode_index == 0: self._setup_mixer(not as_active) self._setup_session(as_active, as_enabled) elif self._mode_index == 1: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 2: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 3: self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) elif self._mode_index == 4: # self._script.set_highlighting_session_component(None) self._session.set_show_highlight(False) self._script._suppress_session_highlight = True self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) self._script._host._set_button_matrix(self._matrix) self._script._host._set_key_buttons(self._side_buttons) self._script._host._set_shift_button(self._modes_buttons[0]) self._script._host._set_lock_button(self._modes_buttons[1]) self._script._host._set_alt_button(self._modes_buttons[2]) self._modes_buttons[3].send_value(9) self._script._host._set_nav_buttons(self._nav_buttons) self._script._host.set_enabled(True) else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() if self._mode_index < 4: for index in range(len(self._modes_buttons)): if index == self._mode_index: self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() # self._script.request_rebuild_midi_map() self._script.schedule_message(1, self._session.update) def _update_control_channels(self): if self._mode_index < 4: new_channel = self.channel_for_current_mode() else: new_channel = 15 for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons( self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3] ) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) # self._session.set_show_highlight(True) #Needs to be replaced with L9 equivalent else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) # self._session.set_show_highlight(False) #Needs to be replaced with L9 equivalent def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) as_active and self._sub_modes.is_enabled() and self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force=True) def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = "Scene_" + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) """Mono Overrides and Additions""" def _mode_value(self, value, sender): assert len(self._modes_buttons) > 0 assert isinstance(value, int) assert isinstance(sender, ButtonElement) assert self._modes_buttons.count(sender) == 1 if self._script._host.is_enabled() != True: if (value is not 0) or (not sender.is_momentary()): if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or ( (self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1) ): if self._script._host._active_client != None: self.set_mode(4) else: self._script.show_message("Monomodular Script not inserted") else: self.set_mode(self._modes_buttons.index(sender)) else: if self._modes_buttons.index(sender) == 3 and value > 0: self.set_mode(0)
class FCB1020(ControlSurface): __doc__ = " Script for FCB1010 in APC emulation mode " _active_instances = [] def _combine_active_instances(): track_offset = 0 scene_offset = 0 for instance in FCB1020._active_instances: instance._activate_combination_mode(track_offset, scene_offset) track_offset += instance._session.width() _combine_active_instances = staticmethod(_combine_active_instances) def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) #self.set_suppress_rebuild_requests(True) with self.component_guard(): self._note_map = [] self._ctrl_map = [] self._load_MIDI_map() self._session = None self._session_zoom = None self._mixer = None self._setup_session_control() self._setup_mixer_control() self._session.set_mixer(self._mixer) self._setup_device_and_transport_control() self.set_highlighting_session_component(self._session) #self.set_suppress_rebuild_requests(False) self._pads = [] self._load_pad_translations() self._do_combine() def disconnect(self): self._note_map = None self._ctrl_map = None self._pads = None self._do_uncombine() self._shift_button = None self._session = None self._session_zoom = None self._mixer = None ControlSurface.disconnect(self) def _do_combine(self): if self not in FCB1020._active_instances: FCB1020._active_instances.append(self) FCB1020._combine_active_instances() def _do_uncombine(self): if ((self in FCB1020._active_instances) and FCB1020._active_instances.remove(self)): self._session.unlink() FCB1020._combine_active_instances() def _activate_combination_mode(self, track_offset, scene_offset): if TRACK_OFFSET != -1: track_offset = TRACK_OFFSET if SCENE_OFFSET != -1: scene_offset = SCENE_OFFSET self._session.link_with_track_offset(track_offset, scene_offset) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(8, 5) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT]) self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP]) self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP]) self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ] self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(8) ] self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS]) self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons)) self._session.set_stop_track_clip_value(2) self._session.selected_scene().name = 'Selected_Scene' self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH]) self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH]) for scene_index in range(5): scene = self._session.scene(scene_index) scene.name = 'Scene_' + str(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_triggered_value(2) for track_index in range(8): button = self._note_map[CLIPNOTEMAP[scene_index][track_index]] button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) clip_slot.set_launch_button(button) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT]) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(8) self._mixer.name = 'Mixer' self._mixer.master_strip().name = 'Master_Channel_Strip' self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL]) self._mixer.selected_strip().name = 'Selected_Channel_Strip' self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT]) self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER]) self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL]) self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME]) for track in range(8): strip = self._mixer.channel_strip(track) strip.name = 'Channel_Strip_' + str(track) strip.set_arm_button(self._note_map[TRACKREC[track]]) strip.set_solo_button(self._note_map[TRACKSOLO[track]]) strip.set_mute_button(self._note_map[TRACKMUTE[track]]) strip.set_select_button(self._note_map[TRACKSEL[track]]) strip.set_volume_control(self._ctrl_map[TRACKVOL[track]]) strip.set_pan_control(self._ctrl_map[TRACKPAN[track]]) strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]])) strip.set_invert_mute_feedback(True) def _setup_device_and_transport_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' device_bank_buttons = [] device_param_controls = [] for index in range(8): device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]]) device_bank_buttons.append(self._note_map[DEVICEBANK[index]]) if None not in device_bank_buttons: self._device.set_bank_buttons(tuple(device_bank_buttons)) if None not in device_param_controls: self._device.set_parameter_controls(tuple(device_param_controls)) self._device.set_on_off_button(self._note_map[DEVICEONOFF]) self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT]) self._device.set_lock_button(self._note_map[DEVICELOCK]) self.set_device_component(self._device) detail_view_toggler = DetailViewControllerComponent() detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW]) detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW]) detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] ) transport = SpecialTransportComponent() transport.name = 'Transport' transport.set_play_button(self._note_map[PLAY]) transport.set_stop_button(self._note_map[STOP]) transport.set_record_button(self._note_map[REC]) transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN]) transport.set_undo_button(self._note_map[UNDO]) transport.set_redo_button(self._note_map[REDO]) transport.set_tap_tempo_button(self._note_map[TAPTEMPO]) transport.set_quant_toggle_button(self._note_map[RECQUANT]) transport.set_overdub_button(self._note_map[OVERDUB]) transport.set_metronome_button(self._note_map[METRONOME]) transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL]) transport.set_loop_button(self._note_map[LOOP]) transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD]) transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT]) ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6 def _on_selected_track_changed(self): ControlSurface._on_selected_track_changed(self) track = self.song().view.selected_track device_to_select = track.view.selected_device if device_to_select == None and len(track.devices) > 0: device_to_select = track.devices[0] if device_to_select != None: self.song().view.select_device(device_to_select) self._device_component.set_device(device_to_select) def _load_pad_translations(self): if -1 not in DRUM_PADS: pad = [] for row in range(4): for col in range(4): pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,) self._pads.append(pad) self.set_pad_translations(tuple(self._pads)) def _load_MIDI_map(self): is_momentary = True for note in range(128): button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note) button.name = 'Note_' + str(note) self._note_map.append(button) self._note_map.append(None) #add None to the end of the list, selectable with [-1] if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL: for ctrl in range(128): self._ctrl_map.append(None) else: for ctrl in range(128): control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl) control.name = 'Ctrl_' + str(ctrl) self._ctrl_map.append(control) self._ctrl_map.append(None)
class Serato(ControlSurface): def __init__(self, c_instance): publish_in_cs_list = True ControlSurface.__init__(self, c_instance, not publish_in_cs_list) self._device_selection_follows_track_selection = True with self.component_guard(): self._matrix = None self._session = None self._mixer = None self._device = None self._scene_launch_buttons = None self._track_arm_buttons = None self._track_solo_buttons = None self._track_mute_buttons = None self._track_stop_buttons = None self._track_select_buttons = None self._device_on_off_button = None self._shift_button = None self._serato_interface = PySCAClipControl() self._serato_interface.PySCA_InitializeClipControl() self._setup_session_control() self._setup_mixer_control() self._setup_device_control() self._session.set_mixer(self._mixer) self.set_highlighting_session_component(self._session) def disconnect(self): ControlSurface.disconnect(self) self._serato_interface.PySCA_DeinitializeClipControl() self._serato_interface = None def connect_script_instances(self, instanciated_scripts): """ Called by the Application as soon as all scripts are initialized. You can connect yourself to other running scripts here, as we do it connect the extension modules (MackieControlXTs). """ for control_surface in self._control_surfaces(): control_surface_session = control_surface.highlighting_session_component() if control_surface_session: self._session.sync_to(control_surface_session) self._on_track_list_changed() break def build_midi_map(self, midi_map_handle): pass def update_display(self): ControlSurface.update_display(self) while self._serato_interface.PySCA_HasIncomingEvent(): new_event = self._serato_interface.PySCA_GetIncomingEvent() if not self._handle_session_event(new_event): if not self._handle_mixer_event(new_event): if not self._handle_device_event(new_event): print 'Unhandled Event: ' + str(new_event) def _setup_session_control(self): is_momentary = True self._session = SpecialSessionComponent(NUM_TRACKS, NUM_SCENES) self._session.set_serato_interface(self._serato_interface) self._matrix = ButtonMatrixElement() self._scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_SCENES) ] self._track_stop_buttons = [ ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_TRACKS) ] stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) self._session.set_stop_all_clips_button(stop_all_button) self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons)) for scene_index in range(NUM_SCENES): scene = self._session.scene(scene_index) button_row = [] scene.set_launch_button(self._scene_launch_buttons[scene_index]) scene.set_index(scene_index) scene.set_serato_interface(self._serato_interface) for track_index in range(NUM_TRACKS): button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.set_launch_button(button) clip_slot.set_serato_interface(self._serato_interface) self._matrix.add_row(tuple(button_row)) def _setup_mixer_control(self): is_momentary = True self._mixer = SpecialMixerComponent(NUM_TRACKS) self._mixer.set_serato_interface(self._serato_interface) self._mixer.master_strip().set_serato_interface(self._serato_interface) self._track_arm_buttons = [] self._track_solo_buttons = [] self._track_mute_buttons = [] self._track_select_buttons = [] self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) for track in range(NUM_TRACKS): strip = self._mixer.channel_strip(track) strip.set_serato_interface(self._serato_interface) self._track_arm_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) self._track_solo_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) self._track_mute_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) self._track_select_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)) strip.set_arm_button(self._track_arm_buttons[-1]) strip.set_solo_button(self._track_solo_buttons[-1]) strip.set_mute_button(self._track_mute_buttons[-1]) strip.set_select_button(self._track_select_buttons[-1]) strip.set_shift_button(self._shift_button) def _setup_device_control(self): is_momentary = True self._device_on_off_button = ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0) self._device = SpecialDeviceComponent() self._device.set_serato_interface(self._serato_interface) self._device.set_parameter_controls(tuple([ SliderElement(MIDI_CC_TYPE, 0, 0) for index in range(NUM_PARAMS) ])) self._device.set_on_off_button(self._device_on_off_button) self.set_device_component(self._device) def _handle_session_event(self, event): result = False if event.type in CLIP_EVENTS: value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventClipPlayedDown) track_index = event.key1 - 1 scene_index = event.key2 - 1 if track_index in range(NUM_TRACKS) and scene_index in range(NUM_SCENES): self._matrix.get_button(track_index, scene_index).receive_value(value) result = True elif event.type in SCENE_EVENTS: value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventScenePlayedDown) scene_index = event.key1 - 1 if scene_index in range(NUM_SCENES): self._scene_launch_buttons[scene_index].receive_value(value) result = True elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixSizeChanged: new_width = event.key1 new_height = event.key2 self._session.set_size(new_width, new_height) result = True elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixOffsetChanged: x_increment = event.key1 y_increment = event.key2 self._session.move_by(x_increment, y_increment) result = True return result def _handle_mixer_event(self, event): result = True track_index = event.key1 - 1 value = event.key2 if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackMasterGainChange: self._mixer.master_strip().set_track_volume(fixed_value(value)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackStopped: self.song().stop_all_clips() elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackSelect: self.song().view.selected_track = self.song().master_track else: result = track_index in range(NUM_TRACKS) and self._handle_strip_event(event) return result def _handle_strip_event(self, event): result = True track_index = event.key1 - 1 value = event.key2 if value == 0: self._shift_button.receive_value(127) if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSolo: self._track_solo_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackRecord: self._track_arm_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackActive: self._track_mute_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackStopped: self._track_stop_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSelect: self._track_select_buttons[track_index].receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackGainChange: self._mixer.channel_strip(track_index).set_track_volume(fixed_value(value)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendAChange: self._mixer.channel_strip(track_index).set_send(0, fixed_value(value)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendBChange: self._mixer.channel_strip(track_index).set_send(1, fixed_value(value)) else: result = False self._shift_button.receive_value(0) return result def _handle_device_event(self, event): result = True if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceValueChanged: self._device.set_parameter_value(event.key1 - 1, fixed_value(event.key2)) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceActivate: self._device_on_off_button.receive_value(127) elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceFocusMove: self._move_device_focus(event.key1) else: result = False return result def _move_device_focus(self, increment): 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') else: modifier_pressed = True direction = Live.Application.Application.View.NavDirection.left if increment > 0: direction = Live.Application.Application.View.NavDirection.right self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed)
class MainSelectorComponent(ModeSelectorComponent): __module__ = __name__ __doc__ = ' Class that reassigns the button on the launchpad to different functions ' def __init__(self, matrix, top_buttons, side_buttons, config_button, script): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._script = script self._session = SpecialSessionComponent(matrix.width(), matrix.height()) for scene in self._session._scenes: for slot in scene._clip_slots: slot._triggered_to_play_value = 24 slot._triggered_to_record_value = 27 slot._started_value = 7 slot._recording_value = 9 slot._stopped_value = 8 self._zooming = SessionZoomingComponent(self._session) self._zooming._stopped_value = 9 self._zooming._playing_value = 7 self._zooming._selected_value = 8 self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in (self._side_buttons + self._nav_buttons): self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def set_modes_buttons(self, buttons): assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == self.number_of_modes() + 1))) identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if (buttons != None): for button in buttons: assert isinstance(button, ButtonElement) self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def _mode_value(self, value, sender): assert (len(self._modes_buttons) > 0) assert isinstance(value, int) assert isinstance(sender, ButtonElement) assert (self._modes_buttons.count(sender) == 1) if self._script._host.is_enabled() != True: if ((value is not 0) or (not sender.is_momentary())): if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or ((self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1)): if(self._script._host._active_client != None): self.set_mode(4) else: self._script.show_message('Monomodular Script not inserted') else: self.set_mode(self._modes_buttons.index(sender)) else: if self._modes_buttons.index(sender) == 3 and value > 0: self.set_mode(0) def number_of_modes(self): return 5 def on_enabled_changed(self): self.update() def set_mode(self, mode): assert (mode in range(self.number_of_modes())) if ((self._mode_index != mode) or (mode == 3)): self._mode_index = mode self.update() def update(self): assert (self._modes_buttons != None) if self.is_enabled(): for scene_index in range(8): self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = (self._mode_index == 1) if (self._mode_index < 4): self._script._host._set_key_buttons(None) self._script._host.set_enabled(False) self._script._host._set_button_matrix(None) self._script._host._set_alt_button(None) self._script._host._set_shift_button(None) self._script._host._set_nav_buttons(None) for button in self._modes_buttons: button.set_on_off_values(5, 0) if (self._mode_index == 0): self._setup_mixer((not as_active)) self._setup_session(as_active, as_enabled) elif (self._mode_index == 1): self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) elif (self._mode_index == 2): self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) elif (self._mode_index == 3): self._setup_session((not as_active), as_enabled) self._setup_mixer(as_active) elif (self._mode_index == 4): self._setup_session((not as_active), (not as_enabled)) self._setup_mixer((not as_active)) self._setup_user(release_buttons) self._script._host._set_button_matrix(self._matrix) self._script._host._set_key_buttons(self._side_buttons) self._script._host._set_shift_button(self._modes_buttons[0]) self._script._host._set_lock_button(self._modes_buttons[1]) self._script._host._set_alt_button(self._modes_buttons[2]) self._modes_buttons[3].send_value(9) self._script._host._set_nav_buttons(self._nav_buttons) self._script._host.set_enabled(True) else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() if(self._mode_index < 4): for index in range(len(self._modes_buttons)): if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() #self._script.request_rebuild_midi_map() self._script.schedule_message(1, self._session.update) def _update_control_channels(self): if self._mode_index < 4: new_channel = (self._mode_index + self._sub_modes.mode()) if (new_channel > 0): new_channel += 3 else: new_channel = 15 for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) self._session.set_show_highlight(True) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._session.set_show_highlight(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled((not release_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_buttons)) self._config_button.send_value(32) if release_buttons: self._config_button.send_value(2) def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button, parent): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._parent = parent self._compact = False self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = SessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self) self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons,self) self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self) self._init_session() self._all_buttons = tuple(self._all_buttons) self._mode_index=0 self._previous_mode_index=-1 self._sub_mode_index=[0,0,0,0] for index in range(4): self._sub_mode_index[index]=0 self.set_mode_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] assert mode in range(self.number_of_modes()) if self._mode_index==mode: if self._mode_index==1: #user mode 1 and device controller and instrument mode self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index]+1)%3 self.update() elif self._mode_index==2: #user mode 2 and step sequencer self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index]+1)%2 self.update() elif self._mode_index==3: self.update() else: self._sub_mode_index[self._mode_index] = 0 self._previous_mode_index=self._mode_index else: self._mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] #if ((self._mode_index != mode) or (mode == 3) or True): #self._mode_index = mode #self._update_mode() # self.update() def number_of_modes(self): return 4 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): for index in range(4): if(self._sub_mode_index[index]==0): self._modes_buttons[index].set_on_off_values(AMBER_FULL,AMBER_THIRD) if(self._sub_mode_index[index]==1): self._modes_buttons[index].set_on_off_values(GREEN_FULL,GREEN_THIRD) if(self._sub_mode_index[index]==2): self._modes_buttons[index].set_on_off_values(RED_FULL,RED_THIRD) if (index == self._mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def channel_for_current_mode(self): if self._compact: if self._mode_index==0: new_channel = 2 #session elif self._mode_index==1: if self._sub_mode_index[self._mode_index]==0: new_channel = 2 #instrument controller 11,12,13,14 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_index[self._mode_index]==1: new_channel = 2 #device controler else : new_channel = 0 #plain user mode 1 elif self._mode_index==2: if self._sub_mode_index[self._mode_index]==0: new_channel = 1 #user 2 else: new_channel = 2 + self._sub_mode_index[self._mode_index] #step seq 2,3 elif self._mode_index==3: #mixer modes new_channel = 2 + self._sub_modes.mode() # 2,3,4,5,6 else: if self._mode_index==0: new_channel = 0 #session elif self._mode_index==1: if self._sub_mode_index[self._mode_index]==0: new_channel = 11 #instrument controller 11,12,13,14 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_index[self._mode_index]==1: new_channel = 3 #device controler else : new_channel = 4 #plain user mode 1 elif self._mode_index==2: if self._sub_mode_index[self._mode_index]==0: new_channel = 5 #user 2 else: new_channel = 1 + self._sub_mode_index[self._mode_index] #step seq 1,2 elif self._mode_index==3: #mixer modes new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) if (self._mode_index == 0): #session self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() elif (self._mode_index == 1): self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_mixer(not as_active) #user mode + device controller + instrument controller if (self._sub_mode_index[self._mode_index]==0): self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) elif (self._sub_mode_index[self._mode_index]==1): self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() else: self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() elif (self._mode_index == 2): self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) if (self._sub_mode_index[self._mode_index]==0): self._setup_step_sequencer(not as_active) self._setup_user_mode(False, False, False, False) else: self._setup_step_sequencer(as_active, self._sub_mode_index[self._mode_index]) self._update_control_channels() elif (self._mode_index == 3): self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() else: assert False self._previous_mode_index=self._mode_index self._session.set_allow_update(True) self._zooming.set_allow_update(True) def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) #matrix for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: self._activate_matrix(True) scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) #zoom if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) #nav buttons if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, enabled): if self._instrument_controller != None: if enabled: self._activate_matrix(False) self._activate_scene_buttons(True) self._activate_navigation_buttons(True) else: for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.use_default_message() scene_button.force_next_send() for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.use_default_message() button.force_next_send() self._instrument_controller.set_enabled(enabled) def _setup_device_controller(self, as_active): if self._device_controller!=None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons = True, drum_rack_mode = True): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if drum_rack_mode: self._config_button.send_value(2) self._config_button.send_value(32) def _setup_step_sequencer(self, as_active, mode=0): if(self._stepseq!=None): if(self._stepseq.is_enabled()!=as_active or self._stepseq._mode!=mode): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if(self._sub_modes.is_enabled()): #go back to default mode self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _init_session(self): self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.set_record_button_value(RED_THIRD) clip_slot.set_clip_palette(CLIP_COLOR_TABLE) #clip_slot.set_clip_rgb_table(RGB_COLOR_TABLE) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) def _activate_navigation_buttons(self,active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self,active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self,active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._parent.log_message(msg) #Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value()
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button): raise isinstance(matrix, ButtonMatrixElement) or AssertionError raise matrix.width() == 8 and matrix.height() == 8 or AssertionError raise isinstance(top_buttons, tuple) or AssertionError raise len(top_buttons) == 8 or AssertionError raise isinstance(side_buttons, tuple) or AssertionError raise len(side_buttons) == 8 or AssertionError raise isinstance(config_button, ButtonElement) or AssertionError ModeSelectorComponent.__init__(self) self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = DeprecatedSessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def set_modes_buttons(self, buttons): raise buttons == None or isinstance( buttons, tuple) or len(buttons) == self.number_of_modes() or AssertionError identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if buttons != None: for button in buttons: raise isinstance(button, ButtonElement) or AssertionError self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def number_of_modes(self): return 4 def on_enabled_changed(self): self.update() def set_mode(self, mode): if not mode in range(self.number_of_modes()): raise AssertionError self._mode_index = (self._mode_index != mode or mode == 3) and mode self.update() def channel_for_current_mode(self): new_channel = self._mode_index + self._sub_modes.mode() if new_channel > 0: new_channel += 3 return new_channel def update(self): super(MainSelectorComponent, self).update() if not self._modes_buttons != None: raise AssertionError if self.is_enabled(): for index in range(len(self._modes_buttons)): self._modes_buttons[index].set_force_next_value() if index == self._mode_index: self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() for scene_index in range(8): self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = self._mode_index == 1 self._mode_index == 0 and self._setup_mixer(not as_active) self._setup_session(as_active, as_enabled) elif self._mode_index == 1: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 2: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 3: self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) else: raise False or AssertionError self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): if not isinstance(as_active, type(False)): raise AssertionError for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button( track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) as_enabled and self._session.set_track_bank_buttons( self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_mixer(self, as_active): if not isinstance(as_active, type(False)): raise AssertionError as_active and self._sub_modes.is_enabled( ) and self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force=True) def _init_session(self): self._session.set_stop_clip_value(AMBER_THIRD) self._session.set_stop_clip_triggered_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL)
class MF3D_Color_Clip(ControlSurface): __doc__ = " Script for Mad Zach's Weekly soundpacks " _active_instances = [] def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method. self.set_suppress_rebuild_requests(True) self._session = None self._session_zoom = None self._last_tr_off = 0 self._last_sc_off = 1 self._setup_session_control() self.set_suppress_rebuild_requests(False) def disconnect(self): self._session = None self._session_zoom = None self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log closed =--------------") # Writes message into Live's main log file. This is a ControlSurface method. ControlSurface.disconnect(self) def _setup_session_control(self): is_momentary = True self._device = DeviceComponent() self._device.name = 'Device_Component' self._session = SpecialSessionComponent(4, 4) self._session.name = 'Session_Control' self._session.set_track_bank_buttons(self._set_button(BUTTONCHANNEL+1, SESSIONRIGHT),self._set_button(BUTTONCHANNEL+1, SESSIONLEFT)) self._session.set_scene_bank_buttons(self._set_button(BUTTONCHANNEL+1, SESSIONDOWN),self._set_button(BUTTONCHANNEL+1, SESSIONUP)) self._session_zoom = SpecialZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_nav_buttons(self._set_button(BUTTONCHANNEL+1, ZOOMUP), self._set_button(BUTTONCHANNEL+1, ZOOMDOWN), self._set_button(BUTTONCHANNEL+1, ZOOMLEFT), self._set_button(BUTTONCHANNEL+1, ZOOMRIGHT)) tracks = self.getslots() #get clip slots to access clip colors for scene_index in range(4): scene_off=self._session._scene_offset scene = self._session.scene(scene_index+scene_off) scene.name = 'Scene_' + str(scene_index+scene_off) button_row = [] for track_index in range(4): button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF) button_row.append(button) clip_slot = scene.clip_slot(track_index) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index+scene_off) clip_slot.set_launch_button(button) c = tracks[track_index][scene_index+scene_off] #get clip for color clip_slot.set_stopped_value(LOWYELLOW) if c.clip != None: cval=self._get_MF3D_color(self.int_to_rgb(c.clip.color)) self.log_message("Clip: tr: " + str(track_index) + " clip: " + str(scene_index+scene_off) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval)) clip_slot.set_stopped_value(cval) ## clip_slot.set_triggered_to_launch_value(1) clip_slot.set_triggered_to_play_value(PLAYTRIG_COL) clip_slot.set_started_value(TRIGD_COL) clip_slot.set_triggered_to_record_value(RECTRIG_COL) clip_slot.set_recording_value(RECD_COL) def int_to_rgb(self,rgbint): return (rgbint/256/256%256, rgbint/256%256,rgbint%256) def getslots(self): tracks = self.song().visible_tracks clipSlots = [] for track in tracks: clipSlots.append(track.clip_slots) return clipSlots def _set_button(self,_channel,_note,_on_color=118,_off_color=0): _button=None; if not _note is -1: _button = ConfigurableButtonElement(True, MESSAGETYPE, _channel, _note,_on_color,_off_color) return _button def _set_colors(self, scene_dir): tracks = self.getslots() #get clip slots to access clip colors scene_off=self._session.scene_offset() track_off=self._session.track_offset() for scene_index in range(4): sc=scene_index scene = self._session.scene(sc) self.log_message("scene offset + index " + str(scene_index)) scene.name = 'Scene_' + str(scene_index) button_row = [] for track_index in range(4): #button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF) #button_row.append(button) tr=track_index clip_slot = scene.clip_slot(tr) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) #clip_slot.set_launch_button(button) c = tracks[track_index][scene_index+scene_off+scene_dir] #get clip for color clip_slot.set_stopped_value(LOWYELLOW) if c.clip != None: cval=self._get_MF3D_color(self.int_to_rgb(c.clip.color)) clip_slot.set_stopped_value(cval) self.log_message("Clip: tr: " + str(track_index) + " clip: " + str(scene_index) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval)) def update_display(self): ControlSurface.update_display(self) scene_off=self._session.scene_offset() track_off=self._session.track_offset() if (scene_off>self._last_sc_off): self.log_message("vooce"+ str(self._session._track_offset)+ " " +str(self._session._scene_offset)) self._set_colors(1) self._last_tr_off = track_off self._last_sc_off = scene_off if (scene_off<self._last_sc_off): self.log_message("vooce"+ str(self._session._track_offset)+ " " +str(self._session._scene_offset)) self._set_colors(-1) self._last_tr_off = track_off self._last_sc_off = scene_off def _get_MF3D_color(self, colors): red = colors[0] green = colors[1] blue = colors[2] color_table=((255,0,0,RED),(125,0,0,LOWRED),(255,127,0,ORANGE),(127,64,0,LOWORANGE), (255,255,0,YELLOW),(127,127,0,LOWYELLOW),(127,255,0,CHARTREUSSE),(64,127,0,LOWCHARTREUSSE), (0,255,0,GREEN),(0,127,0,LOWGREEN),(0,255,255,CYAN),(0,127,127,LOWCYAN), (0,0,255,BLUE),(0,0,127,LOWBLUE),(0,255,127,PURPLE),(0,127,64,LOWPURPLE), (0,255,255,PINK),(0,127,127,LOWPINK),(255,255,255,WHITE)) min_dist=9999999 color_node=(0,0,0,119) for index in range(len(color_table)): if (min_dist>self._get_distance(colors,color_table[index])): min_dist=self._get_distance(colors,color_table[index]) #self.log_message("colors " + str(color_node) + " and " + str(color_table[index])) color_node=color_table[index] #self.log_message("red " + str(red) + " green " + str(green) + " blue " + str(blue) + " distance to" + str(color_node[3]) + " :: " + str(self._get_distance(colors,color_node))) return color_node[3] def _get_distance(self,color1,color2): r1=color1[0] g1=color1[1] b1=color1[2] r2=color2[0] g2=color2[1] b2=color2[2] #self.log_message("got " + str(color1) + " and " + str(color2)) return (abs((r1-r2))+abs((g1-g2))+abs((b1-b2)))
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ #def log(self, message): # self._control_surface.log_message((' ' + message + ' ').center(50, '=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface): #verify matrix dimentions assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) #super constructor #inject ControlSurface and OSD components (M4L) self._osd = osd self._control_surface = control_surface #initialize index variables self._mode_index = 0 #Inherited from parent self._main_mode_index = 0 #LP original modes self._sub_mode_list = [0, 0, 0, 0] for index in range(4): self._sub_mode_list[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS: #session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append( matrix.get_button(column, matrix.height() - 1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height() - 1, clip_stop_buttons, self._control_surface, self) else: #no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self) #initialize _session variables self._session.set_osd(self._osd) self._session.name = 'Session_Control' #initialize _zooming variables self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning=True) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value("Default.Button.Off") self._matrix = matrix self._side_buttons = side_buttons #launch buttons self._nav_buttons = top_buttons[:4] #arrow buttons self._config_button = config_button #used to reset launchpad self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) #User2 stepSequencer (Drum & Melodic) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq.set_osd(self._osd) #User2 stepSequencer (Retro style) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq2.set_osd(self._osd) #User1 Instrument controller (Scale) self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._instrument_controller.set_osd(self._osd) #self._instrument_controller = None #User1 Device controller (Fx or Instrument parameters) self._device_controller = DeviceComponent( control_surface=self._control_surface, matrix=self._matrix, side_buttons=self._side_buttons, top_buttons=self._nav_buttons) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][ 0] #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer) assert mode in range(self.number_of_modes()) # 8 for this script if self._main_mode_index == mode: if self._main_mode_index == 1: #user mode 1 and device controller and instrument mode self._sub_mode_list[self._main_mode_index] = ( self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 2: #user mode 2 and step sequencer self._sub_mode_list[self._main_mode_index] = ( self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 3: #Mixer mode self.update() else: #Session mode self._sub_mode_list[self._main_mode_index] = 0 self._mode_index = 0 else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self.__main_mode_index != mode) or (mode == 3) or True): # self._main_mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 1 + 3 + 3 + 1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): self._modes_buttons[0].set_on_off_values("Mode.Session.On", "Mode.Session.Off") self._modes_buttons[3].set_on_off_values("Mode.Mixer.On", "Mode.Mixer.Off") mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]]) mode2 = self.getSkinName(Settings.USER_MODES[3 + self._sub_mode_list[2]]) self._modes_buttons[1].set_on_off_values("Mode." + mode1 + ".On", "Mode." + mode1 + ".Off") self._modes_buttons[2].set_on_off_values("Mode." + mode2 + ".On", "Mode." + mode2 + ".Off") for index in range(4): if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def getSkinName(self, user2Mode): if user2Mode == "instrument": user2Mode = "Note" if user2Mode == "device": user2Mode = "Device" if user2Mode == "user 1": user2Mode = "User" if user2Mode == "user 2": user2Mode = "User2" if user2Mode == "drum stepseq": user2Mode = "StepSequencer" if user2Mode == "melodic stepseq": user2Mode = "StepSequencer2" return user2Mode def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index == 0: new_channel = 0 # session elif self._main_mode_index == 1: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 11 # instrument controller # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 3 # device controller elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 4 # plain user mode 1 elif self._main_mode_index == 2: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 1 # step seq elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 2 # melodic step seq elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 5 # plain user mode 2 elif self._main_mode_index == 3: # mixer modes # mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value( 40) #Set LP double buffering mode (investigate this) self._config_button.send_value( 1) #Set LP X-Y layout grid mapping mode if self._main_mode_index == 0: # session self._control_surface.show_message("SESSION MODE") self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() self._mode_index = 0 elif self._main_mode_index == 1 or self._main_mode_index == 2: self._setup_sub_mode(Settings.USER_MODES[ (self._main_mode_index - 1) * 3 + self._sub_mode_list[self._main_mode_index]]) elif self._main_mode_index == 3: # mixer self._control_surface.show_message("MIXER MODE") self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() self._mode_index = 3 else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) def _setup_sub_mode(self, mode): as_active = True as_enabled = True if mode == "instrument": self._control_surface.show_message("INSTRUMENT MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) self._mode_index = 4 elif mode == "melodic stepseq": self._control_surface.show_message("MELODIC SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) self._update_control_channels() self._mode_index = 7 elif mode == "user 1": self._control_surface.show_message("USER 1 MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() self._mode_index = 1 self._osd.clear() self._osd.mode = "User 1" self._osd.update() elif mode == "drum stepseq": self._control_surface.show_message("DRUM STEP SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) self._update_control_channels() self._mode_index = 6 elif mode == "device": self._control_surface.show_message("DEVICE CONTROLLER MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() self._mode_index = 5 elif mode == "user 2": self._control_surface.show_message("USER 2 MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() self._mode_index = 2 self._osd.clear() self._osd.mode = "User 2" self._osd.update() def _setup_session(self, as_active, as_navigation_enabled): assert isinstance(as_active, type(False)) #assert is boolean for button in self._nav_buttons: if as_navigation_enabled: button.set_on_off_values("Mode.Session.On", "Mode.Session.Off") else: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") # matrix self._activate_matrix(True) for scene_index in range( self._session._num_scenes): #iterate over scenes scene = self._session.scene(scene_index) if as_active: #set scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range( self._session._num_tracks ): #iterate over tracks of a scene -> clip slots if as_active: #set clip slot launch button button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: #Set up stop clip buttons and stop all clips button if self._session._stop_clip_buttons != None: for button in self._session._stop_clip_buttons: button.set_enabled(as_active) # button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_track_clip_buttons( self._session._stop_clip_buttons) self._side_buttons[self._session._num_scenes].set_enabled( as_active) self._side_buttons[ self._session._num_scenes].set_on_off_values( "Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_all_clips_button( self._side_buttons[self._session._num_scenes]) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) if as_active: # zoom self._zooming.set_zoom_button( self._modes_buttons[0] ) # Set Session button as zoom shift button self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_navigation_enabled: # nav buttons (track/scene) self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, as_active): if self._instrument_controller != None: if as_active: self._activate_matrix( False) #Disable matrix buttons (clip slots) self._activate_scene_buttons(True) #Enable side buttons self._activate_navigation_buttons(True) #Enable nav buttons else: for scene_index in range( 8 ): #Restore all matrix buttons and scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.use_default_message( ) # Reset to original channel scene_button.force_next_send() #Flush for track_index in range(8): button = self._matrix.get_button( track_index, scene_index) button.use_default_message( ) # Reset to original channel button.force_next_send() #Flush self._instrument_controller.set_enabled( as_active) #Enable/disable instrument controller def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True): # user1 -> All True but release_nav_buttons / user2 -> All false for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled( (not release_side_buttons)) #User2 enabled for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled((not release_matrix)) #User2 enabled for button in self._nav_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled( (not release_nav_buttons)) #User1 & User2 enabled if drum_rack_mode: #User1 enabled self._config_button.send_value( 2) #Set LP drum rack layout grid mapping mode self._config_button.send_value( 32) #Send enable flashing led config message to LP def _setup_step_sequencer(self, as_active): if (self._stepseq != None): #if(self._stepseq.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if (self._stepseq2 != None): #if(self._stepseq2.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if (self._sub_modes.is_enabled()): # go back to default mode self._sub_modes.set_mode(-1) else: self._sub_modes.release_controls() self._sub_modes.set_enabled(as_active) def _init_session(self): #self._session.set_stop_clip_value("Session.StopClip") #self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop") session_height = self._matrix.height() if self._session._stop_clip_buttons != None: session_height = self._matrix.height() - 1 for scene_index in range(session_height): # scene = self._session.scene(scene_index) # scene.set_triggered_value("Session.SceneTriggered") # scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): # clip_slot = scene.clip_slot(track_index) # clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay") # clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord") # clip_slot.set_stopped_value("Session.ClipStopped") # clip_slot.set_started_value("Session.ClipStarted") # clip_slot.set_recording_value("Session.ClipRecording") # clip_slot.set_record_button_value("Session.RecordButton") # clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) #self._zooming.set_stopped_value("Zooming.Stopped") #self._zooming.set_selected_value("Zooming.Selected") #self._zooming.set_playing_value("Zooming.Playing") def _activate_navigation_buttons(self, active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self, active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self, active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._control_surface.log_message(msg) # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.force_next_send()
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def log(self, message): self._parent.log_message((' ' + message + ' ').center(50, '=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, parent, skin): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._skin = skin self._osd = osd self._parent = parent self._mode_index = 0 self._previous_mode_index = -1 self._main_mode_index = 0 self._sub_mode_index = [0, 0, 0, 0] for index in range(4): self._sub_mode_index[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS: #session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self, self._skin) else: #no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self, self._skin) self._session.set_osd(self._osd) self._session.name = 'Session_Control' self._zooming = DeprecatedSessionZoomingComponent(self._session) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value(self._skin.off) self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, skin) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin) self._stepseq.set_osd(self._osd) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self, skin) self._stepseq2.set_osd(self._osd) self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin) self._instrument_controller.set_osd(self._osd) self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, self._skin.off) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] assert mode in range(self.number_of_modes()) if self._main_mode_index == mode: if self._main_mode_index == 1: # user mode 1 and device controller and instrument mode self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 2: # user mode 2 and step sequencer self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 3: self.update() else: self._sub_mode_index[self._main_mode_index] = 0 self._mode_index = 0 self._previous_mode_index = self._main_mode_index else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self.__main_mode_index != mode) or (mode == 3) or True): # self._main_mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 1 + 3 + 3 + 1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): for index in range(4): if(self._sub_mode_index[index] == 0): self._modes_buttons[index].set_on_off_values(self._skin.AMBER_FULL, self._skin.AMBER_THIRD) if(self._sub_mode_index[index] == 1): self._modes_buttons[index].set_on_off_values(self._skin.GREEN_FULL, self._skin.GREEN_THIRD) if(self._sub_mode_index[index] == 2): self._modes_buttons[index].set_on_off_values(self._skin.RED_FULL, self._skin.RED_THIRD) if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index == 0: new_channel = 0 # session elif self._main_mode_index == 1: if self._sub_mode_index[self._main_mode_index] == 0: new_channel = 11 # instrument controller # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_index[self._main_mode_index] == 1: new_channel = 3 # device controller elif self._sub_mode_index[self._main_mode_index] == 2: new_channel = 4 # plain user mode 1 elif self._main_mode_index == 2: if self._sub_mode_index[self._main_mode_index] == 0: new_channel = 1 # step seq elif self._sub_mode_index[self._main_mode_index] == 1: new_channel = 2 # melodic step seq elif self._sub_mode_index[self._main_mode_index] == 2: new_channel = 5 # plain user mode 2 elif self._main_mode_index == 3: # mixer modes # mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) if self._main_mode_index == 0: # session self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() self._mode_index = 0 elif self._main_mode_index == 1 or self._main_mode_index == 2: self._setup_usermode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_index[self._main_mode_index] ] ) #if self._sub_mode_index[self._main_mode_index] == 0: # self._setup_usermode(Settings.USER_MODES[0]) #elif self._sub_mode_index[self._main_mode_index] == 1: # self._setup_usermode(Settings.USER_MODES[1]) #else: # self._setup_usermode(Settings.USER_MODES[2]) #elif self._main_mode_index == 2: # if self._sub_mode_index[self._main_mode_index] == 0: # self._setup_usermode(Settings.USER_MODES[3]) # elif self._sub_mode_index[self._main_mode_index] == 1: # self._setup_usermode(Setting.USER_MODES[4]) # else: # self._setup_usermode(Settings.USER_MODES[5]) elif self._main_mode_index == 3: # mixer self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() self._mode_index = 3 else: assert False self._previous_mode_index = self._main_mode_index self._session.set_allow_update(True) self._zooming.set_allow_update(True) #self.log_message("main selector update") #for line in traceback.format_stack(): # self.log_message(line.strip()) def _setup_usermode(self, mode): as_active = True as_enabled = True if mode == "instrument": self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) self._mode_index = 4 elif mode == "melodic stepseq": self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) self._update_control_channels() self._mode_index = 7 elif mode == "user 1": self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() self._mode_index = 1 self._osd.clear() self._osd.mode = "User 1" self._osd.update() elif mode == "drum stepseq": self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) self._update_control_channels() self._mode_index = 6 elif mode == "device": self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() self._mode_index = 5 elif mode == "user 2": self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() self._mode_index = 2 self._osd.clear() self._osd.mode = "User 2" self._osd.update() def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(self._skin.GREEN_FULL, self._skin.GREEN_THIRD) else: button.set_on_off_values(127, self._skin.off) # matrix self._activate_matrix(True) for scene_index in range(self._session._num_scenes): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values(127, self._skin.off) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(self._session._num_tracks): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, self._skin.off) button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: if self._session._stop_clip_buttons != None: for button in self._session._stop_clip_buttons: button.set_enabled(as_active) button.set_on_off_values(self._skin.session.track_stop, self._skin.off) self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons) self._side_buttons[self._session._num_scenes].set_enabled(as_active) self._side_buttons[self._session._num_scenes].set_on_off_values(self._skin.session._stop_clip_buttons, self._skin.off) self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes]) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) # zoom if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) # nav buttons if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, enabled): if self._instrument_controller != None: if enabled: self._activate_matrix(False) self._activate_scene_buttons(True) self._activate_navigation_buttons(True) else: for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.use_default_message() scene_button.force_next_send() for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.use_default_message() button.force_next_send() self._instrument_controller.set_enabled(enabled) def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, self._skin.off) scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, self._skin.off) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: button.set_on_off_values(127, self._skin.off) button.turn_off() button.set_enabled((not release_nav_buttons)) if drum_rack_mode: self._config_button.send_value(2) self._config_button.send_value(32) def _setup_step_sequencer(self, as_active): if(self._stepseq != None): #if(self._stepseq.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if(self._stepseq2 != None): #if(self._stepseq2.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if(self._sub_modes.is_enabled()): # go back to default mode self._sub_modes.set_mode(-1) else: self._sub_modes.release_controls() self._sub_modes.set_enabled(as_active) def _init_session(self): major = self._parent._live_major_version minor = self._parent._live_minor_version bugfix = self._parent._live_bugfix_version if (major >= 9 and minor > 1) or (major >= 9 and minor >= 1 and bugfix >= 2): # api changed in 9.1.2 self._session.set_stop_clip_value(self._skin.session.track_stop) self._session.set_stop_clip_triggered_value(self._skin.session.clip_triggered_to_stop) else: # api for 9.1.1 below self._session.set_stop_track_clip_value(self._skin.session.clip_triggered_to_stop) #if self._mk2: # self._session.set_rgb_mode(self._skin.CLIP_COLOR_TABLE, self._skin.RGB_COLOR_TABLE) session_height = self._matrix.height() if self._session._stop_clip_buttons != None: session_height = self._matrix.height()-1 for scene_index in range(session_height): scene = self._session.scene(scene_index) scene.set_triggered_value(self._skin.session.scene_triggered) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(self._skin.session.clip_triggered_to_play) clip_slot.set_triggered_to_record_value(self._skin.session.clip_triggered_to_record) clip_slot.set_stopped_value(self._skin.session.clip_stopped) clip_slot.set_started_value(self._skin.session.clip_playing) clip_slot.set_recording_value(self._skin.session.clip_recording) clip_slot.set_record_button_value(self._skin.session.clip_record) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(self._skin.RED_FULL) self._zooming.set_selected_value(self._skin.AMBER_FULL) self._zooming.set_playing_value(self._skin.GREEN_FULL) def _activate_navigation_buttons(self, active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self, active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self, active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._parent.log_message(msg) # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value()
class MainSelectorComponent(ModeSelectorComponent,Launchpad95M4LInterfaceMixin): """ Class that reassigns the button on the launchpad to different functions """ def log(self, message): self._parent.log_message((' '+message+' ').center(50,'=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, parent): assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) self._m4lmode_index = 0 self.init_m4l_interface() self._attributes = [ '-' for _ in range(8) ] self._attribute_names = [ '-' for _ in range(8) ] self._info = [' ', ' '] self._map_name = MAP_NAMES[self._m4lmode_index] self._parent = parent self._compact = False self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = SessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self) self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons,self) self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self) self._init_session() self._all_buttons = tuple(self._all_buttons) self._mode_index=0 self._previous_mode_index=-1 self._main_mode_index=0 self._sub_mode_index=[0,0,0,0] for index in range(4): self._sub_mode_index[index]=0 self.set_mode_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def set_m4lmode(self,mode_str): #self.log(mode_str) if mode_str == 'SCALE': self._m4lmode_index = 8 elif mode_str == 'QUICK_SCALE': self._m4lmode_index = 9 elif mode_str == 'MULTINOTE': self._m4lmode_index = 10 elif mode_str == 'INST': self._m4lmode_index = 1 elif mode_str == 'STEP': self._m4lmode_index = 4 self.refresh_map_display() @property def mode_name(self): """ Returns the name of the current mode. """ #self.log(MODE_NAMES[self._m4lmode_index]) return MODE_NAMES[self._m4lmode_index] @property def mode_attributes(self): """ Returns the attributes of the current mode. """ #self.log(self._attributes) return self._attributes @property def mode_attribute_names(self): """ Returns the names of the attributes of the current mode. """ #self.log(self._attributes_names) return self._attribute_names @property def mode_info(self): """ Returns info about the current mode. """ #self.log(self._info) return self._info @property def mode_map(self): """ Returns the name of the relevant map for the current mode. """ #self.log(MAP_NAMES[self._m4lmode_index]) return MAP_NAMES[self._m4lmode_index] def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] assert mode in range(self.number_of_modes()) if self._main_mode_index==mode: if self._main_mode_index==1: #user mode 1 and device controller and instrument mode self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index]+1)%3 self.update() elif self._main_mode_index==2: #user mode 2 and step sequencer self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index]+1)%3 self.update() elif self._main_mode_index==3: self.update() else: self._sub_mode_index[self._main_mode_index] = 0 self._mode_index = 0 self._previous_mode_index=self._main_mode_index else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] self._compute_mode_index() #if ((self.__main_mode_index != mode) or (mode == 3) or True): #self._main_mode_index = mode #self._update_mode() # self.update() def number_of_modes(self): return 1+3+3+1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): for index in range(4): if(self._sub_mode_index[index]==0): self._modes_buttons[index].set_on_off_values(AMBER_FULL,AMBER_THIRD) if(self._sub_mode_index[index]==1): self._modes_buttons[index].set_on_off_values(GREEN_FULL,GREEN_THIRD) if(self._sub_mode_index[index]==2): self._modes_buttons[index].set_on_off_values(RED_FULL,RED_THIRD) if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index==0: new_channel = 0 # session elif self._main_mode_index==1: if self._sub_mode_index[self._main_mode_index]==0: new_channel = 11 # instrument controller #instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_index[self._main_mode_index]==1: new_channel = 3 #device controller elif self._sub_mode_index[self._main_mode_index]==2: new_channel = 4 #plain user mode 1 elif self._main_mode_index==2: if self._sub_mode_index[self._main_mode_index]==0: new_channel = 1 #step seq elif self._sub_mode_index[self._main_mode_index]==1: new_channel = 2 #melodic step seq elif self._sub_mode_index[self._main_mode_index]==2: new_channel = 5 #plain user mode 2 elif self._main_mode_index==3: #mixer modes #mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def _compute_mode_index(self): if self._main_mode_index == 0: #session self._mode_index = 0 elif self._main_mode_index == 1: if self._sub_mode_index[self._main_mode_index]==0: #instrument controller self._mode_index = 4 elif self._sub_mode_index[self._main_mode_index]==1: #device controller self._mode_index = 5 else: #plain user mode 1 self._mode_index = 1 elif self._main_mode_index == 2: if self._sub_mode_index[self._main_mode_index]==0: #stepseq self._mode_index = 6 elif self._sub_mode_index[self._main_mode_index]==1: #melodic step seq self._mode_index = 7 else: #plain user mode 2 self._mode_index = 2 elif self._main_mode_index == 3: self._mode_index = 3 else: assert False def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) if self._main_mode_index == 0: #session self._m4lmode_index = 0 self.refresh_map_display() self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() elif self._main_mode_index == 1: self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) if self._sub_mode_index[self._main_mode_index]==0: #instrument controller self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) elif self._sub_mode_index[self._main_mode_index]==1: #device controller self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() else: #plain user mode 1 self._m4lmode_index = 3 self.refresh_map_display() self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() elif self._main_mode_index == 2: self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) if self._sub_mode_index[self._main_mode_index]==0: #stepseq self._m4lmode_index = 4 self.refresh_map_display() self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) elif self._sub_mode_index[self._main_mode_index]==1: #melodic step seq self._m4lmode_index = 5 self.refresh_map_display() self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) else: #plain user mode 2 self._m4lmode_index = 6 self.refresh_map_display() self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() elif self._main_mode_index == 3: #mixer self._m4lmode_index = 7 self.refresh_map_display() self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() else: assert False self._compute_mode_index() self._previous_mode_index=self._main_mode_index self._session.set_allow_update(True) self._zooming.set_allow_update(True) def _setup_session(self, as_active, as_enabled): assert isinstance(as_active, type(False)) for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) #matrix self._activate_matrix(True) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) #zoom if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) #nav buttons if as_enabled: self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, enabled): if self._instrument_controller != None: if enabled: self._m4lmode_index = 1 self.refresh_map_display() self._activate_matrix(False) self._activate_scene_buttons(True) self._activate_navigation_buttons(True) else: for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.use_default_message() scene_button.force_next_send() for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.use_default_message() button.force_next_send() self._instrument_controller.set_enabled(enabled) def _setup_device_controller(self, as_active): if self._device_controller!=None: if as_active: self._m4lmode_index = 2 self.refresh_map_display() self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons = True, drum_rack_mode = True): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled((not release_side_buttons)) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_matrix)) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled((not release_nav_buttons)) if drum_rack_mode: self._config_button.send_value(2) self._config_button.send_value(32) def _setup_step_sequencer(self, as_active): if(self._stepseq!=None): if(self._stepseq.is_enabled()!=as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if(self._stepseq2!=None): if(self._stepseq2.is_enabled()!=as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if(self._sub_modes.is_enabled()): #go back to default mode self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _init_session(self): if self._parent._live_major_version >= 9 and self._parent._live_minor_version >= 1 and self._parent._live_bugfix_version >= 2: #api changed in 9.1.2 self._session.set_stop_clip_value(AMBER_THIRD) self._session.set_stop_clip_triggered_value(AMBER_BLINK) else: # api for 9.1.1 below self._session.set_stop_track_clip_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.set_record_button_value(RED_THIRD) #clip_slot.set_clip_palette(CLIP_COLOR_TABLE) #clip_slot.set_clip_rgb_table(RGB_COLOR_TABLE) clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL) def _activate_navigation_buttons(self,active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self,active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self,active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._parent.log_message(msg) #Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value()