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 DC1(ControlSurface): def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) is_momentary = True self._timer = 0 #used for flashing states, and is incremented by each call from self._update_display() self._touched = 0 self.flash_status = 1 # Used in FlashingButtonElement (kludge for our purposes) self._device_selection_follows_track_selection = True with self.component_guard(): self._setup_transport_control() if USE_MIXER_CONTROLS == True: self.mixer_control() if USE_SESSION_VIEW == True: self.session_control() self.setup_device_control() def _setup_transport_control(self): is_momentary = True # We'll only be using momentary buttons here self.transport = TransportComponent() #Instantiate a Transport Component """set up the buttons""" self.transport.set_play_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 60)) #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61)) self.transport.set_record_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 62)) def mixer_control(self): is_momentary = True self.num_tracks = N_TRACKS if(USE_SENDS == True): self.mixer = MixerComponent(N_TRACKS, N_SENDS_PER_TRACK, USE_MIXER_EQ, USE_MIXER_FILTERS) else: self.mixer = MixerComponent(N_TRACKS,0, USE_MIXER_EQ, USE_MIXER_FILTERS) self.mixer.name = 'Mixer' self.mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) for index in range(N_TRACKS): self.mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) self.mixer.channel_strip(index)._invert_mute_feedback = True if(USE_SELECT_BUTTONS == True): self.selectbuttons = [None for index in range(N_TRACKS)] for index in range(len(SELECT_BUTTONS)): self.selectbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,SELECT_BUTTONS[index], 'Select_Button', self) self.mixer.channel_strip(index).set_select_button(self.selectbuttons[index]) self.selectbuttons[index].set_on_value(SELECT_BUTTON_ON_COLOR) self.selectbuttons[index].set_off_value(SELECT_BUTTON_OFF_COLOR) if(USE_SOLO_BUTTONS == True): self.solobuttons = [None for index in range(N_TRACKS)] for index in range(len(SOLO_BUTTONS)): self.solobuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,SOLO_BUTTONS[index], 'Solo_Button', self) self.mixer.channel_strip(index).set_solo_button(self.solobuttons[index]) self.solobuttons[index].set_on_value(SOLO_BUTTON_ON_COLOR) self.solobuttons[index].set_off_value(SOLO_BUTTON_OFF_COLOR) if(USE_ARM_BUTTONS == True): self.armbuttons = [None for index in range(N_TRACKS)] for index in range(len(ARM_BUTTONS)): self.armbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,ARM_BUTTONS[index], 'Arm_Button', self) self.mixer.channel_strip(index).set_arm_button(self.armbuttons[index]) self.armbuttons[index].set_on_value(ARM_BUTTON_ON_COLOR) self.armbuttons[index].set_off_value(ARM_BUTTON_OFF_COLOR) if(USE_MUTE_BUTTONS == True): self.mutebuttons = [None for index in range(N_TRACKS)] for index in range(len(MUTE_BUTTONS)): self.mutebuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,MUTE_BUTTONS[index], 'Mute_Button', self) self.mixer.channel_strip(index).set_mute_button(self.mutebuttons[index]) self.mutebuttons[index].set_on_value(MUTE_BUTTON_ON_COLOR) self.mutebuttons[index].set_off_value(MUTE_BUTTON_OFF_COLOR) if(USE_SENDS == True): self.sendencoders = [None for index in range(len(SEND_ENCODERS))] for index in range(len(SEND_ENCODERS)): self.sendencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_ENCODERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(SEND_ENCODERS)/N_SENDS_PER_TRACK): self.mixer.channel_strip(index).set_send_controls(tuple(self.sendencoders[(index*N_SENDS_PER_TRACK):((index*N_SENDS_PER_TRACK)+N_SENDS_PER_TRACK-1)])) if(USE_VOLUME_CONTROLS == True): self.volencoders = [None for index in range(len(VOLUME_ENCODERS))] for index in range (len(VOLUME_ENCODERS)): self.volencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, VOLUME_ENCODERS[index], Live.MidiMap.MapMode.absolute) self.mixer.channel_strip(index).set_volume_control(self.volencoders[index]) def session_control(self): is_momentary = True self._timer = 0 self.flash_status = 1 self.grid = [None for index in range(N_TRACKS*N_SCENES)] for index in range(N_TRACKS*N_SCENES): self.grid[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,TRACK_CLIP_BUTTONS[index], 'Grid' + str(index), self) self.grid[index].set_off_value(0) self.grid[index].turn_off() self.matrix = ButtonMatrixElement() for row in range(N_SCENES): button_row = [] for column in range(N_TRACKS): button_row.append(self.grid[row+(column*N_SCENES)]) self.matrix.add_row(tuple(button_row)) self.session = SessionComponent(N_TRACKS,N_SCENES) self.session.name = "Session" self.session.set_offsets(0,0) self.scene = [None for index in range(N_SCENES)] for row in range(N_SCENES): self.scene[row] = self.session.scene(row) self.scene[row].name = 'Scene_'+str(row) for column in range(N_TRACKS): clip_slot = self.scene[row].clip_slot(column) clip_slot.name = str(column)+'_Clip_Slot'+str(row) self.scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRG_PLAY_COLOR) self.scene[row].clip_slot(column).set_stopped_value(CLIP_STOP_COLOR) self.scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR) self.set_highlighting_session_component(self.session) self.session_zoom = DeprecatedSessionZoomingComponent(self.session) #this creates the ZoomingComponent that allows navigation when the shift button is pressed self.session_zoom.name = 'Session_Overview' #name it so we can access it in m4l self.session_zoom.set_stopped_value(ZOOM_STOPPED) #set the zooms stopped color self.session_zoom.set_playing_value(ZOOM_PLAYING) #set the zooms playing color self.session_zoom.set_selected_value(ZOOM_SELECTED) #set the zooms selected color self.session_zoom.set_button_matrix(self.matrix) #assign the ButtonMatrixElement that we created in _setup_controls() to the zooming component so that we can control it self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 63) self.session_zoom.set_zoom_button(self._shift_button) #assign a shift button so that we can switch states between the SessionComponent and the SessionZoomingComponent self.looper = LooperComponent(self) self.log_message(str(len(STOP_BUTTONS))) if(USE_STOP_BUTTONS == True): self.stopbuttons = [None for index in range(N_TRACKS)] for index in range(len(STOP_BUTTONS)): self.stopbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,STOP_BUTTONS[index], 'Stop_Button', self) self.session.set_stop_track_clip_buttons(self.stopbuttons) self.stopbuttons[index].set_on_value(STOP_BUTTON_ON_COLOR) self.stopbuttons[index].set_off_value(STOP_BUTTON_OFF_COLOR) self.scrollencoder = ScrollEncoderElement(MIDI_CC_TYPE, CHANNEL, 32, Live.MidiMap.MapMode.absolute, self.session, self.transport, self.mixer, self.looper) self.scrollencoder.set_nav_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 0)) self.scrollencoder.set_transport_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 7)) self.scrollencoder.set_scene_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 3)) self.scrollencoder.set_library_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 4)) self.scrollencoder.set_button1(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 1)) self.scrollencoder.set_button2(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 2)) self.scrollencoder.set_button3(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 5)) self.scrollencoder.set_button4(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 6)) self.scrollencoder.set_encoder_button(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 32)) for column in range(N_TRACKS): for row in range(N_SCENES): self.scene[row].clip_slot(column).set_launch_button(self.grid[row+(column*N_SCENES)]) for index in range(N_TRACKS*N_SCENES): self.grid[index].clear_send_cache() if USE_MIXER_CONTROLS == True: self.session.set_mixer(self.mixer) self.refresh_state() self.session.set_enabled(True) self.session.update() def setup_device_control(self): is_momentary = True device_bank_buttons = [] device_param_controls = [] bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button') for index in range(4): device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 16 + index)) device_bank_buttons[-1].name = bank_button_labels[index] for index in range(8): #ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, 21 + index) ringed_encoder = CMDEncoderElement(MIDI_CC_TYPE, CHANNEL, 16 + index, Live.MidiMap.MapMode.relative_binary_offset, 20) #ringed_encoder.set_ring_mode_button(ring_mode_button) ringed_encoder.name = 'Device_Control_' + str(index) #ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button' device_param_controls.append(ringed_encoder) device = ShiftableDeviceComponent() device.name = 'Device_Component' device.set_bank_buttons(tuple(device_bank_buttons)) device.set_shift_button(self._shift_button) device.set_parameter_controls(tuple(device_param_controls)) device.set_on_off_button(device_bank_buttons[1]) self.set_device_component(device) detail_view_toggler = DetailViewControllerComponent(self) detail_view_toggler.name = 'Detail_View_Control' detail_view_toggler.set_shift_button(self._shift_button) detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0]) detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3]) def update_display(self): ControlSurface.update_display(self) self._timer = (self._timer + 1) % 256 def disconnect(self): self._hosts = [] ControlSurface.disconnect(self) return 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 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, note_repeat): #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) assert isinstance(note_repeat, NoteRepeatComponent) ModeSelectorComponent.__init__(self) #super constructor #inject ControlSurface and OSD components (M4L) self._matrix = matrix self._nav_buttons = top_buttons[:4] #arrow buttons self._mode_buttons = top_buttons[ 4:] #session,user1,user2,mixer buttons self._side_buttons = side_buttons #launch buttons self._config_button = config_button #used to reset launchpad self._osd = osd self._control_surface = control_surface self._note_repeat = note_repeat #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(self._mode_buttons) ###SESSION COMPONENT 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' ###ZOOMING COMPONENT self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning=True) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value("Default.Button.Off") #Non-Matrix buttons self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #SubSelector changes the Mode using side buttons -> MIXER MODE (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._note_repeat) 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): u""" Class that reassigns the button on the launchpad to different functions """ 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(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): 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: if not isinstance(button, ButtonElement): raise AssertionError self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(SESSION_MODE) return def number_of_modes(self): return 4 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 == MIXER_MODE: 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): super(MainSelectorComponent, self).update() 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 == USER_1_MODE if self._mode_index == SESSION_MODE: self._setup_mixer(not as_active) self._setup_session(as_active, as_enabled) elif self._mode_index == USER_1_MODE: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == USER_2_MODE: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == MIXER_MODE: self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) else: assert False 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): 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]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) return 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_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 self._mode_index == USER_1_MODE: 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 OhmModes(ControlSurface): __module__ = __name__ __doc__ = ' OhmModes controller script ' def __init__(self, c_instance): super(OhmModes, self).__init__(c_instance) self._version_check = 'b996' self._host_name = 'Ohm' self._color_type = 'OhmRGB' self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 self._backlight = 127 self._backlight_type = 'static' self._ohm = 127 self._ohm_type = 'static' self._pad_translations = PAD_TRANSLATION self._device_selection_follows_track_selection = FOLLOW self._keys_octave = 5 self._keys_scale = 0 self._tempo_buttons = None with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_m4l_interface() self._setup_transport_control() self._setup_mixer_control() self._setup_session_control() self._setup_device_control() self._setup_crossfader() self._setup_translations() self._setup_mod() self._setup_modes() self._assign_page_constants() self._last_device = None self.song().view.add_selected_track_listener(self._update_selected_device) self.show_message('OhmModes Control Surface Loaded') self._send_midi(tuple(switchxfader)) if FORCE_TYPE is True: self._rgb = FORCE_COLOR_TYPE else: self.schedule_message(10, self.query_ohm, None) self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>') debug('DEBUG ON for OhmModes script.') def query_ohm(self): self._send_midi(tuple(check_model)) def update_display(self): super(OhmModes, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() self.strobe() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def get_device_bank(self): return self._device._bank_index def _setup_controls(self): is_momentary = True self._fader = [ None for index in range(8) ] self._dial = [ None for index in range(16) ] self._button = [ None for index in range(8) ] self._menu = [ None for index in range(6) ] for index in range(8): self._fader[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8): self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self) for index in range(16): self._dial[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self) self._knobs = [] for index in range(12): self._knobs.append(self._dial[index]) for index in range(6): self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self) self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute) self._crossfader.name = 'Crossfader' self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self) self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self) self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._grid = [ None for index in range(8) ] self._monomod = ButtonMatrixElement() self._monomod.name = 'Monomod' for column in range(8): self._grid[column] = [ None for index in range(8) ] for row in range(8): self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column * 8 + row, 'Grid_' + str(column) + '_' + str(row), self) for row in range(5): button_row = [] for column in range(7): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) for row in range(8): button_row = [] for column in range(8): button_row.append(self._grid[column][row]) self._monomod.add_row(tuple(button_row)) self._dial_matrix = ButtonMatrixElement() for row in range(3): dial_row = [] for column in range(4): dial_row.append(self._dial[column + (row*4)]) self._dial_matrix.add_row(tuple(dial_row)) self._menu_matrix = ButtonMatrixElement([self._menu]) def _setup_m4l_interface(self): self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard) self.get_control_names = self._m4l_interface.get_control_names self.get_control = self._m4l_interface.get_control self.grab_control = self._m4l_interface.grab_control self.release_control = self._m4l_interface.release_control def _setup_translations(self): controls = [] for array in self._grid: for button in array: controls.append(button) if FADER_BANKING: controls = controls + self._dial if DIAL_BANKING: controls = controls + self._dial self._translations = TranslationComponent(controls, USER_CHANNEL) self._translations.layer = Layer(priority = 7, channel_selector_buttons = self._menu_matrix) def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = OhmModHandler(self) self.modhandler.name = 'ModHandler' self.modhandler.layer = Layer(priority = 5, grid = self._monomod, nav_up_button = self._menu[2], nav_down_button = self._menu[5], nav_left_button = self._menu[3], nav_right_button = self._menu[4], shift_button = self._menu[1], alt_button = self._menu[0], parameter_controls = self._dial_matrix) self.modhandler.legacy_shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, channel_buttons = self._monomod.submatrix[:, 1:2], nav_matrix = self._monomod.submatrix[4:8, 2:6])) self.modhandler.shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, device_selector_matrix = self._monomod.submatrix[:, :1], lock_button = self._livid, key_buttons = self._monomod.submatrix[:, 7:8])) self.modhandler.set_enabled(False) self.modhandler.set_mod_button(self._livid) def _setup_modes(self): self._shift_mode = ShiftModeComponent(self) self._shift_mode.name = 'Shift_Mode' #self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid) self._shift_mode.layer = Layer(priority = 4, mode_toggle1 = self._shift_l, mode_toggle2 = self._shift_r, mode_toggle3 = self._livid) self._shift_mode.set_enabled(True) self._scale_mode = ScaleModeComponent(self) self._scale_mode.name = 'Scale_Mode' self._octave_mode = OctaveModeComponent(self) self._octave_mode.name = 'Octave_Mode' def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' #self._transport.layer = Layer(priority = 4, play_button = self._menu[2], stop_button = self._menu[3]) def _setup_mixer_control(self): global mixer is_momentary = True self._num_tracks = 7 mixer = SpecialMixerComponent(7, 0, True, True) mixer.name = 'Mixer' self._mixer = mixer for index in range(7): mixer.channel_strip(index).set_volume_control(self._fader[index]) for index in range(7): mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) mixer.track_eq(index).name = 'Mixer_EQ_' + str(index) mixer.channel_strip(index)._invert_mute_feedback = True self.song().view.selected_track = mixer.channel_strip(0)._track def _setup_session_control(self): global session is_momentary = True num_tracks = 7 num_scenes = 5 session = SessionComponent(num_tracks, num_scenes) session.name = 'Session' self._session = session session.set_offsets(0, 0) self._scene = [ None for index in range(6) ] for row in range(num_scenes): self._scene[row] = session.scene(row) self._scene[row].name = 'Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) session.set_mixer(self._mixer) session.set_show_highlight(True) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = 'Session_Overview' self.set_highlighting_session_component(self._session) def _assign_session_colors(self): self.log_message('assign session colors') num_tracks = 7 num_scenes = 5 self._session.set_stop_clip_value(STOP_CLIP_COLOR[self._rgb]) for row in range(num_scenes): for column in range(num_tracks): self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRIGD_TO_PLAY_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb]) self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb]) self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb]) self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb]) self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb]) for row in range(8): for column in range(8): self._grid[column][row].set_force_next_value() self._session.on_scene_list_changed() self._shift_mode.update() def _setup_device_control(self): self._device = DeviceComponent() self._device.name = 'Device_Component' self.set_device_component(self._device) self._device_navigator = DetailViewControllerComponent() self._device_navigator.name = 'Device_Navigator' self._device_selection_follows_track_selection = FOLLOW def device_follows_track(self, val): self._device_selection_follows_track_selection = val == 1 return self def _setup_crossfader(self): self._mixer.set_crossfader_control(self._crossfader) def disconnect(self): """clean things up on disconnect""" self.song().view.remove_selected_track_listener(self._update_selected_device) self.log_message(time.strftime('%d.%m.%Y %H:%M:%S', time.localtime()) + '--------------= OhmModes log closed =--------------') super(OhmModes, self).disconnect() rebuild_sys() def _get_num_tracks(self): return self.num_tracks def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) def strobe(self): if self._backlight_type != 'static': if self._backlight_type is 'pulse': self._backlight = int(math.fabs(self._timer * 16 % 64 - 32) + 32) if self._backlight_type is 'up': self._backlight = int(self._timer * 8 % 64 + 16) if self._backlight_type is 'down': self._backlight = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16) self._send_midi(tuple([176, 27, int(self._backlight)])) if self._ohm_type != 'static': if self._ohm_type is 'pulse': self._ohm = int(math.fabs(self._timer * 16 % 64 - 32) + 32) if self._ohm_type is 'up': self._ohm = int(self._timer * 8 % 64 + 16) if self._ohm_type is 'down': self._ohm = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16) self._send_midi(tuple([176, 63, int(self._ohm)])) self._send_midi(tuple([176, 31, int(self._ohm)])) def deassign_matrix(self): with self.component_guard(): self.modhandler.set_enabled(False) self._translations.set_enabled(False) #self.assign_alternate_mappings(0) self._scale_mode.set_mode_buttons(None) self._scale_mode.set_enabled(False) self._octave_mode.set_mode_buttons(None) self._octave_mode.set_enabled(False) self._session_zoom.set_enabled(False) self._session_zoom.set_nav_buttons(None, None, None, None) self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) self._transport.set_enabled(False) for column in range(4): self._mixer.track_eq(column)._gain_controls = None self._mixer.track_eq(column).set_enabled(False) for column in range(7): self._mixer.channel_strip(column).set_crossfade_toggle(None) self._mixer.channel_strip(column).set_mute_button(None) self._mixer.channel_strip(column).set_solo_button(None) self._mixer.channel_strip(column).set_arm_button(None) self._mixer.channel_strip(column).set_send_controls(None) self._mixer.channel_strip(column).set_pan_control(None) self._mixer.track_eq(column).set_enabled(False) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(None) for column in range(8): self._button[column]._on_value = SELECT_COLOR[self._rgb] for row in range(8): #self._grid[column][row].set_channel(0) self._grid[column][row].release_parameter() self._grid[column][row].use_default_message() self._grid[column][row].set_enabled(True) self._grid[column][row].send_value(0, True) self._grid[column][row]._on_value = 127 self._grid[column][row]._off_value = 0 self._grid[column][row].force_next_send() for index in range(6): self._menu[index]._on_value = 127 self._menu[index]._off_value = 0 for index in range(16): self._dial[index].use_default_message() self._dial[index].release_parameter() self._device.set_parameter_controls(None) self._device.set_enabled(False) self._device_navigator.set_enabled(False) self._mixer.update() self._matrix.reset() self.request_rebuild_midi_map() def _assign_page_constants(self): with self.component_guard(): self._session_zoom.set_zoom_button(self._grid[7][7]) self._session_zoom.set_button_matrix(self._matrix) for column in range(7): self._mixer.channel_strip(column).set_select_button(self._button[column]) self._mixer.channel_strip(column).set_volume_control(self._fader[column]) self._mixer.master_strip().set_volume_control(self._fader[7]) self._mixer.master_strip().set_select_button(self._button[7]) self._mixer.set_prehear_volume_control(self._dial[15]) self._transport.set_play_button(self._menu[0]) self._menu[0].send_value(PLAY_COLOR[self._rgb], True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._transport.set_stop_button(self._menu[1]) self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._menu[1].send_value(STOP_COLOR[self._rgb], True) self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4]) def assign_page_0(self): with self.component_guard(): self._backlight_type = 'static' self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = SOLO_COLOR[self._rgb] self._mixer.channel_strip(column).set_solo_button(self._grid[column][6]) self._grid[column][7]._on_value = ARM_COLOR[self._rgb] self._mixer.channel_strip(column).set_arm_button(self._grid[column][7]) self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8]) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for column in range(4): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]])) for index in range(5): self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[index].set_launch_button(self._grid[7][index]) self._grid[7][index].set_force_next_value() self._grid[7][index].turn_off() for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) #self._mixer.update_all() self.request_rebuild_midi_map() #self.log_message('assign_page_0') def assign_page_1(self): with self.component_guard(): self._backlight_type = 'pulse' self._session_zoom.set_enabled(False) for column in range(4): for row in range(4): self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True) self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True) self._grid[column][row].set_enabled(False) self._grid[column][row]._msg_channel = PAGE1_DRUM_CHANNEL self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row]) self._grid[column + 4][row].set_enabled(False) self._grid[column + 4][row]._msg_channel = PAGE1_BASS_CHANNEL self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row]) scale_mode_buttons = [] for column in range(8): for row in range(3): self._grid[column][row + 4].set_enabled(False) self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True) self._grid[column][row + 4]._msg_channel = PAGE1_KEYS_CHANNEL self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12)) for row in range(1): scale_mode_buttons.append(self._grid[column][7]) self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons)) self._scale_mode.set_enabled(True) self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]])) self._octave_mode.set_enabled(True) for column in range(7): self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]])) self._mixer.channel_strip(column).set_arm_button(self._button[column]) self._device.set_enabled(True) device_param_controls = [] for index in range(8): device_param_controls.append(self._dial[index]) self._device.set_parameter_controls(tuple(device_param_controls)) self._menu[0]._on_value = PLAY_COLOR[self._rgb] for index in range(4): self._menu[2 + index]._on_value = DEVICE_NAV_COLOR[self._rgb] self._device_navigator.set_enabled(True) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) self.request_rebuild_midi_map() def assign_page_2(self): with self.component_guard(): self._backlight_type = 'up' self._session_zoom.set_enabled(True) for column in range(7): self._grid[column][5]._on_value = MUTE_COLOR[self._rgb] self._mixer.channel_strip(column).set_mute_button(self._grid[column][5]) self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb] self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6]) self._grid[column][7]._msg_channel = 2 self._grid[column][7].set_identifier(column) self._grid[column][7].reset() self._grid[column][7].set_enabled(False) self._grid[column][7].send_value(4, True) for row in range(5): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) for row in range(5): self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb] self._scene[row].set_launch_button(self._grid[7][row]) self._grid[7][row].set_force_next_value() self._grid[7][row].turn_off() for column in range(4): self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]])) self._mixer.track_eq(column).set_enabled(True) for column in range(3): self._mixer.channel_strip(column + 4).set_pan_control(self._dial[column + 12]) for index in range(4): self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb] self._session.set_track_bank_buttons(self._menu[4], self._menu[3]) self._session.set_scene_bank_buttons(self._menu[5], self._menu[2]) self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]]) self._menu[0]._on_value = PLAY_COLOR[self._rgb] self._menu[1]._off_value = STOP_COLOR[self._rgb] self._menu[1]._on_value = STOP_COLOR[self._rgb] self._transport.set_enabled(True) #self._mixer.update() self.request_rebuild_midi_map() def assign_mod(self): self.modhandler.set_enabled(True) def assign_translation(self): self._translations.set_enabled(True) def assign_alternate_mappings(self, chan): for column in range(8): for row in range(8): self._grid[column][row].set_channel(chan) for knob in self._dial: knob.set_channel(chan) knob.set_enabled(chan is 0) self.request_rebuild_midi_map() def _update_selected_device(self): if self._device_selection_follows_track_selection is True: self._update_device_selection() def handle_sysex(self, midi_bytes): #self.log_message('sysex: ' + str(midi_bytes)) if len(midi_bytes) > 10: if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]): self.log_message(str('>>>color detected')) self._rgb = 0 for button in self._button: button._color_map = COLOR_MAP for column in self._grid: for button in column: button._color_map = COLOR_MAP elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]): self.log_message(str('>>>mono detected')) self._rgb = 1 for button in self._button: button._color_map = [127 for index in range(0, 7)] for column in self._grid: for button in column: button._color_map = [127 for index in range(0, 7)] self._assign_session_colors() def to_encoder(self, num, val): rv = int(val * 127) self._device._parameter_controls[num].receive_value(rv) p = self._device._parameter_controls[num]._parameter_to_map_to newval = val * (p.max - p.min) + p.min p.value = newval def _set_tempo_buttons(self, buttons): if self._tempo_buttons != None: self._tempo_buttons[0].remove_value_listener(self._tempo_value) self._tempo_buttons[1].remove_value_listener(self._tempo_value) self._tempo_buttons = buttons if buttons != None: for button in buttons: assert isinstance(button, MonoButtonElement) self._tempo_buttons[0].set_on_off_values(4, 0) self._tempo_buttons[0].add_value_listener(self._tempo_value, True) self._tempo_buttons[1].set_on_off_values(4, 0) self._tempo_buttons[1].add_value_listener(self._tempo_value, True) self._tempo_buttons[0].turn_on() self._tempo_buttons[1].turn_on() def _tempo_value(self, value, sender): if value > 0 and self._tempo_buttons.index(sender) == 0: self.song().tempo = round(min(self.song().tempo + 1, 999)) elif value > 0 and self._tempo_buttons.index(sender) == 1: self.song().tempo = round(max(self.song().tempo - 1, 20)) def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if not display_string: return ' ' * NUM_CHARS_PER_DISPLAY_STRIP if len(display_string.strip()) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.endswith('dB') and display_string.find('.') != -1: display_string = display_string[:-2] if len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1: for um in [' ', 'i', 'o', 'u', 'e', 'a']: while len(display_string) > NUM_CHARS_PER_DISPLAY_STRIP - 1 and display_string.rfind(um, 1) != -1: um_pos = display_string.rfind(um, 1) display_string = display_string[:um_pos] + display_string[um_pos + 1:] else: display_string = display_string.center(NUM_CHARS_PER_DISPLAY_STRIP - 1) ret = u'' for i in range(NUM_CHARS_PER_DISPLAY_STRIP - 1): if ord(display_string[i]) > 127 or ord(display_string[i]) < 0: ret += ' ' else: ret += display_string[i] ret += ' ' return ret def notification_to_bridge(self, name, value, sender): if isinstance(sender, tuple([MonoButtonElement, MonoEncoderElement])): self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) def touched(self): if self._touched is 0: self._monobridge._send('touch', 'on') self.schedule_message(2, self.check_touch) self._touched += 1 def check_touch(self): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send('touch', 'off') else: self.schedule_message(2, self.check_touch) def get_clip_names(self): clip_names = [] for scene in self._session._scenes: for clip_slot in scene._clip_slots: if clip_slot.has_clip() is True: clip_names.append(clip_slot._clip_slot) return clip_slot._clip_slot return clip_names
class Tweaker(ControlSurface): __module__ = __name__ __doc__ = " Tweaker control surface script " def __init__(self, c_instance, *a, **k): super(Tweaker, self).__init__(c_instance, *a, **k) with self.component_guard(): self._update_linked_device_selection = None self._tweaker_version_check = '0.4' self.log_message("--------------= Tweaker Session " + str(self._tweaker_version_check) + " log opened =--------------") self._timer = 0 self.flash_status = 1 self._last_selected_strip_number = 0 self._device_selection_follows_track_selection = False #self._pad_translations = PAD_TRANSLATION self._linked_session = None self._mixer_offset = 0 self._nav_lock = True self._setup_controls() self._setup_transport_control() self._setup_device_control() self._setup_mixer_control() self._setup_session_control() self._setup_crossfader() self._setup_modes() self._setup_pads() self._setup_navigation_lock() self._setup_arrange_session_toggle() self.assign_main_configuration() self.show_message('Tweaker Control Surface Loaded') #self.schedule_message(3, self._mixer._reassign_tracks) """script initialization methods""" def _setup_controls(self): is_momentary = True self._grid = [None for index in range(8)] for column in range(8): self._grid[column] = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column + (row * 8) + 1, 'Grid_' + str(column) + '_' + str(row), self) for row in range(4)] self._button = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_BUTTONS[index], 'Button_' + str(index), self) for index in range(len(TWEAKER_BUTTONS))] self._nav = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_NAVS[index], 'Nav_' + str(index), self) for index in range(len(TWEAKER_NAVS))] self._encoder_button = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_ENCODER_BUTTONS[index], 'Encoder_Button_' + str(index), self) for index in range(len(TWEAKER_ENCODER_BUTTONS))] self._dial = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_DIALS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_DIALS))] self._fader = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_FADERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_FADERS))] self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute) self._encoder = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_ENCODERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_ENCODERS))] self._pad = [TweakerMonoButtonElement(False, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_PADS[index], 'Pad_' + str(index), self) for index in range(len(TWEAKER_PADS))] for index in range(4): self._pad[index].set_enabled(False) self._pad[index].set_channel(PAD_CHANNEL) self._pad[index].set_identifier(index + 4) self._pad[index+4].set_enabled(False) self._pad[index+4].set_channel(PAD_CHANNEL) self._pad[index+4].set_identifier(index) self._pad_pressure = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_PAD_PRESSURES[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_PADS))] for index in range(8): self._pad_pressure[index]._last_sent = 0 self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' for row in range(4): button_row = [] for column in range(7): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) self._send_midi(tuple([240,0,1,106,01,07,21,21,247])) #set all pots to walk mode self._send_midi(tuple([240, 0, 1, 106, 1, 6, 127 , 127, 25, 0, 15, 0, 9, PAD_SENSITIVITY, 247])) #set pads to sensitivity set in Map file def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' def _setup_mixer_control(self): is_momentary = True self._num_tracks = (2) #A mixer is one-dimensional; self._mixer = MixerComponent(self, 2, 0, False, False) self._mixer.name = 'Mixer' self._device_navigator = [None for index in range(2)] self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) for index in range(2): self._mixer.channel_strip(index).set_volume_control(self._fader[index]) self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) self._mixer.channel_strip(index)._index = index self._mixer.channel_strip(index)._invert_mute_feedback = True self._mixer.channel_strip(index)._device_component = self._device[index] self._device_navigator[index] = DetailViewControllerComponent(self, self._mixer.channel_strip(index)) self._device_navigator[index].name = 'Device_Navigator_'+str(index) self.song().view.selected_track = self._mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error #self._mixer._reassign_tracks() def _setup_session_control(self): is_momentary = True num_tracks = NUM_TRACKS num_scenes = NUM_SCENES self._session = SessionComponent(self, num_tracks, num_scenes) self._session.name = "Session" self._session.set_offsets(0, 0) self._session.set_stop_clip_value(STOP_CLIP) self._scene = [None for index in range(3)] for row in range(num_scenes): self._scene[row] = self._session.scene(row) self._scene[row].name = 'Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_' + str(row) clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY) clip_slot.set_triggered_to_record_value(CLIP_TRG_REC) clip_slot.set_stopped_value(CLIP_STOP) clip_slot.set_started_value(CLIP_STARTED) clip_slot.set_recording_value(CLIP_RECORDING) self._session.set_mixer(self._mixer) self.set_highlighting_session_component(self._session) self._session_zoom = SessionZoomingComponent(self._session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_stopped_value(ZOOM_STOPPED) self._session_zoom.set_playing_value(ZOOM_PLAYING) self._session_zoom.set_selected_value(ZOOM_SELECTED) def _setup_device_control(self): self._device = [None for index in range(2)] for index in range(2): self._device[index] = DeviceComponent() self._device[index].name = 'Device_Component_'+str(index) self._device[index].set_enabled(True) #self._device[index]._number_of_parameter_banks = self._device_number_of_parameter_banks(self._device[index]) #self._device[index]._assign_parameters = self._device_assign_parameters(self._device[index]) self._device[index]._device_banks = DEVICE_DICT self._device[index]._device_best_banks = DEVICE_BOB_DICT self._device[index]._device_bank_names = BANK_NAME_DICT def _setup_crossfader(self): self._mixer.set_crossfader_control(self._crossfader) def _setup_modes(self): self._pad_offset = PadOffsetComponent(self) self._pad_offset._set_protected_mode_index(0) self._pad_offset.set_enabled(False) def _setup_pads(self): self._light_pad.replace_subjects(self._pad_pressure) def _setup_navigation_lock(self): self._nav_lock_value.subject = self._encoder_button[0] def _setup_arrange_session_toggle(self): self._arrange_session_value.subject = self._nav[1] """configuration methods""" def assign_main_configuration(self): for column in range(7): for row in range(3): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) self._session.set_stop_track_clip_buttons(tuple([self._grid[index][3] for index in range(7)])) for row in range(3): self._scene[row].set_launch_button(self._grid[7][row]) self._device[0].set_parameter_controls(tuple([self._encoder[index+1] for index in range(3)])) self._device[0].set_enabled(True) self._device[1].set_parameter_controls(tuple([self._encoder[index+4] for index in range(3)])) self._device[1].set_enabled(True) for track in range(2): self._mixer.channel_strip(track).set_volume_control(self._fader[track]) self._mixer.channel_strip(track).set_solo_button(self._button[track*3]) self._button[track*3].set_on_off_values(SOLO, 0) self._mixer.channel_strip(track).set_arm_button(self._button[1 + (track*3)]) self._button[1 + (track*3)].set_on_off_values(ARM, 0) self._mixer.channel_strip(track).set_crossfade_toggle(self._button[2 + (track*3)]) self._mixer.master_strip().set_volume_control(self._dial[1]) self._mixer.set_prehear_volume_control(self._dial[0]) self._session.set_track_bank_buttons(self._nav[4], self._nav[3]) self._session.set_scene_bank_buttons(self._nav[2], self._nav[0]) self._session_zoom.set_zoom_button(self._grid[7][3]) self._session_zoom.set_nav_buttons(self._nav[0], self._nav[2], self._nav[3], self._nav[4]) self._session_zoom.set_button_matrix(self._matrix) self._device[0].set_on_off_button(self._encoder_button[1]) self._device_navigator[0].set_device_nav_buttons(self._encoder_button[2], self._encoder_button[3]) self._device[1].set_on_off_button(self._encoder_button[4]) self._device_navigator[1].set_device_nav_buttons(self._encoder_button[5], self._encoder_button[6]) for track in range(2): self._update_device(self._mixer.channel_strip(track)) #self._device.set_bank_nav_buttons(self._menu[0], self._menu[3]) #for index in range(8): # self._pad[index].send_value(1, True) # self._pad[index].set_channel(1) # self._pad[index].set_identifier(index) # self._pad[index].set_enabled(False) #this has to happen for translate to work self._track_selector_value.subject = self._encoder[0] self._shift_value.subject = self._grid[7][3] self._grid[7][3].send_value(127, True) self.request_rebuild_midi_map() """Tweaker custom methods""" @subject_slot('value') def _shift_value(self, value): self._pad_offset.set_enabled(value>0) if value > 0: self._update_navigation_view() for pad in self._pad: pad.use_default_message() pad.set_enabled(True) self._pad_offset.set_mode_buttons(tuple(self._pad)) self.schedule_message(1, self._pad_offset.update) #if self._session.is_enabled(): # self._update_navigation_view() self._grid[7][3].send_value(SHIFT_ON) for track in range(2): self._mixer.channel_strip(track).set_crossfade_toggle(None) self._mixer.channel_strip(track).set_select_button(self._button[2 + (track*3)]) else: self._pad_offset.set_mode_buttons(None) for index in range(4): self._pad[index].set_enabled(False) self._pad[index].set_channel(PAD_CHANNEL) self._pad[index].set_identifier(index + 4 + (self._pad_offset._mode_index * 8)) self._pad[index+4].set_enabled(False) self._pad[index+4].set_channel(PAD_CHANNEL) self._pad[index+4].set_identifier(index + (self._pad_offset._mode_index * 8)) self._grid[7][3].send_value(SHIFT_OFF) for track in range(2): self._mixer.channel_strip(track).set_select_button(None) self._mixer.channel_strip(track).set_crossfade_toggle(self._button[2 + (track*3)]) @subject_slot('value') def _nav_lock_value(self, value): if value > 0: if self._nav_lock: self._mixer_offset = self._mixer_offset + self._session._track_offset self._mixer.set_track_offset(self._mixer_offset) else: if self._mixer_offset in range(self._session._track_offset, self._session._track_offset + 5): self._mixer_offset = self._mixer_offset - self._session._track_offset elif self._mixer_offset < self._session._track_offset: self._mixer_offset = 0 else: self._mixer_offset = min(self._session._track_offset+5, len(self._session.tracks_to_use())-2) self._mixer.set_track_offset(self._session._track_offset + self._mixer_offset) self._nav_lock = not self._nav_lock self._session.update() @subject_slot('value') def _arrange_session_value(self, value): if value > 0: if (self.application().view.is_view_visible('Arranger')): self.application().view.show_view('Session') else: self.application().view.show_view('Arranger') @subject_slot('value') def _track_selector_value(self, value): if(value is 1): if self._nav_lock: self._mixer_offset = min(self._mixer_offset + 1, min(NUM_TRACKS - 2, len(self._session.tracks_to_use())-self._session._track_offset-2)) else: self._mixer_offset = min(self._mixer_offset + 1, len(self._session.tracks_to_use())-2) elif(value is 127): self._mixer_offset = max(self._mixer_offset - 1, 0) if self._nav_lock: self._mixer.set_track_offset(self._session._track_offset + self._mixer_offset) #self._session.set_offsets(self._session._track_offset) ?? else: self._mixer.set_track_offset(self._mixer_offset) self._session.update() if self._mixer.channel_strip(self._last_selected_strip_number)._track != None: self.song().view.selected_track = self._mixer.channel_strip(self._last_selected_strip_number)._track if self._linked_session != None: if self._linked_session._is_linked(): self._linked_session._unlink() self._linked_session.set_offsets(self._mixer._track_offset, self._linked_session._scene_offset) self._linked_session._link() @subject_slot_group('value') def _light_pad(self, value, sender): if not self._pad_offset.is_enabled(): if value > sender._last_sent: if self._pad[self._pad_pressure.index(sender)]._last_sent_value < 1: self._pad[self._pad_pressure.index(sender)].send_value(127, True) else: self._pad[self._pad_pressure.index(sender)].send_value(0, True) sender._last_sent = value def _update_navigation_view(self): try: dif = self._mixer._track_offset - self._session._track_offset for index in range(7): #if (index + self._session._track_offset) in range(len(self._session.tracks_to_use())): if (index + self._session._track_offset) in range(0, len(self.song().visible_tracks)): self._grid[index][3].send_value(NAV_COLORS[int(index in range(dif, dif + 2))], True) elif (index + self._session._track_offset) in range(len(self.song().visible_tracks), len(self._session.tracks_to_use())): self._grid[index][3].send_value(RETURN_NAV_COLORS[int(index in range(dif, dif + 2))], True) else: self._grid[index][3].send_value(0, True) self._send_midi(tuple([240,0,1,106,01,07,21,21,247])) #set all pots to walk mode except: self.log_message('cant update navigation veiw') def _update_device(self, channelstrip): try: if channelstrip in self._mixer._channel_strips[:2]: for control in channelstrip._device_component._parameter_controls: control.send_value(0, True) if channelstrip._device_component._on_off_button != None: channelstrip._device_component._on_off_button.turn_off() if not channelstrip._track is None: if not channelstrip._device_component._device in channelstrip._track.devices: track = channelstrip._track device_to_select = track.view.selected_device if (device_to_select == None) and (len(track.devices) > 0): device_to_select = track.devices[0] elif channelstrip._device_component and not type(channelstrip._device_component) is type(None): channelstrip._device_component.set_device(device_to_select) else: channelstrip._device_component.set_device(None) else: pass else: channelstrip._device_component.set_device(None) channelstrip._device_component._on_on_off_changed() except: self.log_message('cant update device') """m4l bridge""" def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 12 if (not display_string): return (' ' * NUM_CHARS_PER_DISPLAY_STRIP) if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))): display_string = display_string[:-2] if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)): for um in [' ', 'i', 'o', 'u', 'e', 'a']: while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)): um_pos = display_string.rfind(um, 1) display_string = (display_string[:um_pos] + display_string[(um_pos + 1):]) else: display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1)) ret = u'' for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)): if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)): ret += ' ' else: ret += display_string[i] ret += ' ' return ret def notification_to_bridge(self, name, value, sender): #if(isinstance(sender, MonoEncoderElement2)): # self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name))) # self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value))) pass def touched(self): if(self._shift_mode._mode_index < 2): if self._touched is 0: self._monobridge._send('touch', 'on') self.schedule_message(2, self.check_touch) self._touched +=1 def check_touch(self): if(self._shift_mode._mode_index < 2): if self._touched > 5: self._touched = 5 elif self._touched > 0: self._touched -= 1 if self._touched is 0: self._monobridge._send('touch', 'off') else: self.schedule_message(2, self.check_touch) """general functionality""" def update_display(self): super(Tweaker, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, TweakerMonoButtonElement): control.flash(self._timer) def disconnect(self): if self._session._is_linked(): self._session._unlink() self.log_message("--------------= Tweaker Session " + str(self._tweaker_version_check) + " log closed =--------------") #Create entry in log file super(Tweaker, self).disconnect() def handle_sysex(self, midi_bytes): pass def _get_num_tracks(self): return self.num_tracks def _on_selected_track_changed(self, *a, **k): super(Tweaker, self)._on_selected_track_changed(*a, **k) self._update_navigation_view() def connect_script_instances(self, instanciated_scripts): link = False for s in instanciated_scripts: if '_tweaker_version' in dir(s): if s._tweaker_version == self._tweaker_version_check: link = True break if link == True: if not self._session._is_linked(): self._session._link()