def _setup_session_control(self): is_momentary = True # Size of session box num_tracks = 8 # column num_scenes = 1 # row """ Buttons declaration """ # Navigation button_navig_up = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_session_up) button_navig_down = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_session_down) """ Declare our session box """ global session #We want to instantiate the global session as a SessionComponent object (it was a global "None" type up until now...) session = SessionComponent(num_tracks, num_scenes) #(num_tracks, num_scenes) A session highlight ("red box") will appear with any two non-zero values session.set_offsets(0, 0) #(track_offset, scene_offset) Sets the initial offset of the "red box" from top left session._do_show_highlight() #to ensure that this session will be highlighted """ Buttons association """ # Navigation up, down, left, right session.set_scene_bank_buttons(button_navig_down, button_navig_up) # Launch selected clip for index in range(num_tracks): session.scene(0).clip_slot(index).set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_session_launch_clip[index])) # Stop selected track stop_track_buttons = [] for index in range(num_tracks): stop_track_buttons.append(ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_session_stop_track[index])) session.set_stop_track_clip_buttons(tuple(stop_track_buttons)) #array size needs to match num_tracks
def _setup_selection_box_control(self, indexDicer): is_momentary = True # Size of session box num_tracks = 1 #1 column num_scenes = 1 #1 row """ Buttons declaration """ # Navigation button_navig_up = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel_red[indexDicer] - 1, midi_cc_normal[0]) button_navig_down = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel_red[indexDicer] - 1, midi_cc_normal[1]) button_navig_left = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel_red[indexDicer] - 1, midi_cc_normal[3]) button_navig_right = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel_red[indexDicer] - 1, midi_cc_normal[4]) # Launch clip button_launch_clip = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel_red[indexDicer] - 1, midi_cc_normal[2]) # Stop track button_stop_track = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel_red[indexDicer] - 1, midi_cc_shifted[2]) # Stop all tracks #button_stop_track_all """ Declare our session box """ global session #We want to instantiate the global session as a SessionComponent object (it was a global "None" type up until now...) session = SessionComponent( num_tracks, num_scenes ) #(num_tracks, num_scenes) A session highlight ("red box") will appear with any two non-zero values session.set_offsets( indexDicer * 4, 0 ) #(track_offset, scene_offset) Sets the initial offset of the "red box" from top left session._do_show_highlight( ) #to ensure that this session will be highlighted """ Buttons association """ # Navigation up, down, left, right session.set_scene_bank_buttons(button_navig_down, button_navig_up) session.set_track_bank_buttons(button_navig_right, button_navig_left) # Launch selected clip session.scene(0).clip_slot(0).set_launch_button(button_launch_clip) # Stop selected track stop_track_buttons = [] stop_track_buttons.append(button_stop_track) session.set_stop_track_clip_buttons( tuple(stop_track_buttons)) #array size needs to match num_tracks
class LambdaControl(ControlSurface): __module__ = __name__ __doc__ = "LambdaControl Live Script" def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.__c_instance = c_instance self._skin = make_default_skin() #scene up and down by encoder self.pad_down_button = self.create_button(MATRIX_CONTROL_CHN, MATRIX_CONTROL_KEY_DOWN, MIDI_NOTE_TYPE, 'Down_Button', is_rgb=False) self.pad_up_button = self.create_button(MATRIX_CONTROL_CHN, MATRIX_CONTROL_KEY_UP, MIDI_NOTE_TYPE, 'Up_Button', is_rgb=False) #stop all clips by press on switch scene encoder self.stop_all_clips_button = self.create_button( STOP_ALL_CLIPS_CHN, STOP_ALL_CLIPS_KEY, MIDI_NOTE_TYPE, 'Stop_All_Clips_Button', is_rgb=False) #array for stop track clip buttons self.stop_track_clip_buttons_raw = [[ self.create_button(MATRIX_CHANNEL, STOP_TRACK_CLIP_OFFSET + i, MIDI_CC_TYPE, 'Stop_' + str(i) + '_Button', is_rgb=True) for i in range(NUMBER_OF_TRACKS) ]] self.stop_track_clip_buttons = ButtonMatrixElement( name='Stop_Track_Clip_Buttons', rows=self.stop_track_clip_buttons_raw) self.matrix_rows_raw = [[ self.create_button( MATRIX_CHANNEL, (NUMBER_OF_SCENES - 1 - row) * NUMBER_OF_TRACKS + column + PAD_OFFSET, MIDI_NOTE_TYPE, str(column) + '_Clip_' + str(row) + '_Button', is_rgb=True, default_states={ True: 'DefaultMatrix.On', False: 'DefaultMatrix.Off' }) for column in xrange(NUMBER_OF_TRACKS) ] for row in xrange(NUMBER_OF_SCENES)] self.matrix = ButtonMatrixElement(name='Button_Matrix', rows=self.matrix_rows_raw) self.side_buttons = ButtonMatrixElement(name='Scene_Launch_Buttons', rows=[[ self.create_button(MATRIX_CHANNEL, 36 + idx, MIDI_CC_TYPE, 'Scene_Launch_Button' + str(idx), is_rgb=True, default_states={True: 'DefaultMatrix.On', False: 'DefaultMatrix.Off'}) \ for idx in reversed(xrange(NUMBER_OF_SCENES)) ]]) #initialisation of the session self.create_session() self.set_highlighting_session_component(self.session) def create_button(self, channel, note, midi_type, name, **k): return ConfigurableButtonElement(True, midi_type, channel, note, name=name, skin=self._skin, **k) def create_session_layer(self): return Layer(scene_launch_buttons=self.side_buttons, clip_launch_buttons=self.matrix, stop_track_clip_buttons=self.stop_track_clip_buttons, stop_all_clips_button=self.stop_all_clips_button, scene_bank_up_button=self.pad_up_button, scene_bank_down_button=self.pad_down_button) def create_session(self): self.session = SessionComponent(NUMBER_OF_TRACKS, NUMBER_OF_SCENES, enable_skinning=True, is_enabled=False, auto_name=True, layer=self.create_session_layer()) self.session.set_offsets( TRACK_OFFSET, SCENE_OFFSET) #offset start a the up-left corner (track1,row1) self.session._do_show_highlight( ) #to ensure that this session will be highlighted self.session.set_rgb_mode(Colors.CLIP_COLOR_TABLE, Colors.RGB_COLOR_TABLE, clip_slots_only=True) self.session.set_enabled(True) def get_matrix_button(self, column, row): return self.matrix_rows_raw[NUMBER_OF_SCENES - row][column]
class MidiFighterTwister(ControlSurface): __module__ = __name__ __doc__ = "MidiFighterTwister class" def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self.__c_instance = c_instance self.show_message('Script initiated') self.init() def init(self): # initialize listeners, caches and colors self.flush_all() self.mf_disable_bank_buttons() self.mf_init_page_config() self.mf_init_light_pages() # Start listeners to call dispatcher self.song().view.add_detail_clip_listener( self.dispatch_detail_clip_listener) self.song().add_current_song_time_listener( self.dispatch_current_song_time_listener) self.song().view.add_selected_track_listener( self.dispatch_selected_track_listener) self.device_listener_wrapper() # Initialize the sequencer buttons self.sequencer_init_buttons() self.sequencer_init_rotaries() self.init_clip_page() self.init_pad_page() self.init_device_params() def flush_all(self): for poti in range(64): for channel in range(4): self._send_midi((175 + channel, poti, 0)) def mf_init_page_config(self): # Initialize configuration parameters # Sequencer configuration self.sequencer_page_default_color = 1 self.sequencer_current_page_color_index = self.sequencer_page_default_color self.sequencer_base_default_note = 36 self.sequencer_current_selected_note = self.sequencer_base_default_note self.sequencer_clip_position_16th = None # Midi Channels self.rotary_midi_channel = 175 + 1 self.ring_midi_channel = 175 + 1 self.switch_midi_channel = 175 + 2 self.light_midi_channel = 175 + 2 # Pages cc map self.clip_page_cc = range(0, 16) self.sequencer_page_cc = range(16, 32) self.note_page_cc = range(32, 48) self.control_page_cc = range(48, 64) # Pages init color self.clip_page_colors = [1] * 16 self.sequencer_page_colors = [self.sequencer_page_default_color] * 16 self.note_page_colors = range(1, 127, 16) * 2 #self.note_page_colors = [0] * 16 self.control_page_colors = [1] * 16 # Status cache for sequencer self.switch_encoder_status_cache = [False] * 64 # List to store ButtonElements in self.switch_encoder_buttons = [False] * 64 # Status cache for rotaries self.rotary_encoder_potis = [False] * 64 def mf_init_light_pages(self): sequencer_page_map = zip(self.sequencer_page_cc, self.sequencer_page_colors) for light_encoder_cc, light_color_cc in sequencer_page_map: self._mf_set_light(light_encoder_cc, light_color_cc, False) note_page_map = zip(self.note_page_cc, self.note_page_colors) for light_encoder_cc, light_color_cc in note_page_map: self._mf_set_light(light_encoder_cc, light_color_cc, False) def _mf_set_light(self, light_encoder_cc, light_color_cc, status): # Sets color on midi channel 2 (177) end updates status cache # for sequencer to remember statuses self._send_midi( (self.light_midi_channel, light_encoder_cc, light_color_cc)) self.switch_encoder_status_cache[light_encoder_cc] = status def mf_disable_bank_buttons(self): # Workaround for not sending values to track when pressing bank buttons self.padm0 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 4, 0) self.padm1 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 4, 1) self.padm2 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 4, 2) self.padm3 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 4, 3) self.padm0.add_value_listener(self.bank_buttons_dummy, identify_sender=True) self.padm1.add_value_listener(self.bank_buttons_dummy, identify_sender=True) self.padm2.add_value_listener(self.bank_buttons_dummy, identify_sender=True) self.padm3.add_value_listener(self.bank_buttons_dummy, identify_sender=True) def bank_buttons_dummy(self): pass def dispatch_detail_clip_listener(self): self.current_clip = self.song().view.highlighted_clip_slot.clip self.init_sequencer() try: if self.current_clip.is_midi_clip and not self.current_clip.notes_has_listener: # Update leds when notes are added or removed self.current_clip.add_notes_listener( self._sequencer_update_notes_to_light) self.init_sequencer() else: self.sequencer_reset_colors() except AttributeError: pass def dispatch_current_song_time_listener(self): self.sequencer_light_follows_beat() def dispatch_selected_track_listener(self): self.device_auto_select() self.device_listener_wrapper() def device_listener_wrapper(self): selected_track = self.song().view.selected_track if not selected_track.devices_has_listener(self.device_auto_select): self.song().view.selected_track.add_devices_listener( self.device_auto_select) # Sequencer def init_sequencer(self): self.sequencer_current_selected_note = self.sequencer_base_default_note self.sequencer_current_page_color_index = self.sequencer_page_default_color self._sequencer_update_notes_to_light() def sequencer_init_buttons(self): for switch_encoder_cc in self.sequencer_page_cc: self.switch_encoder_buttons[switch_encoder_cc] = ButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, 1, switch_encoder_cc) self.switch_encoder_buttons[switch_encoder_cc].add_value_listener( self.sequencer_button_press, identify_sender=True) self.padl14 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 14) self.padr17 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 17) self.padl16 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 16) self.padr19 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 19) self.padl14.add_value_listener(self.sequencer_side_button_press, identify_sender=True) self.padr17.add_value_listener(self.sequencer_side_button_press, identify_sender=True) self.padl16.add_value_listener(self.sequencer_side_button_press, identify_sender=True) self.padr19.add_value_listener(self.sequencer_side_button_press, identify_sender=True) def sequencer_init_rotaries(self): for rotary_encoder_cc in self.sequencer_page_cc: self.rotary_encoder_potis[rotary_encoder_cc] = EncoderElement( MIDI_CC_TYPE, 0, rotary_encoder_cc, Live.MidiMap.MapMode.absolute) self.rotary_encoder_potis[rotary_encoder_cc].add_value_listener( self.sequencer_rotary_change, identify_sender=True) def sequencer_rotary_change(self, value, sender): try: self.current_clip except AttributeError: return False if self.current_clip.is_midi_clip: cc_value = sender._msg_identifier if value > 0: if not self.switch_encoder_status_cache[cc_value]: self._send_midi((self.light_midi_channel, cc_value, self.sequencer_current_light_on_color)) self._send_midi((self.ring_midi_channel, cc_value, 100)) self.switch_encoder_status_cache[cc_value] = True self.current_clip.set_notes( ((self.sequencer_current_selected_note, cc_value % 16 * 0.25, 0.25, value, False), )) elif value == 0: self._send_midi((self.light_midi_channel, cc_value, self.sequencer_current_page_color)) self.current_clip.remove_notes( cc_value % 16 * 0.25, self.sequencer_current_selected_note, 0.25, 1) self.switch_encoder_status_cache[cc_value] = False def sequencer_button_press(self, value, sender): try: self.current_clip except AttributeError: return False if self.current_clip.is_midi_clip: cc_value = sender._msg_identifier if value > 0: if not self.switch_encoder_status_cache[cc_value]: self._send_midi((self.light_midi_channel, cc_value, self.sequencer_current_light_on_color)) self.current_clip.set_notes( ((self.sequencer_current_selected_note, cc_value % 16 * 0.25, 0.25, 100, False), )) self.switch_encoder_status_cache[cc_value] = True self._send_midi((self.ring_midi_channel, cc_value, 100)) else: self._send_midi((self.light_midi_channel, cc_value, self.sequencer_current_page_color)) self._send_midi((self.ring_midi_channel, cc_value, 0)) self.current_clip.remove_notes( cc_value % 16 * 0.25, self.sequencer_current_selected_note, 0.25, 1) self.switch_encoder_status_cache[cc_value] = False def sequencer_side_button_press(self, value, sender): try: cc_value = sender._msg_identifier if value > 0: # Note/clolor up/down if cc_value == 14 and self.sequencer_current_selected_note > 0: self.sequencer_current_selected_note = self.sequencer_current_selected_note - 1 self.sequencer_current_page_color_index = self.sequencer_current_page_color_index - 16 self._sequencer_update_notes_to_light() self.sequencer_clip_position_16th = None self.show_message( "Selected Midi Note: " + str(self.sequencer_current_selected_note)) if cc_value == 17 and self.sequencer_current_selected_note < 127: self.sequencer_current_selected_note = self.sequencer_current_selected_note + 1 self.sequencer_current_page_color_index = self.sequencer_current_page_color_index + 16 self._sequencer_update_notes_to_light() self.sequencer_clip_position_16th = None self.show_message( "Selected Midi Note: " + str(self.sequencer_current_selected_note)) # New/duplicate clip if cc_value == 16 and self.sequencer_current_selected_note > 0: self.duplicate_clip() if cc_value == 19 and self.sequencer_current_selected_note > 0: self.session_record() except AttributeError: pass def sequencer_light_follows_beat(self): try: if self.current_clip.is_midi_clip: if self.sequencer_clip_position_16th == None: self.sequencer_clip_position_16th = int( self.current_clip.playing_position / 0.25) if self.switch_encoder_status_cache[self.sequencer_page_cc[ self.sequencer_clip_position_16th]]: self._send_midi( (177, self.sequencer_page_cc[ self.sequencer_clip_position_16th], self.sequencer_current_light_on_color)) else: self._send_midi((177, self.sequencer_page_cc[ self.sequencer_clip_position_16th], self.sequencer_current_page_color)) elif self.sequencer_clip_position_16th != int( self.current_clip.playing_position / 0.25): if self.switch_encoder_status_cache[self.sequencer_page_cc[ self.sequencer_clip_position_16th]]: self._send_midi( (177, self.sequencer_page_cc[ self.sequencer_clip_position_16th], self.sequencer_current_light_on_color)) else: self._send_midi((177, self.sequencer_page_cc[ self.sequencer_clip_position_16th], self.sequencer_current_page_color)) self.sequencer_clip_position_16th = int( self.current_clip.playing_position / 0.25) self._send_midi((177, self.sequencer_page_cc[ self.sequencer_clip_position_16th], self.sequencer_current_light_beat_color)) except IndexError: pass @property def sequencer_current_light_on_color(self): # light on color to be relative to page color return self.sequencer_current_page_color + 32 % 128 @property def sequencer_current_light_beat_color(self): # light on color to be relative to page color return self.sequencer_current_page_color + 64 % 128 @property def sequencer_current_page_color(self): return self.sequencer_current_page_color_index % 128 def _sequencer_get_midi_notes(self, note): # self.current_clip.get_notes(start, self.sequencer_current_selected_note, # selection_length, hight) try: return self.current_clip.get_notes(0, note, 4, 1) except AttributeError: return [] def _sequencer_update_notes_to_light(self): self.sequencer_reset_colors() notes_for_current_selected_note = self._sequencer_get_midi_notes( self.sequencer_current_selected_note) for note in notes_for_current_selected_note: light_encoder_cc = int(note[1] * 4 + self.sequencer_page_cc[0]) self._send_midi( (self.ring_midi_channel, light_encoder_cc, note[3])) self._mf_set_light(light_encoder_cc, self.sequencer_current_light_on_color, True) def sequencer_reset_colors(self): for light_encoder_cc in self.sequencer_page_cc: self._mf_set_light(light_encoder_cc, self.sequencer_current_page_color, False) self._send_midi((self.ring_midi_channel, light_encoder_cc, 0)) def duplicate_clip(self): self.log_message("duplicate clip") #if self._clip_slot and self._clip_slot.has_clip: # slot_name = self._clip_slot.clip.name # track = self._clip_slot.canonical_parent current_track = self.song().view.selected_track current_clip_slot = self.song().view.highlighted_clip_slot self.song().duplicate_scene( list(current_track.clip_slots).index(current_clip_slot)) #new_clip = current_track.duplicate_clip_slot( # list(current_track.clip_slots).index(current_clip_slot)+1) #self.log_message(new_clip) #selected_track = self.song().view.selected_track #selected_track.duplicate_clip_slot(selected_track) def session_record(self): self.log_message("session record") #self.song().trigger_session_record() # Clip page setion def init_clip_page(self): num_tracks = 4 num_scenes = 3 self.flash_status = 1 self.Mixer = MixerComponent(4, 3) # Volencoder self.volencoders = [None for index in range(num_tracks)] for index in range(num_tracks): self.volencoders[index] = EncoderElement( MIDI_CC_TYPE, 0, index, Live.MidiMap.MapMode.absolute) self.Mixer.channel_strip(index).set_volume_control( self.volencoders[index]) # Sendencoder for index in range(num_tracks): encoder_cc_send_1 = index + num_tracks encoder_cc_send_2 = index + num_tracks * 2 send1 = EncoderElement(MIDI_CC_TYPE, 0, encoder_cc_send_1, Live.MidiMap.MapMode.absolute) send2 = EncoderElement(MIDI_CC_TYPE, 0, encoder_cc_send_2, Live.MidiMap.MapMode.absolute) self.Mixer.channel_strip(index).set_send_controls((send1, send2)) # Panencoder for index in range(num_tracks): encoder_cc_pan = index + num_tracks * 3 pan = EncoderElement(MIDI_CC_TYPE, 0, encoder_cc_pan, Live.MidiMap.MapMode.absolute) self.Mixer.channel_strip(index).set_pan_control(pan) # Arm-/selectbuttons for index in range(num_tracks): armbutton = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, index + 12) self.Mixer.channel_strip(index).set_arm_button(armbutton) self.Mixer.channel_strip(index).set_select_button(armbutton) # Navigation buttons self.padl11 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 11) self.padr8 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 8) self.padl10 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 10) self.padr13 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 3, 13) self.grid = [None for index in range(num_tracks * 3)] for index in range(num_tracks * 3): self.grid[index] = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, index) self.matrix = ButtonMatrixElement() for row in range(num_scenes): button_row = [] for column in range(num_tracks): button_row.append(self.grid[column + (row * 4)]) self.log_message(str(column + (row * 4))) self.matrix.add_row(tuple(button_row)) self.Session = SessionComponent(num_tracks, num_scenes) self.Session.name = "Session" self.Session.set_offsets(0, 0) self.Session.set_mixer(self.Mixer) self.Session._do_show_highlight() self.set_highlighting_session_component(self.Session) self.Session.set_track_bank_buttons(self.padl11, self.padr8) self.Session.set_scene_bank_buttons(self.padr13, self.padl10) self.scene = [None for index in range(num_scenes)] 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) self.scene[row].clip_slot(column).set_triggered_to_play_value( 35) self.scene[row].clip_slot(column).set_stopped_value(68) self.scene[row].clip_slot(column).set_started_value(45) self.scene[row].clip_slot( column).set_triggered_to_record_value(100) self.scene[row].clip_slot(column).set_recording_value(80) for column in range(num_tracks): for row in range(num_scenes): self.scene[row].clip_slot(column).set_launch_button( self.grid[column + (row * 4)]) for index in range(num_tracks * num_scenes): self.grid[index].clear_send_cache() def update_display(self): # Called every 100 ms ControlSurface.update_display(self) self.refresh_state() self.Session.set_enabled(True) self.Session.update() # Sequencer hack try: for light_encoder_cc in self.sequencer_page_cc: self._send_midi((self.ring_midi_channel, light_encoder_cc, 0)) notes_for_current_selected_note = self._sequencer_get_midi_notes( self.sequencer_current_selected_note) for note in notes_for_current_selected_note: light_encoder_cc = int(note[1] * 4 + self.sequencer_page_cc[0]) self._send_midi( (self.ring_midi_channel, light_encoder_cc, note[3])) except AttributeError: pass # Pad Section def init_pad_page(self): self.pad_device_params() PAD_TRANSLATION = ((0, 0, 32, 1), (1, 0, 33, 1), (2, 0, 34, 1), (3, 0, 35, 1), (0, 1, 36, 1), (1, 1, 37, 1), (2, 1, 38, 1), (3, 1, 39, 1), (0, 2, 40, 1), (1, 2, 41, 1), (2, 2, 42, 1), (3, 2, 43, 1), (0, 3, 44, 1), (1, 3, 45, 1), (2, 3, 46, 1), (3, 3, 47, 1)) self.set_pad_translations(PAD_TRANSLATION) self._device_selection_follows_track_selection = True def pad_device_params(self): device_param_controls = [] for param in self.note_page_cc[:8]: self.rotary_encoder_potis[param] = EncoderElement( MIDI_CC_TYPE, 0, param, Live.MidiMap.MapMode.absolute) self.rotary_encoder_potis[param].release_parameter() self.rotary_encoder_potis[param].send_value(0, True) self.rotary_encoder_potis[param].clear_send_cache() device_param_controls.append(self.rotary_encoder_potis[param]) device = DeviceComponent() device.name = 'Device_Component pad' device.set_parameter_controls(tuple(device_param_controls)) self.set_device_component(device) #def scrolling(self): # self.application().view.scroll_view(ndir, 'Detail/DeviceChain', True) # Live.Song.Song.View.selected_track #Live.Song.Song.View.select_device()[0] # Device parameter section def init_device_params(self): device_param_controls = [] device_bank_buttons = [] for param in self.control_page_cc[:8]: self.rotary_encoder_potis[param] = EncoderElement( MIDI_CC_TYPE, 0, param, Live.MidiMap.MapMode.absolute) self.switch_encoder_buttons[param] = ButtonElement( IS_MOMENTARY, MIDI_CC_TYPE, 1, param) self.rotary_encoder_potis[param].release_parameter() self.rotary_encoder_potis[param].send_value(0, True) self.rotary_encoder_potis[param].clear_send_cache() device_param_controls.append(self.rotary_encoder_potis[param]) device_bank_buttons.append(self.switch_encoder_buttons[param]) device = DeviceComponent() device.name = 'Device_Component' device.set_parameter_controls(tuple(device_param_controls)) device.set_bank_buttons(tuple(device_bank_buttons)) device.set_on_off_button( ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 56)) self.set_device_component(device) def device_auto_select(self): # Iterates through devices within a track and assigns the first # DrumPad device to activate the individual drum's device. # Use first device in case none is a DrumPad device. selected_track = self.song().view.selected_track devices = selected_track.devices for device in devices: if device.can_have_drum_pads: self.current_drum_device = device pad_device = self.current_drum_device.view.selected_chain.devices[ 0] self.song().view.select_device(pad_device) if not self.current_drum_device.view.selected_drum_pad_has_listener( self.device_update_current_note): self.current_drum_device.view.add_selected_drum_pad_listener( self.device_update_current_note) break else: self.song().view.select_device(devices[0]) def device_update_current_note(self): current_note = self.current_drum_device.view.selected_drum_pad.note self.sequencer_current_selected_note = current_note # Update light of active pad #self._send_midi((self.light_midi_channel, light_encoder_cc, 63)) try: self.current_clip = self.song().view.highlighted_clip_slot.clip self.current_clip.is_midi_clip self._sequencer_update_notes_to_light() except AttributeError: pass