def _set_track(track): assert ((track == None) or isinstance(track, Live.Track.Track)) if channelstrip._track != None and isinstance(channelstrip._track, Live.Track.Track): if channelstrip._track.devices_has_listener(cb): channelstrip._track.remove_devices_listener(cb) if (track != None): track.add_devices_listener(cb) ChannelStripComponent.set_track(channelstrip, track)
def set_track(self, track): custom_log("ChanStripComponent.set_track") # Remove monitoring listener for old track # if self._track_has_monitoring_state(self._track): # custom_log("(old) track.name = " + self._track.name) # self._track.remove_current_monitoring_state_listener(self._on_current_monitoring_state_changed) if self._current_monitoring_state_button != None: self._current_monitoring_state_button.turn_off() ChannelStripComponentBase.set_track(self, track)
def set_track(self, track): custom_log("ChanStripComponent.set_track") # Remove monitoring listener for old track # if self._track_has_monitoring_state(self._track): # custom_log("(old) track.name = " + self._track.name) # self._track.remove_current_monitoring_state_listener(self._on_current_monitoring_state_changed) if self._current_monitoring_state_button != None: self._current_monitoring_state_button.turn_off() ChannelStripComponentBase.set_track(self, track)
def set_track(self, track): self._remove_send_listeners() self._remove_level_listener() if self._track != None: self._track.remove_color_listener(self._on_track_color_changed) self._track.mixer_device.volume.remove_value_listener(self._on_volume_changed) self._track.remove_has_midi_output_listener(self._on_output_type_changed) ChannelStripComponent.set_track(self, track) if self._track != None: self._track.add_color_listener(self._on_track_color_changed) self._track.mixer_device.volume.add_value_listener(self._on_volume_changed) self._track.add_has_midi_output_listener(self._on_output_type_changed) self._add_send_listeners() self._on_volume_changed() self._on_output_type_changed() self._update_track_index()
def set_track(self, track): self._remove_send_listeners() self._remove_level_listener() if self._track != None: self._track.remove_color_listener(self._on_track_color_changed) self._track.mixer_device.volume.remove_value_listener(self._on_volume_changed) self._track.remove_has_midi_output_listener(self._on_output_type_changed) ChannelStripComponent.set_track(self, track) if self._track != None: self._track.add_color_listener(self._on_track_color_changed) self._track.mixer_device.volume.add_value_listener(self._on_volume_changed) self._track.add_has_midi_output_listener(self._on_output_type_changed) self._add_send_listeners() self._on_volume_changed() self._on_output_type_changed() self._update_track_index()
class TrackControl(): def __init__(self, control_surface): self.control_surface = control_surface self.song = control_surface.song() self.component = ChannelStripComponent() self.component.set_track(self.song.view.selected_track) self.component.set_volume_control(control_surface.get_encoder(3, 12)) self.component.set_pan_control(control_surface.get_encoder(3, 4)) self.component.set_send_controls((control_surface.get_encoder(3, 5), control_surface.get_encoder(3, 13), control_surface.get_encoder(3, 6), control_surface.get_encoder(3, 14))) # track navigation #control_surface.get_encoder(3,7).add_value_listener(self._track_nav) def _on_selected_track_changed(self): if self.song.view.selected_track: self.component.set_track(self.song.view.selected_track) def _get_all_tracks(self, only_visible=False): if not only_visible: return self.song.tracks + self.song.return_tracks + ( self.song.master_track, ) tracks = [] for track in self.song.tracks: if track.is_visible: tracks.append(track) for track in self.song.return_tracks: tracks.append(track) tracks.append(self.song.master_track) return tracks # helper function to go from one track to the other def _get_track_by_delta(self, track, d_value): tracks = self._get_all_tracks(only_visible=True) max_tracks = len(tracks) for i in range(max_tracks): if track == tracks[i]: return tracks[max((0, min(i + d_value, max_tracks - 1)))] def _track_nav(self, value): value -= 64 self.song.view.selected_track = self._get_track_by_delta( self.song.view.selected_track, value)
class TrackControl(): def __init__(self, control_surface): self.control_surface = control_surface self.song = control_surface.song() self.component = ChannelStripComponent() self.component.set_track(self.song.view.selected_track) self.component.set_volume_control(control_surface.get_encoder(3,12)) self.component.set_pan_control(control_surface.get_encoder(3,4)) self.component.set_send_controls((control_surface.get_encoder(3,5), control_surface.get_encoder(3,13), control_surface.get_encoder(3,6), control_surface.get_encoder(3,14))) # track navigation #control_surface.get_encoder(3,7).add_value_listener(self._track_nav) def _on_selected_track_changed(self): if self.song.view.selected_track: self.component.set_track(self.song.view.selected_track) def _get_all_tracks(self, only_visible = False): if not only_visible: return self.song.tracks + self.song.return_tracks + (self.song.master_track, ) tracks = [] for track in self.song.tracks: if track.is_visible: tracks.append(track) for track in self.song.return_tracks: tracks.append(track) tracks.append(self.song.master_track) return tracks # helper function to go from one track to the other def _get_track_by_delta(self, track, d_value): tracks = self._get_all_tracks(only_visible = True) max_tracks = len(tracks) for i in range(max_tracks): if track == tracks[i]: return tracks[max((0, min(i+d_value, max_tracks-1)))] def _track_nav(self, value): value-= 64 self.song.view.selected_track = self._get_track_by_delta(self.song.view.selected_track, value)
def set_track(self, track): assert (track == None) or isinstance(track, Live.Track.Track) if track != self._track: if self._track != None: volume = self._track.mixer_device.volume panning = self._track.mixer_device.panning sends = self._track.mixer_device.sends if volume.value_has_listener(self._on_volume_changed): volume.remove_value_listener(self._on_volume_changed) if panning.value_has_listener(self._on_panning_changed): panning.remove_value_listener(self._on_panning_changed) if (len(sends) > 0) and sends[0].value_has_listener(self._on_send1_changed): sends[0].remove_value_listener(self._on_send1_changed) if (len(sends) > 1) and sends[1].value_has_listener(self._on_send2_changed): sends[1].remove_value_listener(self._on_send2_changed) ChannelStripComponent.set_track(self, track) else: self.update()
def set_track(self, track): assert ((track == None) or isinstance(track, Live.Track.Track)) if (track != self._track): if (self._track != None): volume = self._track.mixer_device.volume panning = self._track.mixer_device.panning sends = self._track.mixer_device.sends if volume.value_has_listener(self._on_volume_changed): volume.remove_value_listener(self._on_volume_changed) if panning.value_has_listener(self._on_panning_changed): panning.remove_value_listener(self._on_panning_changed) if len(sends) > 0 and sends[0].value_has_listener(self._on_send1_changed): sends[0].remove_value_listener(self._on_send1_changed) if len(sends) > 1 and sends[1].value_has_listener(self._on_send2_changed): sends[1].remove_value_listener(self._on_send2_changed) ChannelStripComponent.set_track(self, track) else: self.update()
class Pw(ControlSurface): def __init__(self, c_instance): super(Pw, self).__init__(c_instance) with self.component_guard(): self.clips = [] config = self._open_config() self._setup_session(config['width'], config['height']) self._setup_strip() self._track_clip_slots_info() def _open_config(self): with open('/users/berry/config.json') as f: data = json.load(f) self.log(json.dumps(data)) return json.loads(json.dumps(data)) def _track_clip_slots_info(self): track = self.session.tracks_to_use()[0] for cs in track.clip_slots: if cs.clip is not None: self.clips.append(cs.clip.name) self.log(json.dumps(self.clips)) def _setup_session(self, width, height): self.session = SessionComponent(width, height) self.session.set_offsets(0, 0) self.set_highlighting_session_component(self.session) def _setup_strip(self): self.strip = ChannelStripComponent() self._update_strip() def _update_strip(self): self.strip.set_track(self.session.tracks_to_use()[0]) def log(self, message): log_str = 'LOG: ' + message + '\n' with io.open("/users/berry/somefile.txt", mode='w', encoding='utf-8') as f: f.write(log_str) f.close()
def set_track(self, track): if self._track is not None: try: self._track.remove_color_listener(self._on_color_changed) self._track.remove_devices_listener(self._on_devices_changed) self._track.view.remove_selected_device_listener(self._on_selected_device_changed) except: pass if self._track in self.song().tracks and not self._track.is_foldable: self._track.remove_current_monitoring_state_listener(self._on_monitor_changed) self._track.remove_playing_slot_index_listener(self._on_playing_slot_changed) ChannelStripComponent.set_track(self, track) if track is not None: self._track.add_color_listener(self._on_color_changed) self._track.add_devices_listener(self._on_devices_changed) self._track.view.add_selected_device_listener(self._on_selected_device_changed) if track in self.song().tracks and not track.is_foldable: self._track.add_current_monitoring_state_listener(self._on_monitor_changed) self._track.add_playing_slot_index_listener(self._on_playing_slot_changed) self._on_selected_device_changed()
def set_track(self, track): if self._track is not None: try: self._track.remove_color_listener(self._on_color_changed) self._track.remove_devices_listener(self._on_devices_changed) self._track.view.remove_selected_device_listener(self._on_selected_device_changed) except: pass if self._track in self.song().tracks and not self._track.is_foldable: self._track.remove_current_monitoring_state_listener(self._on_monitor_changed) self._track.remove_playing_slot_index_listener(self._on_playing_slot_changed) ChannelStripComponent.set_track(self, track) if track is not None: self._track.add_color_listener(self._on_color_changed) self._track.add_devices_listener(self._on_devices_changed) self._track.view.add_selected_device_listener(self._on_selected_device_changed) if track in self.song().tracks and not track.is_foldable: self._track.add_current_monitoring_state_listener(self._on_monitor_changed) self._track.add_playing_slot_index_listener(self._on_playing_slot_changed) self._on_selected_device_changed()
class TrackControl(): def __init__(self, control_surface): self.control_surface = control_surface self.song = control_surface.song() self.component = ChannelStripComponent() self.component.set_track(self.song.view.selected_track) for cc, callback in ((100, self._arm), (108, self._mute_solo), (111, self._track_nav)): EncoderElement( MIDI_CC_TYPE, \ settings.CHANNEL, \ cc, \ Live.MidiMap.MapMode.relative_two_compliment)\ .add_value_listener(callback) #for cc, callback in ((101, "set_pan_control"), (109, "set_volume_control")): self.component.set_pan_control(\ EncoderElement( MIDI_CC_TYPE, \ settings.CHANNEL, \ 101, \ Live.MidiMap.MapMode.relative_two_compliment)) self.component.set_volume_control(\ EncoderElement( MIDI_CC_TYPE, \ settings.CHANNEL, \ 109, \ Live.MidiMap.MapMode.relative_two_compliment)) def _on_selected_track_changed(self): if self.song.view.selected_track: self.component.set_track(self.song.view.selected_track) def _get_all_tracks(self, only_visible = False): if not only_visible: return self.song.tracks + self.song.return_tracks + (self.song.master_track, ) tracks = [] for track in self.song.tracks: if track.is_visible: tracks.append(track) for track in self.song.return_tracks: tracks.append(track) tracks.append(self.song.master_track) return tracks # helper function to go from one track to the other def _get_track_by_delta(self, track, d_value): tracks = self._get_all_tracks(only_visible = True) max_tracks = len(tracks) for i in range(max_tracks): if track == tracks[i]: return tracks[max((0, min(i+d_value, max_tracks-1)))] def _arm(self, value): track = self.song.view.selected_track if track.can_be_armed: if value > 65: track.arm = False else: track.arm = True def _mute_solo(self, value): track = self.song.view.selected_track if value > 65: if track.solo: track.solo = False else: track.mute = True else: if track.mute: track.mute = False else: track.solo = True def _track_nav(self, value): if value > 65: value = value-128 self.song.view.selected_track = self._get_track_by_delta(self.song.view.selected_track, value)
class MPK_SessionControl(ControlSurface): __module__ = __name__ __doc__ = "MPK Session Control Script" def __init__(self, c_instance): ControlSurface.__init__(self, c_instance) with self.component_guard(): self._setup_mixer_control() self._setup_transport_control() self._setup_session_control() self._setup_channel_strip_control() self.set_highlighting_session_component(self.session) # Sets up the control surface ('colored box') def _setup_session_control(self): num_tracks = 3 # 3 columns (tracks) num_scenes = 1 # 1 row (scenes) # a session highlight ("red box") will appear with any two non-zero values self.session = SessionComponent(num_tracks, num_scenes) # (track_offset, scene_offset) Sets the initial offset of the "red box" from top left self.session.set_offsets(0, 0) self.session.set_select_buttons( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C - 7), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C - 6)) # These calls control the actual movement of the box; however, we're just # using scene and track select to move around # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 86), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 85)) # self.session.set_track_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 15), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 14)) # Launch current scene with top right pad self.session.selected_scene().set_launch_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, BANK_B[3])) # Stop all clips with bottom right pad self.session.set_stop_all_clips_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, BANK_B[7])) # First three pads launch clips in box clip_launch_notes = [BANK_B[0], BANK_B[1], BANK_B[2]] clip_select_notes = [ KEYBOARD_MID_C - 6, KEYBOARD_MID_C - 4, KEYBOARD_MID_C - 2 ] for tracks in range(num_tracks): self.session.scene(0).clip_slot(tracks).set_launch_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, clip_launch_notes[tracks])) self.session.scene(0).clip_slot(tracks).set_select_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, clip_select_notes[tracks])) self.session.scene(0).clip_slot(tracks).set_started_value(1) self.session.scene(0).clip_slot(tracks).set_stopped_value(0) # Bottom three pads stop current tracks in box track_stop_notes = [BANK_B[4], BANK_B[5], BANK_B[6]] # This looks unnecessary but I don't know the actual API call to to set the stop track button for the selected track stop_track_buttons = [] for tracks in range(num_tracks): stop_track_buttons.append( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, track_stop_notes[tracks])) self.session.set_stop_track_clip_buttons(tuple(stop_track_buttons)) #here we set up a mixer and channel strip(s) which move with the session self.session.set_mixer( self.mixer ) #bind the mixer to the session so that they move together selected_scene = self.song( ).view.selected_scene #this is from the Live API all_scenes = self.song().scenes index = list(all_scenes).index(selected_scene) self.session.set_offsets(0, index) #(track_offset, scene_offset) def _setup_transport_control(self): self.transport = TransportComponent() self.transport.set_stop_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_LOW_C)) self.transport.set_play_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 113)) self.transport.set_metronome_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 114)) self.transport.set_tap_tempo_button( ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 81)) def _setup_mixer_control(self): #set up the mixer self.mixer = MixerComponent( NUM_TRACKS, 2) #(num_tracks, num_returns, with_eqs, with_filters) self.mixer.set_track_offset( 0) #sets start point for mixer strip (offset from left) self.mixer.selected_strip().set_arm_button( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C)) self.mixer.set_select_buttons( ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C - 2), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KEYBOARD_HIGH_C - 4)) self.mixer.master_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[3])) #self.mixer.master_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[7])) #set the selected strip to the first track, so that we don't assign a button to arm the master track, which would cause an assertion error self.song().view.selected_track = self.mixer.channel_strip(0)._track self.mixer.selected_strip().set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[0])) #self.mixer.selected_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[4])) selected_track = self.song().view.selected_track all_tracks = ((self.song().tracks + self.song().return_tracks) + (self.song().master_track, )) currentTrackIndex = list(all_tracks).index(selected_track) if currentTrackIndex < len(all_tracks) - 1: self.mixer.channel_strip(currentTrackIndex + 1).set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[1])) #self.mixer.channel_strip(currentTrackIndex + 1).set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[5])) if currentTrackIndex < len(all_tracks) - 2: self.mixer.channel_strip(currentTrackIndex + 2).set_volume_control( SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[2])) #self.mixer.channel_strip(currentTrackIndex + 2).set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KNOBS[6])) def _setup_channel_strip_control(self): self.channelstrip = ChannelStripComponent() self.channelstrip.set_track(self.mixer.channel_strip(0)._track) def _on_selected_track_changed(self): """This is an override, to add special functionality (we want to move the session to the selected track, when it changes) Note that it is sometimes necessary to reload Live (not just the script) when making changes to this function""" ControlSurface._on_selected_track_changed( self ) # This will run component.on_selected_track_changed() for all components """here we set the mixer and session to the selected track, when the selected track changes""" selected_track = self.song( ).view.selected_track #this is how to get the currently selected track, using the Live API self.mixer.channel_strip(0).set_track(selected_track) all_tracks = ( (self.song().tracks + self.song().return_tracks) + (self.song().master_track, ) ) #this is from the MixerComponent's _next_track_value method index = list(all_tracks).index(selected_track) #and so is this self.session.set_offsets( index, self.session._scene_offset ) #(track_offset, scene_offset); we leave scene_offset unchanged, but set track_offset to the selected track. This allows us to jump the red box to the selected track. def _on_selected_scene_changed(self): """This is an override, to add special functionality (we want to move the session to the selected scene, when it changes)""" """When making changes to this function on the fly, it is sometimes necessary to reload Live (not just the script)...""" ControlSurface._on_selected_scene_changed( self ) # This will run component.on_selected_scene_changed() for all components """Here we set the mixer and session to the selected track, when the selected track changes""" selected_scene = self.song( ).view.selected_scene #this is how we get the currently selected scene, using the Live API all_scenes = self.song().scenes #then get all of the scenes index = list(all_scenes).index( selected_scene ) #then identify where the selected scene sits in relation to the full list self.session.set_offsets( self.session._track_offset, index ) #(track_offset, scene_offset) Set the session's scene offset to match the selected track (but make no change to the track offset) def disconnect(self): #clean things up on disconnect #create entry in log file self.log_message( time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "----------MPK SessionControl log closed----------") ControlSurface.disconnect(self) return None