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 _setup_session_control(self): is_momentary = True num_tracks = COLS num_scenes = ROWS global session session = SessionComponent(num_tracks, num_scenes) session.name = "Session" session.set_offsets(0, 0) self._session = session self._session.set_stop_clip_value(0) self._scene = [None for index in range(ROWS)] 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) clip_slot.set_triggered_to_play_value(64) clip_slot.set_triggered_to_record_value(64) clip_slot.set_stopped_value(0) clip_slot.set_started_value(64) clip_slot.set_recording_value(64) #clip_slot.set_launch_button(self._grid[column][row]) #comment out if you don't want clip launch session.set_mixer(mixer) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_stopped_value(0) self._session_zoom.set_playing_value(64) self._session_zoom.set_selected_value(64) if STANDALONE is True: self.set_highlighting_session_component(self._session) self._session.set_track_bank_buttons(self._grid[5][3], self._grid[4][3]) #comment out when using with Griid self._session.set_scene_bank_buttons(self._grid[7][3], self._grid[6][3]) # comment out when using with Griid
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_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 _setup_session_control(self): is_momentary = True num_tracks = COLS num_scenes = ROWS global session session = SessionComponent(num_tracks, num_scenes) session.name = "Session" session.set_offsets(0, 0) self._session = session self._session.set_stop_clip_value(0) self._scene = [None for index in range(ROWS)] 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) clip_slot.set_triggered_to_play_value(64) clip_slot.set_triggered_to_record_value(64) clip_slot.set_stopped_value(0) clip_slot.set_started_value(64) clip_slot.set_recording_value(64) # clip_slot.set_launch_button(self._grid[column][row]) #comment out if you don't want clip launch session.set_mixer(mixer) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = "Session_Overview" self._session_zoom.set_stopped_value(0) self._session_zoom.set_playing_value(64) self._session_zoom.set_selected_value(64) if STANDALONE is True: self.set_highlighting_session_component(self._session) self._session.set_track_bank_buttons( self._grid[5][3], self._grid[4][3] ) # comment out when using with Griid self._session.set_scene_bank_buttons( self._grid[7][3], self._grid[6][3] ) # comment out when using with Griid
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ #def log(self, message): # self._control_surface.log_message((' ' + message + ' ').center(50, '=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface): #verify matrix dimentions assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) #super constructor #inject ControlSurface and OSD components (M4L) self._osd = osd self._control_surface = control_surface #initialize index variables self._mode_index = 0 #Inherited from parent self._main_mode_index = 0 #LP original modes self._sub_mode_list = [0, 0, 0, 0] for index in range(4): self._sub_mode_list[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS:#session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self._control_surface, self) else:#no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self) #initialize _session variables self._session.set_osd(self._osd) self._session.name = 'Session_Control' #initialize _zooming variables self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning = True) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value("Default.Button.Off") self._matrix = matrix self._side_buttons = side_buttons#launch buttons self._nav_buttons = top_buttons[:4]#arrow buttons self._config_button = config_button#used to reset launchpad self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) #User2 stepSequencer (Drum) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq.set_osd(self._osd) #User2 stepSequencer (Melodic) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq2.set_osd(self._osd) #User1 Instrument controller (Scale) self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._instrument_controller.set_osd(self._osd) #self._instrument_controller = None #User1 Device controller (Fx or Instrument parameters) self._device_controller = DeviceComponent(control_surface = self._control_surface, matrix = self._matrix, side_buttons = self._side_buttons, top_buttons = self._nav_buttons) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][0] #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer) assert mode in range(self.number_of_modes()) # 8 for this script if self._main_mode_index == mode: if self._main_mode_index == 1: #user mode 1 and device controller and instrument mode self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 2: #user mode 2 and step sequencer self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 3: #Mixer mode self.update() else: #Session mode self._sub_mode_list[self._main_mode_index] = 0 self._mode_index = 0 else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self.__main_mode_index != mode) or (mode == 3) or True): # self._main_mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 1 + 3 + 3 + 1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): self._modes_buttons[0].set_on_off_values("Mode.Session.On","Mode.Session.Off") self._modes_buttons[3].set_on_off_values("Mode.Mixer.On","Mode.Mixer.Off") mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]]) mode2 = self.getSkinName(Settings.USER_MODES[3 + self._sub_mode_list[2]]) self._modes_buttons[1].set_on_off_values("Mode."+mode1+".On","Mode."+mode1+".Off") self._modes_buttons[2].set_on_off_values("Mode."+mode2+".On","Mode."+mode2+".Off") for index in range(4): if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def getSkinName(self, user2Mode): if user2Mode=="instrument": user2Mode = "Note" if user2Mode=="device": user2Mode = "Device" if user2Mode=="user 1": user2Mode = "User" if user2Mode=="user 2": user2Mode = "User2" if user2Mode=="drum stepseq": user2Mode = "StepSequencer" if user2Mode=="melodic stepseq": user2Mode = "StepSequencer2" return user2Mode def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index == 0: new_channel = 0 # session elif self._main_mode_index == 1: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 11 # instrument controller # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 3 # device controller elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 4 # plain user mode 1 elif self._main_mode_index == 2: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 1 # step seq elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 2 # melodic step seq elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 5 # plain user mode 2 elif self._main_mode_index == 3: # mixer modes # mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) #Set LP double buffering mode (investigate this) self._config_button.send_value(1) #Set LP X-Y layout grid mapping mode if self._main_mode_index == 0: # session self._control_surface.show_message("SESSION MODE" ) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() self._mode_index = 0 elif self._main_mode_index == 1 or self._main_mode_index == 2: self._setup_sub_mode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_list[self._main_mode_index] ] ) elif self._main_mode_index == 3: # mixer self._control_surface.show_message("MIXER MODE") self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() self._mode_index = 3 else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) def _setup_sub_mode(self, mode): as_active = True as_enabled = True if mode == "instrument": self._control_surface.show_message("INSTRUMENT MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) self._mode_index = 4 elif mode == "melodic stepseq": self._control_surface.show_message("MELODIC SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) self._update_control_channels() self._mode_index = 7 elif mode == "user 1": self._control_surface.show_message("USER 1 MODE" ) self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() self._mode_index = 1 self._osd.clear() self._osd.mode = "User 1" self._osd.update() elif mode == "drum stepseq": self._control_surface.show_message("DRUM SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) self._update_control_channels() self._mode_index = 6 elif mode == "device": self._control_surface.show_message("DEVICE CONTROLLER MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() self._mode_index = 5 elif mode == "user 2": self._control_surface.show_message("USER 2 MODE" ) self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() self._mode_index = 2 self._osd.clear() self._osd.mode = "User 2" self._osd.update() def _setup_session(self, as_active, as_navigation_enabled): assert isinstance(as_active, type(False))#assert is boolean for button in self._nav_buttons: if as_navigation_enabled: button.set_on_off_values("Mode.Session.On", "Mode.Session.Off") else: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") # matrix self._activate_matrix(True) for scene_index in range(self._session._num_scenes):#iterate over scenes scene = self._session.scene(scene_index) if as_active:#set scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(self._session._num_tracks):#iterate over tracks of a scene -> clip slots if as_active:#set clip slot launch button button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active:#Set up stop clip buttons and stop all clips button if self._session._stop_clip_buttons != None: for button in self._session._stop_clip_buttons: button.set_enabled(as_active) # button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons) self._side_buttons[self._session._num_scenes].set_enabled(as_active) self._side_buttons[self._session._num_scenes].set_on_off_values("Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes]) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) if as_active:# zoom self._zooming.set_zoom_button(self._modes_buttons[0])# Set Session button as zoom button, wrong behavior??? self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_navigation_enabled: # nav buttons (track/scene) self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, as_active): if self._instrument_controller != None: if as_active: self._activate_matrix(False) #Disable matrix buttons (clip slots) self._activate_scene_buttons(True)#Enable side buttons self._activate_navigation_buttons(True)#Enable nav buttons else: for scene_index in range(8):#Restore all matrix buttons and scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.use_default_message() # Reset to original channel scene_button.force_next_send() #Flush for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.use_default_message()# Reset to original channel button.force_next_send()#Flush self._instrument_controller.set_enabled(as_active)#Enable/disable instrument controller def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True): # user1 -> All True but release_nav_buttons / user2 -> All false for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled((not release_side_buttons))#User2 enabled for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled((not release_matrix))#User2 enabled for button in self._nav_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled((not release_nav_buttons)) #User1 & User2 enabled if drum_rack_mode:#User1 enabled self._config_button.send_value(2)#Set LP drum rack layout grid mapping mode self._config_button.send_value(32)#Send enable flashing led config message to LP def _setup_step_sequencer(self, as_active): if(self._stepseq != None): #if(self._stepseq.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if(self._stepseq2 != None): #if(self._stepseq2.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if(self._sub_modes.is_enabled()):# go back to default mode self._sub_modes.set_mode(-1) else: self._sub_modes.release_controls() self._sub_modes.set_enabled(as_active) def _init_session(self): #self._session.set_stop_clip_value("Session.StopClip") #self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop") session_height = self._matrix.height() if self._session._stop_clip_buttons != None: session_height = self._matrix.height()-1 for scene_index in range(session_height): # scene = self._session.scene(scene_index) # scene.set_triggered_value("Session.SceneTriggered") # scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): # clip_slot = scene.clip_slot(track_index) # clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay") # clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord") # clip_slot.set_stopped_value("Session.ClipStopped") # clip_slot.set_started_value("Session.ClipStarted") # clip_slot.set_recording_value("Session.ClipRecording") # clip_slot.set_record_button_value("Session.RecordButton") # clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append(self._matrix.get_button(track_index, scene_index)) #self._zooming.set_stopped_value("Zooming.Stopped") #self._zooming.set_selected_value("Zooming.Selected") #self._zooming.set_playing_value("Zooming.Playing") def _activate_navigation_buttons(self, active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self, active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self, active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._control_surface.log_message(msg) # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.force_next_send()
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button): 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)
def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface): #verify matrix dimentions assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) #super constructor #inject ControlSurface and OSD components (M4L) self._osd = osd self._control_surface = control_surface #initialize index variables self._mode_index = 0 #Inherited from parent self._main_mode_index = 0 #LP original modes self._sub_mode_list = [0, 0, 0, 0] for index in range(4): self._sub_mode_list[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS: #session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append( matrix.get_button(column, matrix.height() - 1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height() - 1, clip_stop_buttons, self._control_surface, self) else: #no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self) #initialize _session variables self._session.set_osd(self._osd) self._session.name = 'Session_Control' #initialize _zooming variables self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning=True) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value("Default.Button.Off") self._matrix = matrix self._side_buttons = side_buttons #launch buttons self._nav_buttons = top_buttons[:4] #arrow buttons self._config_button = config_button #used to reset launchpad self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) #User2 stepSequencer (Drum & Melodic) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq.set_osd(self._osd) #User2 stepSequencer (Retro style) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq2.set_osd(self._osd) #User1 Instrument controller (Scale) self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._instrument_controller.set_osd(self._osd) #self._instrument_controller = None #User1 Device controller (Fx or Instrument parameters) self._device_controller = DeviceComponent( control_surface=self._control_surface, matrix=self._matrix, side_buttons=self._side_buttons, top_buttons=self._nav_buttons) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons)
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ #def log(self, message): # self._control_surface.log_message((' ' + message + ' ').center(50, '=')) def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface): #verify matrix dimentions assert isinstance(matrix, ButtonMatrixElement) assert ((matrix.width() == 8) and (matrix.height() == 8)) assert isinstance(top_buttons, tuple) assert (len(top_buttons) == 8) assert isinstance(side_buttons, tuple) assert (len(side_buttons) == 8) assert isinstance(config_button, ButtonElement) ModeSelectorComponent.__init__(self) #super constructor #inject ControlSurface and OSD components (M4L) self._osd = osd self._control_surface = control_surface #initialize index variables self._mode_index = 0 #Inherited from parent self._main_mode_index = 0 #LP original modes self._sub_mode_list = [0, 0, 0, 0] for index in range(4): self._sub_mode_list[index] = 0 self.set_mode_buttons(top_buttons[4:]) if Settings.SESSION__STOP_BUTTONS: #session with bottom stop buttons clip_stop_buttons = [] for column in range(8): clip_stop_buttons.append( matrix.get_button(column, matrix.height() - 1)) self._session = SpecialSessionComponent(matrix.width(), matrix.height() - 1, clip_stop_buttons, self._control_surface, self) else: #no stop buttons self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self) #initialize _session variables self._session.set_osd(self._osd) self._session.name = 'Session_Control' #initialize _zooming variables self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning=True) self._zooming.name = 'Session_Overview' self._zooming.set_empty_value("Default.Button.Off") self._matrix = matrix self._side_buttons = side_buttons #launch buttons self._nav_buttons = top_buttons[:4] #arrow buttons self._config_button = config_button #used to reset launchpad self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface) self._sub_modes.name = 'Mixer_Modes' self._sub_modes._mixer.set_osd(self._osd) self._sub_modes.set_update_callback(self._update_control_channels) #User2 stepSequencer (Drum & Melodic) self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq.set_osd(self._osd) #User2 stepSequencer (Retro style) self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._stepseq2.set_osd(self._osd) #User1 Instrument controller (Scale) self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons, self._control_surface) self._instrument_controller.set_osd(self._osd) #self._instrument_controller = None #User1 Device controller (Fx or Instrument parameters) self._device_controller = DeviceComponent( control_surface=self._control_surface, matrix=self._matrix, side_buttons=self._side_buttons, top_buttons=self._nav_buttons) self._device_controller.set_osd(self._osd) self._init_session() self._all_buttons = tuple(self._all_buttons) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def _update_mode(self): mode = self._modes_heap[-1][ 0] #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer) assert mode in range(self.number_of_modes()) # 8 for this script if self._main_mode_index == mode: if self._main_mode_index == 1: #user mode 1 and device controller and instrument mode self._sub_mode_list[self._main_mode_index] = ( self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 2: #user mode 2 and step sequencer self._sub_mode_list[self._main_mode_index] = ( self._sub_mode_list[self._main_mode_index] + 1) % 3 self.update() elif self._main_mode_index == 3: #Mixer mode self.update() else: #Session mode self._sub_mode_list[self._main_mode_index] = 0 self._mode_index = 0 else: self._main_mode_index = mode self.update() def set_mode(self, mode): self._clean_heap() self._modes_heap = [(mode, None, None)] # if ((self.__main_mode_index != mode) or (mode == 3) or True): # self._main_mode_index = mode # self._update_mode() # self.update() def number_of_modes(self): return 1 + 3 + 3 + 1 def on_enabled_changed(self): self.update() def _update_mode_buttons(self): self._modes_buttons[0].set_on_off_values("Mode.Session.On", "Mode.Session.Off") self._modes_buttons[3].set_on_off_values("Mode.Mixer.On", "Mode.Mixer.Off") mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]]) mode2 = self.getSkinName(Settings.USER_MODES[3 + self._sub_mode_list[2]]) self._modes_buttons[1].set_on_off_values("Mode." + mode1 + ".On", "Mode." + mode1 + ".Off") self._modes_buttons[2].set_on_off_values("Mode." + mode2 + ".On", "Mode." + mode2 + ".Off") for index in range(4): if (index == self._main_mode_index): self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() def getSkinName(self, user2Mode): if user2Mode == "instrument": user2Mode = "Note" if user2Mode == "device": user2Mode = "Device" if user2Mode == "user 1": user2Mode = "User" if user2Mode == "user 2": user2Mode = "User2" if user2Mode == "drum stepseq": user2Mode = "StepSequencer" if user2Mode == "melodic stepseq": user2Mode = "StepSequencer2" return user2Mode def channel_for_current_mode(self): # in this code, midi channels start at 0. # so channels range from 0 - 15. # mapping to 1-16 in the real world if self._main_mode_index == 0: new_channel = 0 # session elif self._main_mode_index == 1: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 11 # instrument controller # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15 if self._instrument_controller != None: self._instrument_controller.base_channel = new_channel elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 3 # device controller elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 4 # plain user mode 1 elif self._main_mode_index == 2: if self._sub_mode_list[self._main_mode_index] == 0: new_channel = 1 # step seq elif self._sub_mode_list[self._main_mode_index] == 1: new_channel = 2 # melodic step seq elif self._sub_mode_list[self._main_mode_index] == 2: new_channel = 5 # plain user mode 2 elif self._main_mode_index == 3: # mixer modes # mixer uses base channel 7 and the 4 next ones. new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10 return new_channel def update(self): assert (self._modes_buttons != None) if self.is_enabled(): self._update_mode_buttons() as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value( 40) #Set LP double buffering mode (investigate this) self._config_button.send_value( 1) #Set LP X-Y layout grid mapping mode if self._main_mode_index == 0: # session self._control_surface.show_message("SESSION MODE") self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(as_active, as_enabled) self._update_control_channels() self._mode_index = 0 elif self._main_mode_index == 1 or self._main_mode_index == 2: self._setup_sub_mode(Settings.USER_MODES[ (self._main_mode_index - 1) * 3 + self._sub_mode_list[self._main_mode_index]]) elif self._main_mode_index == 3: # mixer self._control_surface.show_message("MIXER MODE") self._setup_device_controller(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_instrument_controller(not as_active) self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) self._update_control_channels() self._mode_index = 3 else: assert False self._session.set_allow_update(True) self._zooming.set_allow_update(True) def _setup_sub_mode(self, mode): as_active = True as_enabled = True if mode == "instrument": self._control_surface.show_message("INSTRUMENT MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._update_control_channels() self._setup_instrument_controller(as_active) self._mode_index = 4 elif mode == "melodic stepseq": self._control_surface.show_message("MELODIC SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(as_active) self._update_control_channels() self._mode_index = 7 elif mode == "user 1": self._control_surface.show_message("USER 1 MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_device_controller(not as_active) self._setup_instrument_controller(not as_active) self._setup_user_mode(True, True, False, True) self._update_control_channels() self._mode_index = 1 self._osd.clear() self._osd.mode = "User 1" self._osd.update() elif mode == "drum stepseq": self._control_surface.show_message("DRUM STEP SEQUENCER MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_step_sequencer(as_active) self._update_control_channels() self._mode_index = 6 elif mode == "device": self._control_surface.show_message("DEVICE CONTROLLER MODE") self._setup_session(not as_active, not as_enabled) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_mixer(not as_active) self._setup_instrument_controller(not as_active) self._setup_device_controller(as_active) self._update_control_channels() self._mode_index = 5 elif mode == "user 2": self._control_surface.show_message("USER 2 MODE") self._setup_session(not as_active, not as_enabled) self._setup_instrument_controller(not as_active) self._setup_device_controller(not as_active) self._setup_mixer(not as_active) self._setup_step_sequencer(not as_active) self._setup_step_sequencer2(not as_active) self._setup_user_mode(False, False, False, False) self._update_control_channels() self._mode_index = 2 self._osd.clear() self._osd.mode = "User 2" self._osd.update() def _setup_session(self, as_active, as_navigation_enabled): assert isinstance(as_active, type(False)) #assert is boolean for button in self._nav_buttons: if as_navigation_enabled: button.set_on_off_values("Mode.Session.On", "Mode.Session.Off") else: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") # matrix self._activate_matrix(True) for scene_index in range( self._session._num_scenes): #iterate over scenes scene = self._session.scene(scene_index) if as_active: #set scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.set_enabled(as_active) scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range( self._session._num_tracks ): #iterate over tracks of a scene -> clip slots if as_active: #set clip slot launch button button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.set_enabled(as_active) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: #Set up stop clip buttons and stop all clips button if self._session._stop_clip_buttons != None: for button in self._session._stop_clip_buttons: button.set_enabled(as_active) # button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_track_clip_buttons( self._session._stop_clip_buttons) self._side_buttons[self._session._num_scenes].set_enabled( as_active) self._side_buttons[ self._session._num_scenes].set_on_off_values( "Session.StopClip", "DefaultButton.Disabled") self._session.set_stop_all_clips_button( self._side_buttons[self._session._num_scenes]) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) else: self._session.set_stop_track_clip_buttons(None) self._session.set_stop_all_clips_button(None) if as_active: # zoom self._zooming.set_zoom_button( self._modes_buttons[0] ) # Set Session button as zoom shift button self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) if as_navigation_enabled: # nav buttons (track/scene) self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_instrument_controller(self, as_active): if self._instrument_controller != None: if as_active: self._activate_matrix( False) #Disable matrix buttons (clip slots) self._activate_scene_buttons(True) #Enable side buttons self._activate_navigation_buttons(True) #Enable nav buttons else: for scene_index in range( 8 ): #Restore all matrix buttons and scene launch buttons scene_button = self._side_buttons[scene_index] scene_button.use_default_message( ) # Reset to original channel scene_button.force_next_send() #Flush for track_index in range(8): button = self._matrix.get_button( track_index, scene_index) button.use_default_message( ) # Reset to original channel button.force_next_send() #Flush self._instrument_controller.set_enabled( as_active) #Enable/disable instrument controller def _setup_device_controller(self, as_active): if self._device_controller != None: if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._device_controller._is_active = True self._config_button.send_value(32) self._device_controller.set_enabled(True) self._device_controller.update() else: self._device_controller._is_active = False self._device_controller.set_enabled(False) def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True): # user1 -> All True but release_nav_buttons / user2 -> All false for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") scene_button.force_next_send() scene_button.turn_off() scene_button.set_enabled( (not release_side_buttons)) #User2 enabled for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled((not release_matrix)) #User2 enabled for button in self._nav_buttons: button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled") button.turn_off() button.set_enabled( (not release_nav_buttons)) #User1 & User2 enabled if drum_rack_mode: #User1 enabled self._config_button.send_value( 2) #Set LP drum rack layout grid mapping mode self._config_button.send_value( 32) #Send enable flashing led config message to LP def _setup_step_sequencer(self, as_active): if (self._stepseq != None): #if(self._stepseq.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq.set_enabled(True) else: self._stepseq.set_enabled(False) def _setup_step_sequencer2(self, as_active): if (self._stepseq2 != None): #if(self._stepseq2.is_enabled() != as_active): if as_active: self._activate_scene_buttons(True) self._activate_matrix(True) self._activate_navigation_buttons(True) self._config_button.send_value(32) self._stepseq2.set_enabled(True) else: self._stepseq2.set_enabled(False) def _setup_mixer(self, as_active): assert isinstance(as_active, type(False)) if as_active: self._activate_navigation_buttons(True) self._activate_scene_buttons(True) self._activate_matrix(True) if (self._sub_modes.is_enabled()): # go back to default mode self._sub_modes.set_mode(-1) else: self._sub_modes.release_controls() self._sub_modes.set_enabled(as_active) def _init_session(self): #self._session.set_stop_clip_value("Session.StopClip") #self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop") session_height = self._matrix.height() if self._session._stop_clip_buttons != None: session_height = self._matrix.height() - 1 for scene_index in range(session_height): # scene = self._session.scene(scene_index) # scene.set_triggered_value("Session.SceneTriggered") # scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): # clip_slot = scene.clip_slot(track_index) # clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay") # clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord") # clip_slot.set_stopped_value("Session.ClipStopped") # clip_slot.set_started_value("Session.ClipStarted") # clip_slot.set_recording_value("Session.ClipRecording") # clip_slot.set_record_button_value("Session.RecordButton") # clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) #self._zooming.set_stopped_value("Zooming.Stopped") #self._zooming.set_selected_value("Zooming.Selected") #self._zooming.set_playing_value("Zooming.Playing") def _activate_navigation_buttons(self, active): for button in self._nav_buttons: button.set_enabled(active) def _activate_scene_buttons(self, active): for button in self._side_buttons: button.set_enabled(active) def _activate_matrix(self, active): for scene_index in range(8): for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(active) def log_message(self, msg): self._control_surface.log_message(msg) # Update the channels of the buttons in the user modes.. def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.force_next_send()
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_session_control(self): is_momentary = True num_tracks = 4 num_scenes = 5 self._session = NameServerSessionComponent(num_tracks, num_scenes, self) self._session.name = "Left_Session" self._session.set_offsets(0, 0) self._session.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene = [None for index in range(5)] for row in range(num_scenes): self._scene[row] = self._session.scene(row) self._scene[row].name = 'L_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_L_' + str(row) clip_slot.set_triggered_to_play_value(self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value(self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value(self._color_defs['CLIP_RECORDING']) self._session.set_mixer(self._mixer) self._session_zoom = SessionZoomingComponent(self._session) self._session_zoom.name = 'L_Session_Overview' self._session_zoom.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom.set_selected_value(self._color_defs['ZOOM_SELECTED']) self._session_zoom._zoom_button = (self._dummy_button) self._session_zoom.set_enabled(True) self._session2 = SessionComponent(num_tracks, num_scenes) self._session2.name = 'Right_Session' self._session2.set_offsets(4, 0) self._session2.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene2 = [None for index in range(5)] for row in range(num_scenes): self._scene2[row] = self._session2.scene(row) self._scene2[row].name = 'R_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene2[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_R_' + str(row) clip_slot.set_triggered_to_play_value(self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value(self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value(self._color_defs['CLIP_RECORDING']) self._session2.set_mixer(self._mixer2) self._session2.add_offset_listener(self._on_session_offset_changes) self._session_zoom2 = SessionZoomingComponent(self._session2) self._session_zoom2.name = 'R_Session_Overview' self._session_zoom2.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom2.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom2.set_selected_value(self._color_defs['ZOOM_SELECTED']) self._session_zoom.set_enabled(True) self._session_zoom2._zoom_button = (self._dummy_button2) self._session_main = SessionComponent(8, num_scenes) self._session_main.name = 'Main_Session' self._session_main.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene_main = [None for index in range(5)] for row in range(num_scenes): self._scene_main[row] = self._session_main.scene(row) self._scene_main[row].name = 'M_Scene_' + str(row) for column in range(8): clip_slot = self._scene_main[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_M_' + str(row) clip_slot.set_triggered_to_play_value(self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value(self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value(self._color_defs['CLIP_RECORDING']) self._session_main.set_mixer(self._mixer) self._session_zoom_main = SessionZoomingComponent(self._session_main) self._session_zoom_main.name = 'M_Session_Overview' self._session_zoom_main.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom_main.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom_main.set_selected_value(self._color_defs['ZOOM_SELECTED']) self._session_zoom_main.set_enabled(True) self._session_zoom_main._zoom_button = (self._dummy_button3) self._sessions = [self._session, self._session2, self._session_main] self._zooms = [self._session_zoom, self._session_zoom2, self._session_zoom_main]
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 _setup_session_control(self): is_momentary = True num_tracks = 4 num_scenes = 5 self._session = NameServerSessionComponent(num_tracks, num_scenes, self) self._session.name = "Left_Session" self._session.set_offsets(0, 0) self._session.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene = [None for index in range(5)] for row in range(num_scenes): self._scene[row] = self._session.scene(row) self._scene[row].name = 'L_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_L_' + str(row) clip_slot.set_triggered_to_play_value( self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value( self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value( self._color_defs['CLIP_RECORDING']) self._session.set_mixer(self._mixer) self._session_zoom = SessionZoomingComponent(self._session) self._session_zoom.name = 'L_Session_Overview' self._session_zoom.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom.set_selected_value( self._color_defs['ZOOM_SELECTED']) self._session_zoom._zoom_button = (self._dummy_button) self._session_zoom.set_enabled(True) self._session2 = SessionComponent(num_tracks, num_scenes) self._session2.name = 'Right_Session' self._session2.set_offsets(4, 0) self._session2.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene2 = [None for index in range(5)] for row in range(num_scenes): self._scene2[row] = self._session2.scene(row) self._scene2[row].name = 'R_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene2[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_R_' + str(row) clip_slot.set_triggered_to_play_value( self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value( self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value( self._color_defs['CLIP_RECORDING']) self._session2.set_mixer(self._mixer2) self._session2.add_offset_listener(self._on_session_offset_changes) self._session_zoom2 = SessionZoomingComponent(self._session2) self._session_zoom2.name = 'R_Session_Overview' self._session_zoom2.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom2.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom2.set_selected_value( self._color_defs['ZOOM_SELECTED']) self._session_zoom.set_enabled(True) self._session_zoom2._zoom_button = (self._dummy_button2) self._session_main = SessionComponent(8, num_scenes) self._session_main.name = 'Main_Session' self._session_main.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene_main = [None for index in range(5)] for row in range(num_scenes): self._scene_main[row] = self._session_main.scene(row) self._scene_main[row].name = 'M_Scene_' + str(row) for column in range(8): clip_slot = self._scene_main[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_M_' + str(row) clip_slot.set_triggered_to_play_value( self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value( self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value( self._color_defs['CLIP_RECORDING']) self._session_main.set_mixer(self._mixer) self._session_zoom_main = SessionZoomingComponent(self._session_main) self._session_zoom_main.name = 'M_Session_Overview' self._session_zoom_main.set_stopped_value( self._color_defs['ZOOM_STOPPED']) self._session_zoom_main.set_playing_value( self._color_defs['ZOOM_PLAYING']) self._session_zoom_main.set_selected_value( self._color_defs['ZOOM_SELECTED']) self._session_zoom_main.set_enabled(True) self._session_zoom_main._zoom_button = (self._dummy_button3) self._sessions = [self._session, self._session2, self._session_main] self._zooms = [ self._session_zoom, self._session_zoom2, self._session_zoom_main ]
class LemurPad(MonOhm): __module__ = __name__ __doc__ = " Lemur version of the MonOhm companion controller script " def __init__(self, *a, **k): self._timer_callbacks = [ ] #Used for _monobridge, which uses L8 method for registering timer callbacks. deprecated, needs to be replaced by new L9 Task class. self._osc_registry = {} self._display_button_names = DISPLAY_BUTTON_NAMES super(LemurPad, self).__init__(*a, **k) self._host_name = "LemurPad" self._color_type = 'AumPad' self.connected = 0 with self.component_guard(): self._setup_touchosc() self._assign_host2() self._assign_session_colors() def query_ohm(self): pass """script initialization methods""" def _setup_monobridge(self): self._monobridge = OSCMonoBridgeElement(self) self._monobridge.name = 'MonoBridge' 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] = OSCMonoEncoderElement( MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self, osc='/Fader_' + str(index) + '/x', osc_parameter='/Strip' + str(index + 8) + '/set', osc_name='/Strip' + str(index) + '/set') for index in range(8): self._button[index] = OSCMonoButtonElement( is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self, osc='/Select_' + str(index) + '/value', osc_alt='/Select/set ' + str(index), osc_name='/Select/text ' + str(index)) for index in range(16): self._dial[index] = OSCMonoEncoderElement( MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index + 8, self, osc='/Dial_' + str(index) + '/x', osc_parameter='/Dial' + str(index) + 'val/set', osc_name='/Dial' + str(index) + 'name/set') for index in range(6): self._menu[index] = OSCMonoButtonElement( is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self, osc='/Function_' + str(index) + '/value', osc_alt='/Function/set ' + str(index), osc_name='/Function/text ' + str(index)) self._crossfader = OSCMonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute, "Crossfader", 24, self, osc='/XFader/x', osc_parameter='/XFader/none', osc_name=None) self._livid = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self, osc='/Livid/x', osc_alt='/Livid/x', osc_name=None) self._shift_l = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Shift_Button_Left', self, osc='/ShiftL/x', osc_alt='/ShiftL/x', osc_name=None) self._shift_r = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Shift_Button_Right', self, osc='/ShiftR/x', osc_alt='/ShiftR/x', osc_name=None) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._monomod = ButtonMatrixElement() self._monomod.name = 'Monomod' self._grid = [None for index in range(8)] for column in range(8): self._grid[column] = [None for index in range(8)] for row in range(8): self._grid[column][row] = OSCMonoButtonElement( is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self, osc='/ClipGrid_' + str(column) + '_' + str(row) + '/value', osc_alt='/ClipGrid/set ' + str(column) + ' ' + str(row), osc_name='/ClipGrid/text ' + str(column) + ' ' + str(row)) 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._dummy_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 125) self._dummy_button.name = 'Dummy1' self._dummy_button2 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 126) self._dummy_button2.name = 'Dummy2' self._dummy_button3 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 127) self._dummy_button2.name = 'Dummy3' self._monomod256 = ButtonMatrixElement() self._monomod256.name = 'Monomod256' self._square = [None for index in range(16)] for column in range(16): self._square[column] = [None for index in range(16)] for row in range(16): self._square[column][row] = OSCMonoButtonElement( is_momentary, MIDI_NOTE_TYPE, int(column / 8) + 1, row + ((column % 8) * 16), '256Grid_' + str(column) + '_' + str(row), self, osc='/Grid_' + str(column) + '_' + str(row) + '/value', osc_alt='/Grid/set ' + str(column) + ' ' + str(row), osc_name=None) #self._square[column][row] = FlashingButtonElement(is_momentary, 0, 15, -1, '256Grid_' + str(column) + '_' + str(row), '/1/p_grid/'+str(column)+'/'+str(row), '/1/c_grid/'+str(column)+'/'+str(row), self) for row in range(16): button_row = [] for column in range(16): button_row.append(self._square[column][row]) self._monomod256.add_row(tuple(button_row)) self._bank_buttons = ButtonMatrixElement() self._key_buttons = ButtonMatrixElement() self._bank_button = [None for index in range(2)] for index in range(2): self._bank_button[index] = OSCMonoButtonElement( is_momentary, MIDI_NOTE_TYPE, 15, index, '256Grid_Bank_' + str(index), self, osc='/Shift_' + str(index) + '/value', osc_alt='/Shift/set ' + str(index), osc_name=None) button_row = [] for index in range(2): button_row.append(self._bank_button[index]) self._bank_buttons.add_row(tuple(button_row)) button_row = [] self._key_button = [None for index in range(8)] for index in range(8): self._key_button[index] = OSCMonoButtonElement( is_momentary, MIDI_NOTE_TYPE, 15, index + 8, '256Grid_Key_' + str(index), self, osc='/Keys_' + str(index) + '/value', osc_alt='/Keys/set ' + str(index), osc_name=None) for index in range(8): button_row.append(self._key_button[index]) self._key_buttons.add_row(tuple(button_row)) def _setup_session_control(self): is_momentary = True num_tracks = 4 num_scenes = 5 self._session = NameServerSessionComponent(num_tracks, num_scenes, self) self._session.name = "Left_Session" self._session.set_offsets(0, 0) self._session.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene = [None for index in range(5)] for row in range(num_scenes): self._scene[row] = self._session.scene(row) self._scene[row].name = 'L_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_L_' + str(row) clip_slot.set_triggered_to_play_value( self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value( self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value( self._color_defs['CLIP_RECORDING']) self._session.set_mixer(self._mixer) self._session_zoom = SessionZoomingComponent(self._session) self._session_zoom.name = 'L_Session_Overview' self._session_zoom.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom.set_selected_value( self._color_defs['ZOOM_SELECTED']) self._session_zoom._zoom_button = (self._dummy_button) self._session_zoom.set_enabled(True) self._session2 = SessionComponent(num_tracks, num_scenes) self._session2.name = 'Right_Session' self._session2.set_offsets(4, 0) self._session2.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene2 = [None for index in range(5)] for row in range(num_scenes): self._scene2[row] = self._session2.scene(row) self._scene2[row].name = 'R_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene2[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_R_' + str(row) clip_slot.set_triggered_to_play_value( self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value( self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value( self._color_defs['CLIP_RECORDING']) self._session2.set_mixer(self._mixer2) self._session2.add_offset_listener(self._on_session_offset_changes) self._session_zoom2 = SessionZoomingComponent(self._session2) self._session_zoom2.name = 'R_Session_Overview' self._session_zoom2.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom2.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom2.set_selected_value( self._color_defs['ZOOM_SELECTED']) self._session_zoom.set_enabled(True) self._session_zoom2._zoom_button = (self._dummy_button2) self._session_main = SessionComponent(8, num_scenes) self._session_main.name = 'Main_Session' self._session_main.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene_main = [None for index in range(5)] for row in range(num_scenes): self._scene_main[row] = self._session_main.scene(row) self._scene_main[row].name = 'M_Scene_' + str(row) for column in range(8): clip_slot = self._scene_main[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_M_' + str(row) clip_slot.set_triggered_to_play_value( self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value( self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value( self._color_defs['CLIP_RECORDING']) self._session_main.set_mixer(self._mixer) self._session_zoom_main = SessionZoomingComponent(self._session_main) self._session_zoom_main.name = 'M_Session_Overview' self._session_zoom_main.set_stopped_value( self._color_defs['ZOOM_STOPPED']) self._session_zoom_main.set_playing_value( self._color_defs['ZOOM_PLAYING']) self._session_zoom_main.set_selected_value( self._color_defs['ZOOM_SELECTED']) self._session_zoom_main.set_enabled(True) self._session_zoom_main._zoom_button = (self._dummy_button3) self._sessions = [self._session, self._session2, self._session_main] self._zooms = [ self._session_zoom, self._session_zoom2, self._session_zoom_main ] def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = LemurOhmModHandler(self) self.modhandler.name = 'ModHandler' self.modhandler256 = LemurModHandler(self) self.modhandler256.name = 'ModHandler256' def _assign_host2(self): self.modhandler256.set_shift_button(self._bank_button[0]) self.modhandler256.set_alt_button(self._bank_button[1]) self.modhandler256.set_grid(self._monomod256) self.modhandler256.set_key_buttons(self._key_buttons) self.modhandler256.set_enabled(True) def _setup_touchosc(self): self._osc_registry = {} #self._osc_registry['/ping'] = self._monobridge.ping #self._osc_registry['/1'] = self._monobridge.page1 #self._osc_registry['/2'] = self._monobridge.page2 for control in self.controls: if hasattr(control, 'osc'): self._osc_registry[control.osc] = control.set_value #if hasattr(control, 'osc_alt'): # self._osc_registry[control.osc_alt] = control.set_value #self.log_message('create dict key: ' + str(control.osc) + str(control.name)) """shift/zoom methods""" def deassign_matrix(self): super(LemurPad, self).deassign_matrix() self.clear_grid_names() """menu button management methods""" def deassign_menu(self): super(LemurPad, self).deassign_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(' ')) def assign_device_nav_to_menu(self): super(LemurPad, self).assign_device_nav_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(DEVICE_NAV_NAMES[index]))) def assign_transport_to_menu(self): super(LemurPad, self).assign_transport_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(TRANSPORT_NAMES[index]))) def assign_session_nav_to_menu(self): super(LemurPad, self).assign_session_nav_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(SESSION_NAV_NAMES[index]))) def assign_session_main_nav_to_menu(self): super(LemurPad, self).assign_session_main_nav_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(SESSION_NAV_NAMES[index]))) def assign_monomod_shift_to_menu(self): super(LemurPad, self).assign_monomod_shift_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(MONOMOD_SHIFT_NAMES[index]))) def assign_monomod_to_menu(self): super(LemurPad, self).assign_monomod_shift_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(MONOMOD_NAMES[index]))) def assign_session_bank_to_menu(self): super(LemurPad, self).assign_session_bank_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(SESSION_BANK_NAMES[index]))) def assign_session2_bank_to_menu(self): super(LemurPad, self).assign_session2_bank_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str(SESSION_BANK2_NAMES[index]))) def assign_session_main_nav_to_menu(self): super(LemurPad, self).assign_session_main_nav_to_menu() for index in range(6): self._monobridge._send_osc( self._menu[index].osc_name, self.generate_strip_string(str( SESSION_MAIN_BANK_NAMES[index]))) """m4l bridge""" def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 9 if (not display_string): return ('`_') 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 += ' ' assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return '`' + ret.replace(' ', '_') def notification_to_bridge(self, name, value, sender): if (isinstance(sender, MonoEncoderElement2)): #self.log_message(str(name) + str(value) + str(sender.num)) self._monobridge._send('lcd_name', sender.name, self.generate_strip_string(str(name))) self._monobridge._send('lcd_value', sender.name, self.generate_strip_string(str(value))) def clip_name(self, sender, name): #self.log_message('clip name ' + str(sender.osc_name) + ' ' + str(self.generate_strip_string(str(name)))) self._monobridge._send_osc(sender.osc_name, self.generate_strip_string(str(name))) """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(): clip_names.append(clip_slot._clip_slot)##.clip.name) #return clip_slot._clip_slot #self.log_message('clip name' + str(clip_slot._clip_slot.clip.name)) return clip_names""" """called on timer""" def update_display(self): super(LemurPad, self).update_display() for callback in self._timer_callbacks: callback() def strobe(self): pass """general functionality""" def disconnect(self): super(MonOhm, self).disconnect() def clear_grid_names(self): #self.log_message('clear grid names' + str(self)) for column in range(8): for row in range(8): self._monobridge._send_osc(self._grid[column][row].osc_name, '`_') def _register_timer_callback(self, callback): """ Registers a callback that is triggerd on every call of update_display """ assert (callback != None) assert (dir(callback).count('im_func') is 1) assert (self._timer_callbacks.count(callback) == 0) self._timer_callbacks.append(callback) return None def _unregister_timer_callback(self, callback): """ Unregisters a timer callback """ assert (callback != None) assert (dir(callback).count('im_func') is 1) assert (self._timer_callbacks.count(callback) == 1) self._timer_callbacks.remove(callback) return None def _set_brightness(self, value): #self._bright = (value != 0) #for control in self.controls: # if isinstance(control, OSCMonoButtonElement): # self._monobridge._send_osc(control.osc_alt, int(self._bright), True) pass def reset(self): #self._monobridge._send_osc('/reset') for control in self.controls: control.reset() def assign_lower_grid_names(self, mode): if self._display_button_names is True: for column in range(8): for row in range(3): self._monobridge._send_osc( self._grid[column][row + 5].osc_name, self.generate_strip_string( str(GRID_NAMES[mode][row][column]))) def reset_and_refresh_state(self, *a, **k): self.schedule_message(1, self.reset) self.schedule_message(2, self.refresh_state)
class code(ControlSurface): __module__ = __name__ __doc__ = " Code controller script " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= Code opened =--------------" ) # Writes message into Live's main log file. This is a ControlSurface method. self._send_midi(factoryreset) self._send_midi(btn_channels) self._send_midi(enc_channels) # self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up self._setup_controls() self._setup_device_controls() self._setup_mixer_control() # Setup the mixer object self._setup_transport_control() self._setup_session_control() # Setup the session object - do this last self._setup_modes() self._setup_m4l_interface() # self.set_suppress_rebuild_requests(False) # Turn rebuild back on, once we're done setting up ##self.assign_page_2() def handle_sysex(self, midi_bytes): self._send_midi(tuple([240, 00, 01, 97, 04, 15, 01, 247])) # response = [long(0),long(0)] # self.log_message(str(response)) 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_controls(self): is_momentary = True self._dial = [None for index in range(DIALCOUNT)] self._trackbtns = [None for index in range(8)] self._modebtns = [None for index in range(5)] for index in range(DIALCOUNT): self._dial[index] = EncoderElement(MIDI_CC_TYPE, CH, matrix_nums[index], Live.MidiMap.MapMode.absolute) self._dial[index].name = "Dial_" + str(index) self._dial[index].set_feedback_delay(-1) for index in range(8): self._trackbtns[index] = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]) self._trackbtns[index].name = "Button_" + str(index) for index in range(5): self._modebtns[index] = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, mode_select_notes[index]) self._modebtns[index].name = "ModeButton_" + str(index) self._matrix = ButtonMatrixElement() self._matrix.name = "Matrix" self._grid = [None for index in range(COLS)] for column in range(COLS): self._grid[column] = [None for index in range(COLS)] for row in range(ROWS): nn = 1 + (column * ROWS) + row self._grid[column][row] = ButtonElement( is_momentary, MIDI_NOTE_TYPE, CH, nn ) # comment out if you don't want clip launch self._grid[column][row].name = "Grid_" + str(column) + "_" + str(row) for row in range(ROWS): button_row = [] for column in range(COLS): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) """ not sure about this bit, but somehow I'll need to set up the modes here...!""" def _setup_modes(self): self._shift_mode = ShiftModeComponent(self, tuple(button for button in self._modebtns)) self._shift_mode.name = "Mix_Mode" # mode 1 # self._shift_mode.set_mode_buttons(self._modebtns) def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = "Transport" def _setup_mixer_control(self): is_momentary = True self._num_tracks = COLS global mixer mixer = MixerComponent(COLS, 0, True, True) mixer.name = "Mixer" self._mixer = mixer mixer.set_track_offset(0) # Sets start point for mixer strip (offset from left) for index in range(COLS): # use the bottom row of encoders for volume, so add 24 to offset the index mixer.channel_strip(index).set_volume_control(self._dial[index + 24]) for index in range(COLS): mixer.channel_strip(index).name = "Mixer_ChannelStrip_" + str(index) mixer.track_eq(index).name = "Mixer_EQ_" + str(index) mixer.track_filter(index).name = "Mixer_Filter_" + str(index) # added by a mixer.channel_strip(index)._invert_mute_feedback = True # mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index])) self.song().view.selected_track = 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 """ Technically, we aren't using the session control, but I'm going to set it up in case inter-script communication needs it""" def _setup_session_control(self): is_momentary = True num_tracks = COLS num_scenes = ROWS global session session = SessionComponent(num_tracks, num_scenes) session.name = "Session" session.set_offsets(0, 0) self._session = session self._session.set_stop_clip_value(0) self._scene = [None for index in range(ROWS)] 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) clip_slot.set_triggered_to_play_value(64) clip_slot.set_triggered_to_record_value(64) clip_slot.set_stopped_value(0) clip_slot.set_started_value(64) clip_slot.set_recording_value(64) # clip_slot.set_launch_button(self._grid[column][row]) #comment out if you don't want clip launch session.set_mixer(mixer) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = "Session_Overview" self._session_zoom.set_stopped_value(0) self._session_zoom.set_playing_value(64) self._session_zoom.set_selected_value(64) if STANDALONE is True: self.set_highlighting_session_component(self._session) self._session.set_track_bank_buttons( self._grid[5][3], self._grid[4][3] ) # comment out when using with Griid self._session.set_scene_bank_buttons( self._grid[7][3], self._grid[6][3] ) # comment out when using with Griid """this is where we take care of setting up the the multiple devices per page, we will need 4""" def _setup_device_controls(self): self._device = [None for index in range(4)] for index in range(ROWS): self._device[index] = DeviceComponent() self._device[index].name = "Device_Component_" + str(index) # self.set_device_component(self._device) #this doesn't work anymore, because we have multiple devices for the controller....we'll have to get fancy here, but that's for later # self._device_navigator = DetailViewControllerComponent() #its unclear if we'll need this....how is device navigation (i.e. banking for device parameter banks) going to be handled by the script? # self._device_navigator.name = 'Device_Navigator' device_param_controls = [] for control in range(COLS): """this setups up 8 device parameters per row""" # dial_index = control + (index*COLS) """alternatively, this setus up device controls in 4 4x2 groups""" dial_index = device_encoders[control + (index * COLS)] device_param_controls.append(self._dial[dial_index]) self._device[index].set_parameter_controls(tuple(device_param_controls)) """this is where we deassign every control that will be changing function when we switch modes...best to just deassign them all, and reassign them on update""" def deassign_matrix(self): for index in range( DIALCOUNT ): # this should totally work!!! I'm over appealing to Python's sadistic mannerisms right now.... self._dial[index].send_value( 0, True ) ##this is kind of a hack, and should be unnecessary; the bool at the end tells the send_value method to force the value out to the controller for index in range(COLS): self._mixer.track_eq(index).set_enabled(False) ##set_gain_controls(tuple([None for index in range(3)])) self._mixer.channel_strip(index).set_volume_control(None) self._mixer.track_filter(index).set_enabled(False) ##set_filter_controls(tuple([None, None])) self._mixer.channel_strip(index).set_pan_control(None) self._mixer.channel_strip(index).set_select_button(None) self._mixer.channel_strip(index).set_send_controls(tuple([None for index in range(4)])) for device in range(4): self._device[device].set_bank_nav_buttons(None, None) self._device[device].set_enabled(False) ##set_parameter_controls(tuple([None for index in range(8)])) for track in range(8): self._mixer.channel_strip(track).set_select_button(None) for scene in range(4): self._scene[scene].clip_slot(track).set_launch_button(None) # self.request_rebuild_midi_map() # I think this is causing problems updating the leds when in build? """EQ Hi/Mid/Low and volume""" def assign_page_0(self): """for each column""" is_momentary = True for index in range(COLS): self._mixer.track_eq(index).set_gain_controls( (self._dial[index + 16], self._dial[index + 8], self._dial[index]) ) self._mixer.track_eq(index).set_enabled(True) self._mixer.channel_strip(index).set_volume_control( self._dial[index + 24] ) # use the bottom row of encoders for volume, so add 24 to offset the index self._mixer.channel_strip(index).set_select_button(self._trackbtns[index]) self.assign_cliplaunch() self._mixer.update() """sends 1-4""" def assign_page_1(self): is_momentary = True for index in range(COLS): send_controllers = [ self._dial[index], self._dial[index + 8], self._dial[index + 16], self._dial[index + 24], ] self._mixer.channel_strip(index).set_send_controls(tuple(send_controllers)) self._mixer.channel_strip(index).set_select_button(self._trackbtns[index]) self._mixer.update() """devices 1-8""" def assign_pages_2_3(self): ##these need to be here anyway, whether or not there is a device present to control for index in range(4): self._device[index].set_enabled(True) # device_param_controls = [] ###no need to reassign it, since we are turning it off and on # for control in range(COLS): ###in fact, I think we can assign all this stuff in the header except for things directly connected to the mixer module # device_param_controls.append(self._dial[control + (index*COLS)]) # self._device[index].set_parameter_controls(tuple(device_param_controls)) self._reassign_devices(self._shift_mode._mode_index) """ filter res,filter q, pan, volume""" def assign_page_4(self): is_momentary = True for index in range(COLS): self._mixer.track_filter(index).set_filter_controls( self._dial[index], self._dial[index + 8] ) # set_filter_controls(self, freq, reso) self._mixer.track_filter(index).set_enabled(True) # self._mixer.track_eq(index).set_gain_controls((self._dial[index],self._dial[index+8],self._dial[index+16])) self._mixer.channel_strip(index).set_pan_control(self._dial[index + 16]) self._mixer.channel_strip(index).set_volume_control(self._dial[index + 24]) self._mixer.channel_strip(index).set_select_button(self._trackbtns[index]) self._mixer.update() def assign_cliplaunch(self): if STANDALONE is True: for column in range(COLS): for row in range(ROWS - 1): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) def _reassign_devices(self, mode_index): if self._shift_mode._mode_index in range(2, 4): ##both of these lines would be better handled by a property offset = (mode_index - 2) * 4 ## set up in an override module of the device_component....bleh track = self.song().view.selected_track for index in range(4): if index + offset < len(track.devices): # self.log_message('assigning device') self._device[index].set_device(track.devices[index + offset]) else: # self.log_message('assigning device to None') self._device[index].set_device(None) self._device[index].set_bank_nav_buttons(self._trackbtns[(index * 2)], self._trackbtns[(index * 2) + 1]) self._device[index].update() def disconnect(self): """clean things up on disconnect""" self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= Code log closed =--------------" ) # Create entry in log file ControlSurface.disconnect(self) return None
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
def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface, note_repeat, c_instance): #Live.Base.log("MainSelectorComponent - __init__ ") #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 self._c_instance = c_instance self._pro_session_on = False self._long_press = 500 self._last_session_mode_button_press = int(round(time.time() * 1000)) self._aux_scene = None #Non-Matrix buttons self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) #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] # One for each LP Mode button for index in range(4): self._sub_mode_list[index] = 0 self.set_mode_buttons(self._mode_buttons) self._last_mode_index = 0 self._clip_stop_buttons = [] for column in range(8): self._clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1)) self._session = SpecialProSessionComponent(matrix.width(), matrix.height(), None, self._side_buttons, self._control_surface, self, self._c_instance.song()) #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("DefaultButton.Disabled") #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)
class LemurPad(MonOhm): __module__ = __name__ __doc__ = " Lemur version of the MonOhm companion controller script " def __init__(self, *a, **k): self._timer_callbacks = [] #Used for _monobridge, which uses L8 method for registering timer callbacks. deprecated, needs to be replaced by new L9 Task class. self._osc_registry = {} self._display_button_names = DISPLAY_BUTTON_NAMES super(LemurPad, self).__init__(*a, **k) self._host_name = "LemurPad" self._color_type = 'AumPad' self.connected = 0 with self.component_guard(): self._setup_touchosc() self._assign_host2() self._assign_session_colors() def query_ohm(self): pass """script initialization methods""" def _setup_monobridge(self): self._monobridge = OSCMonoBridgeElement(self) self._monobridge.name = 'MonoBridge' 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] = OSCMonoEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self, osc = '/Fader_'+str(index)+'/x', osc_parameter = '/Strip'+str(index+8)+'/set', osc_name = '/Strip'+str(index)+'/set') for index in range(8): self._button[index] = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_'+str(index), self, osc = '/Select_'+str(index)+'/value', osc_alt = '/Select/set '+str(index), osc_name = '/Select/text '+str(index)) for index in range(16): self._dial[index] = OSCMonoEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index + 8, self, osc = '/Dial_'+str(index)+'/x', osc_parameter = '/Dial'+str(index)+'val/set', osc_name = '/Dial'+str(index)+'name/set') for index in range(6): self._menu[index] = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self, osc = '/Function_'+str(index)+'/value', osc_alt = '/Function/set '+str(index), osc_name = '/Function/text '+str(index)) self._crossfader = OSCMonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute, "Crossfader", 24, self, osc = '/XFader/x', osc_parameter = '/XFader/none', osc_name = None) self._livid = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self, osc = '/Livid/x', osc_alt = '/Livid/x', osc_name = None) self._shift_l = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Shift_Button_Left', self, osc = '/ShiftL/x', osc_alt = '/ShiftL/x', osc_name = None) self._shift_r = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Shift_Button_Right', self, osc = '/ShiftR/x', osc_alt = '/ShiftR/x', osc_name = None) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._monomod = ButtonMatrixElement() self._monomod.name = 'Monomod' self._grid = [None for index in range(8)] for column in range(8): self._grid[column] = [None for index in range(8)] for row in range(8): self._grid[column][row] = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self, osc = '/ClipGrid_'+str(column)+'_'+str(row)+'/value', osc_alt = '/ClipGrid/set '+str(column)+' '+str(row), osc_name = '/ClipGrid/text '+str(column)+' '+str(row)) 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._dummy_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 125) self._dummy_button.name = 'Dummy1' self._dummy_button2 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 126) self._dummy_button2.name = 'Dummy2' self._dummy_button3 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 127) self._dummy_button2.name = 'Dummy3' self._monomod256 = ButtonMatrixElement() self._monomod256.name = 'Monomod256' self._square = [None for index in range(16)] for column in range(16): self._square[column] = [None for index in range(16)] for row in range(16): self._square[column][row] = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, int(column/8) + 1, row + ((column%8) * 16), '256Grid_' + str(column) + '_' + str(row), self, osc = '/Grid_'+str(column)+'_'+str(row)+'/value', osc_alt = '/Grid/set '+str(column)+' '+str(row), osc_name = None) #self._square[column][row] = FlashingButtonElement(is_momentary, 0, 15, -1, '256Grid_' + str(column) + '_' + str(row), '/1/p_grid/'+str(column)+'/'+str(row), '/1/c_grid/'+str(column)+'/'+str(row), self) for row in range(16): button_row = [] for column in range(16): button_row.append(self._square[column][row]) self._monomod256.add_row(tuple(button_row)) self._bank_buttons = ButtonMatrixElement() self._key_buttons = ButtonMatrixElement() self._bank_button = [None for index in range(2)] for index in range(2): self._bank_button[index] = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, index, '256Grid_Bank_' + str(index), self, osc = '/Shift_'+str(index)+'/value', osc_alt = '/Shift/set '+str(index), osc_name = None) button_row = [] for index in range(2): button_row.append(self._bank_button[index]) self._bank_buttons.add_row(tuple(button_row)) button_row = [] self._key_button = [None for index in range(8)] for index in range(8): self._key_button[index] = OSCMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, index+8, '256Grid_Key_' + str(index), self, osc = '/Keys_'+str(index)+'/value', osc_alt = '/Keys/set '+str(index), osc_name = None) for index in range(8): button_row.append(self._key_button[index]) self._key_buttons.add_row(tuple(button_row)) def _setup_session_control(self): is_momentary = True num_tracks = 4 num_scenes = 5 self._session = NameServerSessionComponent(num_tracks, num_scenes, self) self._session.name = "Left_Session" self._session.set_offsets(0, 0) self._session.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene = [None for index in range(5)] for row in range(num_scenes): self._scene[row] = self._session.scene(row) self._scene[row].name = 'L_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_L_' + str(row) clip_slot.set_triggered_to_play_value(self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value(self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value(self._color_defs['CLIP_RECORDING']) self._session.set_mixer(self._mixer) self._session_zoom = SessionZoomingComponent(self._session) self._session_zoom.name = 'L_Session_Overview' self._session_zoom.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom.set_selected_value(self._color_defs['ZOOM_SELECTED']) self._session_zoom._zoom_button = (self._dummy_button) self._session_zoom.set_enabled(True) self._session2 = SessionComponent(num_tracks, num_scenes) self._session2.name = 'Right_Session' self._session2.set_offsets(4, 0) self._session2.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene2 = [None for index in range(5)] for row in range(num_scenes): self._scene2[row] = self._session2.scene(row) self._scene2[row].name = 'R_Scene_' + str(row) for column in range(num_tracks): clip_slot = self._scene2[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_R_' + str(row) clip_slot.set_triggered_to_play_value(self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value(self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value(self._color_defs['CLIP_RECORDING']) self._session2.set_mixer(self._mixer2) self._session2.add_offset_listener(self._on_session_offset_changes) self._session_zoom2 = SessionZoomingComponent(self._session2) self._session_zoom2.name = 'R_Session_Overview' self._session_zoom2.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom2.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom2.set_selected_value(self._color_defs['ZOOM_SELECTED']) self._session_zoom.set_enabled(True) self._session_zoom2._zoom_button = (self._dummy_button2) self._session_main = SessionComponent(8, num_scenes) self._session_main.name = 'Main_Session' self._session_main.set_stop_clip_value(self._color_defs['STOP_CLIP']) self._scene_main = [None for index in range(5)] for row in range(num_scenes): self._scene_main[row] = self._session_main.scene(row) self._scene_main[row].name = 'M_Scene_' + str(row) for column in range(8): clip_slot = self._scene_main[row].clip_slot(column) clip_slot.name = str(column) + '_Clip_Slot_M_' + str(row) clip_slot.set_triggered_to_play_value(self._color_defs['CLIP_TRG_PLAY']) clip_slot.set_triggered_to_record_value(self._color_defs['CLIP_TRG_REC']) clip_slot.set_stopped_value(self._color_defs['CLIP_STOP']) clip_slot.set_started_value(self._color_defs['CLIP_STARTED']) clip_slot.set_recording_value(self._color_defs['CLIP_RECORDING']) self._session_main.set_mixer(self._mixer) self._session_zoom_main = SessionZoomingComponent(self._session_main) self._session_zoom_main.name = 'M_Session_Overview' self._session_zoom_main.set_stopped_value(self._color_defs['ZOOM_STOPPED']) self._session_zoom_main.set_playing_value(self._color_defs['ZOOM_PLAYING']) self._session_zoom_main.set_selected_value(self._color_defs['ZOOM_SELECTED']) self._session_zoom_main.set_enabled(True) self._session_zoom_main._zoom_button = (self._dummy_button3) self._sessions = [self._session, self._session2, self._session_main] self._zooms = [self._session_zoom, self._session_zoom2, self._session_zoom_main] def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = LemurOhmModHandler(self) self.modhandler.name = 'ModHandler' self.modhandler256 = LemurModHandler(self) self.modhandler256.name = 'ModHandler256' def _assign_host2(self): self.modhandler256.set_shift_button(self._bank_button[0]) self.modhandler256.set_alt_button(self._bank_button[1]) self.modhandler256.set_grid(self._monomod256) self.modhandler256.set_key_buttons(self._key_buttons) self.modhandler256.set_enabled(True) def _setup_touchosc(self): self._osc_registry = {} #self._osc_registry['/ping'] = self._monobridge.ping #self._osc_registry['/1'] = self._monobridge.page1 #self._osc_registry['/2'] = self._monobridge.page2 for control in self.controls: if hasattr(control, 'osc'): self._osc_registry[control.osc] = control.set_value #if hasattr(control, 'osc_alt'): # self._osc_registry[control.osc_alt] = control.set_value #self.log_message('create dict key: ' + str(control.osc) + str(control.name)) """shift/zoom methods""" def deassign_matrix(self): super(LemurPad, self).deassign_matrix() self.clear_grid_names() """menu button management methods""" def deassign_menu(self): super(LemurPad, self).deassign_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(' ')) def assign_device_nav_to_menu(self): super(LemurPad, self).assign_device_nav_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(DEVICE_NAV_NAMES[index]))) def assign_transport_to_menu(self): super(LemurPad, self).assign_transport_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(TRANSPORT_NAMES[index]))) def assign_session_nav_to_menu(self): super(LemurPad, self).assign_session_nav_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(SESSION_NAV_NAMES[index]))) def assign_session_main_nav_to_menu(self): super(LemurPad, self).assign_session_main_nav_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(SESSION_NAV_NAMES[index]))) def assign_monomod_shift_to_menu(self): super(LemurPad, self).assign_monomod_shift_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(MONOMOD_SHIFT_NAMES[index]))) def assign_monomod_to_menu(self): super(LemurPad, self).assign_monomod_shift_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(MONOMOD_NAMES[index]))) def assign_session_bank_to_menu(self): super(LemurPad, self).assign_session_bank_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(SESSION_BANK_NAMES[index]))) def assign_session2_bank_to_menu(self): super(LemurPad, self).assign_session2_bank_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(SESSION_BANK2_NAMES[index]))) def assign_session_main_nav_to_menu(self): super(LemurPad, self).assign_session_main_nav_to_menu() for index in range(6): self._monobridge._send_osc(self._menu[index].osc_name, self.generate_strip_string(str(SESSION_MAIN_BANK_NAMES[index]))) """m4l bridge""" def generate_strip_string(self, display_string): NUM_CHARS_PER_DISPLAY_STRIP = 9 if (not display_string): return ('`_') 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 += ' ' assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return '`' + ret.replace(' ', '_') def notification_to_bridge(self, name, value, sender): if(isinstance(sender, MonoEncoderElement2)): #self.log_message(str(name) + str(value) + str(sender.num)) self._monobridge._send('lcd_name', sender.name, self.generate_strip_string(str(name))) self._monobridge._send('lcd_value', sender.name, self.generate_strip_string(str(value))) def clip_name(self, sender, name): #self.log_message('clip name ' + str(sender.osc_name) + ' ' + str(self.generate_strip_string(str(name)))) self._monobridge._send_osc(sender.osc_name, self.generate_strip_string(str(name))) """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(): clip_names.append(clip_slot._clip_slot)##.clip.name) #return clip_slot._clip_slot #self.log_message('clip name' + str(clip_slot._clip_slot.clip.name)) return clip_names""" """called on timer""" def update_display(self): super(LemurPad, self).update_display() for callback in self._timer_callbacks: callback() def strobe(self): pass """general functionality""" def disconnect(self): super(MonOhm, self).disconnect() def clear_grid_names(self): #self.log_message('clear grid names' + str(self)) for column in range(8): for row in range(8): self._monobridge._send_osc(self._grid[column][row].osc_name, '`_') def _register_timer_callback(self, callback): """ Registers a callback that is triggerd on every call of update_display """ assert (callback != None) assert (dir(callback).count('im_func') is 1) assert (self._timer_callbacks.count(callback) == 0) self._timer_callbacks.append(callback) return None def _unregister_timer_callback(self, callback): """ Unregisters a timer callback """ assert (callback != None) assert (dir(callback).count('im_func') is 1) assert (self._timer_callbacks.count(callback) == 1) self._timer_callbacks.remove(callback) return None def _set_brightness(self, value): #self._bright = (value != 0) #for control in self.controls: # if isinstance(control, OSCMonoButtonElement): # self._monobridge._send_osc(control.osc_alt, int(self._bright), True) pass def reset(self): #self._monobridge._send_osc('/reset') for control in self.controls: control.reset() def assign_lower_grid_names(self, mode): if self._display_button_names is True: for column in range(8): for row in range(3): self._monobridge._send_osc(self._grid[column][row+5].osc_name, self.generate_strip_string(str(GRID_NAMES[mode][row][column]))) def reset_and_refresh_state(self, *a, **k): self.schedule_message(1, self.reset) self.schedule_message(2, self.refresh_state)
class code(ControlSurface): __module__ = __name__ __doc__ = " Code controller script " def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= Code opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method. self._send_midi(factoryreset) self._send_midi(btn_channels) self._send_midi(enc_channels) #self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up self._setup_controls() self._setup_device_controls() self._setup_mixer_control() # Setup the mixer object self._setup_transport_control() self._setup_session_control() # Setup the session object - do this last self._setup_modes() self._setup_m4l_interface() #self.set_suppress_rebuild_requests(False) # Turn rebuild back on, once we're done setting up ##self.assign_page_2() def handle_sysex(self, midi_bytes): self._send_midi(tuple([240, 00, 01, 97, 04, 15, 01, 247])) #response = [long(0),long(0)] #self.log_message(str(response)) 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_controls(self): is_momentary = True self._dial = [None for index in range(DIALCOUNT)] self._trackbtns = [None for index in range(8)] self._modebtns = [None for index in range(5)] for index in range(DIALCOUNT): self._dial[index] = EncoderElement(MIDI_CC_TYPE, CH, matrix_nums[index], Live.MidiMap.MapMode.absolute) self._dial[index].name = 'Dial_' + str(index) self._dial[index].set_feedback_delay(-1) for index in range(8): self._trackbtns[index] = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]) self._trackbtns[index].name = 'Button_' + str(index) for index in range(5): self._modebtns[index] = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, mode_select_notes[index]) self._modebtns[index].name = 'ModeButton_' + str(index) self._matrix = ButtonMatrixElement() self._matrix.name = 'Matrix' self._grid = [None for index in range(COLS)] for column in range(COLS): self._grid[column] = [None for index in range(COLS)] for row in range(ROWS): nn = 1+(column * ROWS) + row self._grid[column][row] = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, nn) #comment out if you don't want clip launch self._grid[column][row].name = 'Grid_' + str(column) + '_' + str(row) for row in range(ROWS): button_row = [] for column in range(COLS): button_row.append(self._grid[column][row]) self._matrix.add_row(tuple(button_row)) """ not sure about this bit, but somehow I'll need to set up the modes here...!""" def _setup_modes(self): self._shift_mode = ShiftModeComponent(self, tuple(button for button in self._modebtns)) self._shift_mode.name = 'Mix_Mode' #mode 1 #self._shift_mode.set_mode_buttons(self._modebtns) def _setup_transport_control(self): self._transport = TransportComponent() self._transport.name = 'Transport' def _setup_mixer_control(self): is_momentary = True self._num_tracks = (COLS) global mixer mixer = MixerComponent(COLS, 0, True, True) mixer.name = 'Mixer' self._mixer = mixer mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left) for index in range(COLS): #use the bottom row of encoders for volume, so add 24 to offset the index mixer.channel_strip(index).set_volume_control(self._dial[index+24]) for index in range(COLS): mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index) mixer.track_eq(index).name = 'Mixer_EQ_' + str(index) mixer.track_filter(index).name = 'Mixer_Filter_' + str(index) #added by a mixer.channel_strip(index)._invert_mute_feedback = True #mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index])) self.song().view.selected_track = 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 """ Technically, we aren't using the session control, but I'm going to set it up in case inter-script communication needs it""" def _setup_session_control(self): is_momentary = True num_tracks = COLS num_scenes = ROWS global session session = SessionComponent(num_tracks, num_scenes) session.name = "Session" session.set_offsets(0, 0) self._session = session self._session.set_stop_clip_value(0) self._scene = [None for index in range(ROWS)] 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) clip_slot.set_triggered_to_play_value(64) clip_slot.set_triggered_to_record_value(64) clip_slot.set_stopped_value(0) clip_slot.set_started_value(64) clip_slot.set_recording_value(64) #clip_slot.set_launch_button(self._grid[column][row]) #comment out if you don't want clip launch session.set_mixer(mixer) self._session_zoom = SessionZoomingComponent(session) self._session_zoom.name = 'Session_Overview' self._session_zoom.set_stopped_value(0) self._session_zoom.set_playing_value(64) self._session_zoom.set_selected_value(64) if STANDALONE is True: self.set_highlighting_session_component(self._session) self._session.set_track_bank_buttons(self._grid[5][3], self._grid[4][3]) #comment out when using with Griid self._session.set_scene_bank_buttons(self._grid[7][3], self._grid[6][3]) # comment out when using with Griid """this is where we take care of setting up the the multiple devices per page, we will need 4""" def _setup_device_controls(self): self._device = [None for index in range(4)] for index in range(ROWS): self._device[index] = DeviceComponent() self._device[index].name = 'Device_Component_' + str(index) #self.set_device_component(self._device) #this doesn't work anymore, because we have multiple devices for the controller....we'll have to get fancy here, but that's for later #self._device_navigator = DetailViewControllerComponent() #its unclear if we'll need this....how is device navigation (i.e. banking for device parameter banks) going to be handled by the script? #self._device_navigator.name = 'Device_Navigator' device_param_controls = [] for control in range(COLS): """this setups up 8 device parameters per row""" #dial_index = control + (index*COLS) """alternatively, this setus up device controls in 4 4x2 groups""" dial_index = device_encoders[control + (index*COLS)] device_param_controls.append(self._dial[dial_index]) self._device[index].set_parameter_controls(tuple(device_param_controls)) """this is where we deassign every control that will be changing function when we switch modes...best to just deassign them all, and reassign them on update""" def deassign_matrix(self): for index in range(DIALCOUNT): #this should totally work!!! I'm over appealing to Python's sadistic mannerisms right now.... self._dial[index].send_value(0, True) ##this is kind of a hack, and should be unnecessary; the bool at the end tells the send_value method to force the value out to the controller for index in range(COLS): self._mixer.track_eq(index).set_enabled(False) ##set_gain_controls(tuple([None for index in range(3)])) self._mixer.channel_strip(index).set_volume_control(None) self._mixer.track_filter(index).set_enabled(False) ##set_filter_controls(tuple([None, None])) self._mixer.channel_strip(index).set_pan_control(None) self._mixer.channel_strip(index).set_select_button(None) self._mixer.channel_strip(index).set_send_controls(tuple([None for index in range(4)])) for device in range(4): self._device[device].set_bank_nav_buttons(None, None) self._device[device].set_enabled(False) ##set_parameter_controls(tuple([None for index in range(8)])) for track in range(8): self._mixer.channel_strip(track).set_select_button(None) for scene in range(4): self._scene[scene].clip_slot(track).set_launch_button(None) #self.request_rebuild_midi_map() # I think this is causing problems updating the leds when in build? """EQ Hi/Mid/Low and volume""" def assign_page_0(self): """for each column""" is_momentary = True for index in range(COLS): self._mixer.track_eq(index).set_gain_controls((self._dial[index+16],self._dial[index+8],self._dial[index])) self._mixer.track_eq(index).set_enabled(True) self._mixer.channel_strip(index).set_volume_control(self._dial[index+24])#use the bottom row of encoders for volume, so add 24 to offset the index self._mixer.channel_strip(index).set_select_button(self._trackbtns[index]) self.assign_cliplaunch() self._mixer.update() """sends 1-4""" def assign_page_1(self): is_momentary = True for index in range(COLS): send_controllers = [self._dial[index],self._dial[index+8],self._dial[index+16],self._dial[index+24]] self._mixer.channel_strip(index).set_send_controls(tuple(send_controllers)) self._mixer.channel_strip(index).set_select_button(self._trackbtns[index]) self._mixer.update() """devices 1-8""" def assign_pages_2_3(self): ##these need to be here anyway, whether or not there is a device present to control for index in range(4): self._device[index].set_enabled(True) #device_param_controls = [] ###no need to reassign it, since we are turning it off and on #for control in range(COLS): ###in fact, I think we can assign all this stuff in the header except for things directly connected to the mixer module # device_param_controls.append(self._dial[control + (index*COLS)]) #self._device[index].set_parameter_controls(tuple(device_param_controls)) self._reassign_devices(self._shift_mode._mode_index) """ filter res,filter q, pan, volume""" def assign_page_4(self): is_momentary = True for index in range(COLS): self._mixer.track_filter(index).set_filter_controls(self._dial[index], self._dial[index + 8]) #set_filter_controls(self, freq, reso) self._mixer.track_filter(index).set_enabled(True) #self._mixer.track_eq(index).set_gain_controls((self._dial[index],self._dial[index+8],self._dial[index+16])) self._mixer.channel_strip(index).set_pan_control(self._dial[index+16]) self._mixer.channel_strip(index).set_volume_control(self._dial[index+24]) self._mixer.channel_strip(index).set_select_button(self._trackbtns[index]) self._mixer.update() def assign_cliplaunch(self): if STANDALONE is True: for column in range(COLS): for row in range(ROWS-1): self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row]) def _reassign_devices(self, mode_index): if self._shift_mode._mode_index in range(2, 4): ##both of these lines would be better handled by a property offset = (mode_index - 2) * 4 ## set up in an override module of the device_component....bleh track = self.song().view.selected_track for index in range(4): if index + offset < len(track.devices): #self.log_message('assigning device') self._device[index].set_device(track.devices[index + offset]) else: #self.log_message('assigning device to None') self._device[index].set_device(None) self._device[index].set_bank_nav_buttons(self._trackbtns[(index * 2)], self._trackbtns[(index * 2) + 1]) self._device[index].update() def disconnect(self): """clean things up on disconnect""" self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= Code log closed =--------------") #Create entry in log file ControlSurface.disconnect(self) return None
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(127) 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*5)]) 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.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) # Clip trigger on grid assignments 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*5)]) for index in range(N_TRACKS*N_SCENES): self.grid[index].clear_send_cache() if USE_SESSION_NAV == True: self.navleft = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_LEFT_BUTTON, 'Nav_Left_Button', self) self.navleft.clear_send_cache() self.navleft.set_on_off_values(NAVBOX_LEFT_BUTTON_C, NAVBOX_LEFT_BUTTON_C) self.navright = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_RIGHT_BUTTON, 'Nav_Right_Button', self) self.navright.clear_send_cache() self.navright.set_on_off_values(NAVBOX_RIGHT_BUTTON_C, NAVBOX_RIGHT_BUTTON_C) self.navup = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_UP_BUTTON, 'Nav_Up_Button', self) self.navup.clear_send_cache() self.navup.set_on_off_values(NAVBOX_UP_BUTTON_C, NAVBOX_UP_BUTTON_C) self.navdown = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_DOWN_BUTTON, 'Nav_Down_Button', self) self.navdown.clear_send_cache() self.navdown.set_on_off_values(NAVBOX_DOWN_BUTTON_C, NAVBOX_DOWN_BUTTON_C) self.session.set_track_bank_buttons(self.navright, self.navleft) self.session.set_scene_bank_buttons(self.navdown, self.navup) if USE_MIXER_CONTROLS == True: self.session.set_mixer(self.mixer) self.refresh_state() self.session.set_enabled(True) self.session.update()
class MainSelectorComponent(ModeSelectorComponent): """ Class that reassigns the button on the launchpad to different functions """ def __init__(self, matrix, top_buttons, side_buttons, config_button): raise isinstance(matrix, ButtonMatrixElement) or AssertionError raise matrix.width() == 8 and matrix.height() == 8 or AssertionError raise isinstance(top_buttons, tuple) or AssertionError raise len(top_buttons) == 8 or AssertionError raise isinstance(side_buttons, tuple) or AssertionError raise len(side_buttons) == 8 or AssertionError raise isinstance(config_button, ButtonElement) or AssertionError ModeSelectorComponent.__init__(self) self._session = SpecialSessionComponent(matrix.width(), matrix.height()) self._zooming = DeprecatedSessionZoomingComponent(self._session) self._session.name = 'Session_Control' self._zooming.name = 'Session_Overview' self._matrix = matrix self._side_buttons = side_buttons self._nav_buttons = top_buttons[:4] self._config_button = config_button self._zooming.set_empty_value(LED_OFF) self._all_buttons = [] for button in self._side_buttons + self._nav_buttons: self._all_buttons.append(button) self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session) self._sub_modes.name = 'Mixer_Modes' self._sub_modes.set_update_callback(self._update_control_channels) self._init_session() self._all_buttons = tuple(self._all_buttons) self.set_modes_buttons(top_buttons[4:]) def disconnect(self): for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._session = None self._zooming = None for button in self._all_buttons: button.set_on_off_values(127, LED_OFF) self._config_button.turn_off() self._matrix = None self._side_buttons = None self._nav_buttons = None self._config_button = None ModeSelectorComponent.disconnect(self) def session_component(self): return self._session def set_modes_buttons(self, buttons): raise buttons == None or isinstance( buttons, tuple) or len(buttons) == self.number_of_modes() or AssertionError identify_sender = True for button in self._modes_buttons: button.remove_value_listener(self._mode_value) self._modes_buttons = [] if buttons != None: for button in buttons: raise isinstance(button, ButtonElement) or AssertionError self._modes_buttons.append(button) button.add_value_listener(self._mode_value, identify_sender) self.set_mode(0) def number_of_modes(self): return 4 def on_enabled_changed(self): self.update() def set_mode(self, mode): if not mode in range(self.number_of_modes()): raise AssertionError self._mode_index = (self._mode_index != mode or mode == 3) and mode self.update() def channel_for_current_mode(self): new_channel = self._mode_index + self._sub_modes.mode() if new_channel > 0: new_channel += 3 return new_channel def update(self): super(MainSelectorComponent, self).update() if not self._modes_buttons != None: raise AssertionError if self.is_enabled(): for index in range(len(self._modes_buttons)): self._modes_buttons[index].set_force_next_value() if index == self._mode_index: self._modes_buttons[index].turn_on() else: self._modes_buttons[index].turn_off() for scene_index in range(8): self._side_buttons[scene_index].set_enabled(True) for track_index in range(8): self._matrix.get_button(track_index, scene_index).set_enabled(True) for button in self._nav_buttons: button.set_enabled(True) as_active = True as_enabled = True self._session.set_allow_update(False) self._zooming.set_allow_update(False) self._config_button.send_value(40) self._config_button.send_value(1) release_buttons = self._mode_index == 1 self._mode_index == 0 and self._setup_mixer(not as_active) self._setup_session(as_active, as_enabled) elif self._mode_index == 1: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 2: self._setup_session(not as_active, not as_enabled) self._setup_mixer(not as_active) self._setup_user(release_buttons) elif self._mode_index == 3: self._setup_session(not as_active, as_enabled) self._setup_mixer(as_active) else: raise False or AssertionError self._session.set_allow_update(True) self._zooming.set_allow_update(True) self._update_control_channels() def _update_control_channels(self): new_channel = self.channel_for_current_mode() for button in self._all_buttons: button.set_channel(new_channel) button.set_force_next_value() def _setup_session(self, as_active, as_enabled): if not isinstance(as_active, type(False)): raise AssertionError for button in self._nav_buttons: if as_enabled: button.set_on_off_values(GREEN_FULL, GREEN_THIRD) else: button.set_on_off_values(127, LED_OFF) for scene_index in range(8): scene = self._session.scene(scene_index) if as_active: scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene.set_launch_button(scene_button) else: scene.set_launch_button(None) for track_index in range(8): if as_active: button = self._matrix.get_button( track_index, scene_index) button.set_on_off_values(127, LED_OFF) scene.clip_slot(track_index).set_launch_button(button) else: scene.clip_slot(track_index).set_launch_button(None) if as_active: self._zooming.set_zoom_button(self._modes_buttons[0]) self._zooming.set_button_matrix(self._matrix) self._zooming.set_scene_bank_buttons(self._side_buttons) self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]) self._zooming.update() else: self._zooming.set_zoom_button(None) self._zooming.set_button_matrix(None) self._zooming.set_scene_bank_buttons(None) self._zooming.set_nav_buttons(None, None, None, None) as_enabled and self._session.set_track_bank_buttons( self._nav_buttons[3], self._nav_buttons[2]) self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0]) else: self._session.set_track_bank_buttons(None, None) self._session.set_scene_bank_buttons(None, None) def _setup_mixer(self, as_active): if not isinstance(as_active, type(False)): raise AssertionError as_active and self._sub_modes.is_enabled( ) and self._sub_modes.set_mode(-1) self._sub_modes.set_enabled(as_active) def _setup_user(self, release_buttons): for scene_index in range(8): scene_button = self._side_buttons[scene_index] scene_button.set_on_off_values(127, LED_OFF) scene_button.turn_off() scene_button.set_enabled(not release_buttons) for track_index in range(8): button = self._matrix.get_button(track_index, scene_index) button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) for button in self._nav_buttons: button.set_on_off_values(127, LED_OFF) button.turn_off() button.set_enabled(not release_buttons) if release_buttons: self._config_button.send_value(2) self._config_button.send_value(32, force=True) def _init_session(self): self._session.set_stop_clip_value(AMBER_THIRD) self._session.set_stop_clip_triggered_value(AMBER_BLINK) for scene_index in range(self._matrix.height()): scene = self._session.scene(scene_index) scene.set_triggered_value(GREEN_BLINK) scene.name = 'Scene_' + str(scene_index) for track_index in range(self._matrix.width()): clip_slot = scene.clip_slot(track_index) clip_slot.set_triggered_to_play_value(GREEN_BLINK) clip_slot.set_triggered_to_record_value(RED_BLINK) clip_slot.set_stopped_value(AMBER_FULL) clip_slot.set_started_value(GREEN_FULL) clip_slot.set_recording_value(RED_FULL) clip_slot.name = str(track_index) + '_Clip_Slot_' + str( scene_index) self._all_buttons.append( self._matrix.get_button(track_index, scene_index)) self._zooming.set_stopped_value(RED_FULL) self._zooming.set_selected_value(AMBER_FULL) self._zooming.set_playing_value(GREEN_FULL)
class 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 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()