コード例 #1
0
ファイル: OhmModesHH.py プロジェクト: amuntner/m4m7
	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (7) #A mixer is one-dimensional; 
		global mixer
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		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 #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
コード例 #2
0
 def _setup_mixer_control(self):
     is_momentary = True
     self._num_tracks = (7)  #A mixer is one-dimensional;
     global mixer
     mixer = SpecialMixerComponent(7, 0, True, False)
     mixer.name = 'Mixer'
     self._mixer = mixer
     mixer.set_track_offset(
         0)  #Sets start point for mixer strip (offset from left)
     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  #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
コード例 #3
0
class QuNeo(ControlSurface):
    __doc__ = " Minimal Script for Volume control via _Framework by @djnsm / Data Mafia "
    __module__ = __name__

    # INIT FUNCTION FOR QUNEO
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)  # in aaa
        with self.component_guard():  # new for Live9 / Py
            self._suppress_session_highlight = True
            self._suppress_send_midi = True
            #   self.session = None #===========
            self.mixer = None
            self.box_width = box_width
            # self.transport = None -----marwei
            # self.led_value = None ------marwei
            #self._note_input = [] -------marwei

            # marwei added for web app++
            self.gutter = gutter  # see param info

            self.volume_control = None

            self._setup_mixer_control()  #------- needed
            #self._setup_session_control() # -----------
            #self.session.set_mixer(self.mixer) #----------

            # @marwei --- needed? 8apr
            self._suppress_session_highlight = False

    # DISCONNECT FUNCTION
    def disconnect(self):
        self.mixer
        self.session

        #self._note_input = None
        ControlSurface.disconnect(self)
        return None

    # CREATE A SLIDER @marwei reqd
    def slider(self, channel, value):
        if (value != -1):
            return SliderElement(MIDI_CC_TYPE, channel, value)
        else:
            return None

    # REASSIGN MIXER
    def _reassign_mixer_control(self, shift_value):
        self.volume_control = self.slider(midi_channel, SELECTED_VOL)
        if (self.volume_control != None):
            self.mixer.selected_strip().set_volume_control(self.volume_control)
        else:
            self.mixer.selected_strip().set_volume_control(None)

    # SETUP MIXER
    def _setup_mixer_control(self):

        self.mixer = SpecialMixerComponent(
            self.box_width, self)  # get a local mixer object ready
        self.mixer.name = 'Mixer'  # name
        self.mixer.set_track_offset(self.gutter)  # gutter ----marwei
        # compare width with track vol count to qualify -- put somewhere else
        for index in range(
                self.box_width):  # @marwei must kill this style and count
            self.mixer.channel_strip(index).set_volume_control(
                self.slider(midi_channel, track_volume[index]))
コード例 #4
0
class NanoKontrolLP95(ControlSurface):
    __module__ = __name__
    __doc__ = " NanoKontrolLP95 controller script "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn off rebuild MIDI map until after we're done setting up
        Live.Base.log(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolLP95 log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        with self.component_guard():
            # OBJECTS
            self._session = None #session object
            self._mixer = None #mixer object
            self._transport = None #transport object
            self._last_button_time = time.time()
            self._io_list_index = 0
            
            self._setup_controls()

            self._setup_session_control()  # Setup the session object
            self._setup_mixer_control() # Setup the mixer object
            self._session.set_mixer(self._mixer) # Bind mixer to session
            self._setup_transport_control() # Setup transport object

            self._set_mode_button()
            self._set_normal_mode()
            self._track = self.song().view.selected_track
            
            self.set_highlighting_session_component(self._session)

            self._flash_counter = 0
            self._flash_on = True
            
            for component in self.components:
                component.set_enabled(True)

        self._suppress_send_midi = True # Turn rebuild back on, once we're done setting up
        Live.Base.log("NanoKontrolLP95 Loaded !")

    def disconnect(self):
        """clean things up on disconnect"""
        if self._cycle_button != None:
            self._cycle_button.remove_value_listener(self._cycle_button_value)
        self._clear_controls()
        self._transport.set_stop_button(None)
        self._transport.set_play_button(None)
        self._transport.set_rec_button(None)

        self._solo_buttons = None 
        self._mute_buttons = None 
        self._arm_buttons = None 
        self._knobs = None 
        self._faders = None 

        self._ff_button = None
        self._rwd_button = None
        self._play_button = None
        self._stop_button = None
        self._rec_button = None
        
        self._track_left_button = None
        self._track_right_button = None
        self._cycle_button = None
        
        self._set_button = None    
        self._mrk_left_button = None
        self._mrk_right_button = None
        
        self._session = None
        self._mixer = None
        self._transport = None

        ControlSurface.disconnect(self)
    
    def _setup_controls(self):
        self._track_left_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_left_btn)
        self._track_right_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_right_btn)    
        self._cycle_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, cycle_btn)
        self._cycle_button_active = False             
        
        self._set_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, set_btn)        
        self._mrk_left_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, mrk_left_btn)
        self._mrk_right_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, mrk_right_btn)

        self._ff_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, ff_btn)
        self._rwd_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, rwd_btn)        
        self._play_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, play_btn)
        self._stop_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, stop_btn)
        self._rec_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, rec_btn)
        
        self._solo_buttons = [ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_solo_cc[index]) for index in range(num_tracks)] 
        self._mute_buttons = [ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_mute_cc[index]) for index in range(num_tracks)] 
        self._arm_buttons = [ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_arm_cc[index]) for index in range(num_tracks)] 
        self._knobs = [SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_knob_cc[index]) for index in range(num_tracks)] 
        self._faders = [SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_fader_cc[index]) for index in range(num_tracks)] 
    
    
    def _setup_session_control(self):
        # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX
        self._session = SpecialSessionComponent(num_tracks, num_scenes) #(num_tracks, num_scenes)
        self._session.set_offsets(0, 0)

    def _setup_mixer_control(self):
        #CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON)
        self._mixer = SpecialMixerComponent(self, num_tracks, 0, False, False) # 8 tracks, 2 returns, no EQ, no filters
        self._mixer.name = 'Mixer'
        self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
        self._mixer.set_select_buttons(self._track_right_button,self._track_left_button)
        self._mixer.set_knobs(self._knobs)
    def _setup_transport_control(self):
        # CREATE TRANSPORT DEVICE
        self._transport = SpecialTransportComponent(self)
        self._transport.set_stop_button(self._stop_button)
        self._transport.set_play_button(self._play_button)
        self._transport.set_rec_button(self._rec_button)
        
    def connect_script_instances(self, instanciated_scripts):
        #Live.Base.log("connect_script_instances - Start")
        #Live.Base.log("connect_script_instances - self._control_surfaces()=" + str(self._control_surfaces()))
        if(linked):
            for control_surface in self._control_surfaces():
                control_surface_type = str(control_surface)
                for sync_master in SYNC_TO_LIST:
                    if(control_surface_type.count(sync_master)>0):
                        control_surface_session = control_surface.highlighting_session_component()
                        if control_surface_session:
                            self._session.sync_to(control_surface_session)
                            self._on_track_list_changed()
                            break


    def _clear_controls(self):
            
        if (self._ff_button != None):
            self._ff_button.remove_value_listener(self._out_value)
            self._ff_button.turn_off()
    
        if (self._rwd_button != None):
            self._rwd_button.remove_value_listener(self._in_value)
            self._rwd_button.turn_off()           
            
        if (self._set_button != None):
            self._set_button.remove_value_listener(self._monitor_value)
            self._set_button.remove_value_listener(self._dup_track_value)           
            
        if (self._mrk_left_button != None):
            self._mrk_left_button.remove_value_listener(self._sub_in_value)
            self._mrk_left_button.remove_value_listener(self._new_midi_value)            
            
        if (self._mrk_right_button != None):
            self._mrk_right_button.remove_value_listener(self._sub_out_value)
            self._mrk_right_button.remove_value_listener(self._new_audio_value)            

        # SESSION
        resetsend_controls = []
        self._mixer.send_controls = []
        self._session.set_stop_track_clip_buttons(None)

        # MIXER
        self._mixer._set_send_nav(None, None)
        for track_index in range(num_tracks):
            strip = self._mixer.channel_strip(track_index)
            strip.set_solo_button(None)
            strip.set_mute_button(None)
            strip.set_arm_button(None)
            resetsend_controls.append(None)
            strip.set_select_button(None)
            for i in range(12):
                self._mixer.send_controls.append(None)
            strip.set_send_controls(tuple(self._mixer.send_controls))
        self._mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self.log_message("Controls Cleared")

    def _set_mode_button(self):
        if self._cycle_button != None:
            self._cycle_button.remove_value_listener(self._cycle_button_value)
            self._cycle_button.add_value_listener(self._cycle_button_value)
            self._cycle_button.set_light(self._cycle_button_active)

    def _cycle_button_value(self, value):
        assert (value in range(128))        
        if self._cycle_button != None:
            if value is not 0:
                self._cycle_button_active = not self._cycle_button_active
                self._clear_controls()
                if self._cycle_button_active:
                    self._set_alt_mode()
                else:
                    self._set_normal_mode()
                self.update()   
            
    def _set_normal_mode(self):
        for index in range(num_tracks):
            strip = self._mixer.channel_strip(index)
            strip.set_solo_button(self._solo_buttons[index])
            strip.set_mute_button(self._mute_buttons[index])
            strip.set_arm_button(self._arm_buttons[index])
            strip.set_pan_control(self._knobs[index])
            strip.set_volume_control(self._faders[index])
        self._set_in_out_nav_listeners()    
        self.show_message("IN/OUT SETUP - MUTE SOLO ARM")
                        
    def _set_alt_mode(self):
        self._mixer._set_send_nav(self._ff_button, self._rwd_button)
        stop_track_controls = []
        resetsend_controls = []
        # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB
        for index in range(num_tracks):
            strip = self._mixer.channel_strip(index)
            strip.set_select_button(self._solo_buttons[index])
            stop_track_controls.append(self._arm_buttons[index])
            resetsend_controls.append(self._mute_buttons[index])
        self._session.set_stop_track_clip_buttons(tuple(stop_track_controls))
        self._mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self._mixer._update_send_index()
        self._set_create_track_listeners()
        self.show_message("TRACK CREATE DEL DUPE - SEL STOP RESET SEND")
        
    def _set_in_out_nav_listeners(self):
        if (self._ff_button != None):
            self._ff_button.add_value_listener(self._out_value)
    
        if (self._rwd_button != None):
            self._rwd_button.add_value_listener(self._in_value)
            
        if (self._set_button != None):
            self._set_button.add_value_listener(self._monitor_value)
            
        if (self._mrk_left_button != None):
            self._mrk_left_button.add_value_listener(self._sub_in_value)
            
        if (self._mrk_right_button != None):
            self._mrk_right_button.add_value_listener(self._sub_out_value)                                                
        self.update()
           
    def _monitor_value(self, value):
        now = time.time()
        if(value is not 0):
            self._last_button_time = now
        else:
            song = self.song()
            if self._track in song.tracks:
                if now - self._last_button_time < LONG_PRESS:            
                    if not self._track.is_foldable:
                        self._track.current_monitoring_state = (self._track.current_monitoring_state + 1) % 3
                else:  
                    self._set_default_io()            

    def _set_default_io(self):
        if self._track.has_midi_input:
                self._track.input_routing_type = list(self._track.available_input_routing_types)[0]
                if self._track.has_audio_output:
                    if self._track.is_grouped:
                        self._track.output_routing_type = list(self._track.available_output_routing_types)[2]       
                    else:
                        self._track.output_routing_type = list(self._track.available_output_routing_types)[1]
                else:
                    self._track.output_routing_type = list(self._track.available_output_routing_types)[-1]
        else:
                self._track.input_routing_type = list(self._track.available_input_routing_types)[-1]
                if self._track.is_grouped:
                    self._track.output_routing_type = list(self._track.available_output_routing_types)[2]       
                else:
                    self._track.output_routing_type = list(self._track.available_output_routing_types)[1]
                    
        self._track.input_routing_channel = list(self._track.available_input_routing_channels)[0]            
        self._track.output_routing_channel = list(self._track.available_output_routing_channels)[0]  
        self.show_message("TRACK: " + str(self._track.name) + ' INPUT - OUTPUT RESET ')                             
                                     
    def _in_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_input_routing_types)
            current_routing = self._track.input_routing_type
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.input_routing_type = routings[new_index]
                route = ' INPUT: ' +  str(self._track.input_routing_type.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)
            self.update()
            
    def _out_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_output_routing_types)
            current_routing = self._track.output_routing_type
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.output_routing_type = routings[new_index]
                route = ' OUTPUT: ' +  str(self._track.output_routing_type.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)
        self.update()

    def _sub_in_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_input_routing_channels)
            current_routing = self._track.input_routing_channel
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.input_routing_channel = routings[new_index]
                route = ' SUB_INPUT: ' +  str(self._track.input_routing_channel.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)
            self.update()
     
    def _sub_out_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_output_routing_channels)
            current_routing = self._track.output_routing_channel
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.output_routing_channel = routings[new_index]
                route = ' SUB_OUTPUT: ' +  str(self._track.output_routing_channel.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)                       
            self.update()


    def _on_selected_track_changed(self):
        # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY
        ControlSurface._on_selected_track_changed(self)
        self._track = self.song().view.selected_track
              
    def update(self):
        ControlSurface.update(self)
        self._cycle_button.set_light(self._cycle_button_active)
        
        
    def _set_create_track_listeners(self):
        if (self._set_button != None):
            self._set_button.add_value_listener(self._dup_track_value)
            
        if (self._mrk_left_button != None):
            self._mrk_left_button.add_value_listener(self._new_midi_value)
            
        if (self._mrk_right_button != None):
            self._mrk_right_button.add_value_listener(self._new_audio_value)                                                
        self.update()            
        
    def _dup_track_value(self, value):
        now = time.time()
        if(value is not 0):
            self._last_button_time = now
        else:
            song = self.song()
            if self._track in song.tracks:
                if now - self._last_button_time < LONG_PRESS:            
                    song.duplicate_track(list(song.tracks).index(self._track))
                else:  
                    song.delete_track(list(song.tracks).index(self._track))

    def _new_audio_value(self, value):
        if(value is not 0):
            self._add_track(self.song().create_audio_track)
            
    def _new_midi_value(self, value):
        if(value is not 0):
            self._add_track(self.song().create_midi_track)
            
    def _add_track(self, func):
        song = self.song()
        index = list(song.tracks).index(self._track) + 1
        if index < len(song.tracks) and index >0:
            track = song.tracks[index]
            if track.is_foldable or track.is_grouped:
                while index < len(song.tracks) and song.tracks[index].is_grouped:
                    index += 1
        func(index)
        
    @profile
    def update_display(self):
        super(NanoKontrolLP95, self).update_display()
        self._flash_counter = self._flash_counter + 1
        if self._cycle_button_active  == True:
            if(self._flash_counter % 2  == 0):
                if (self._flash_on == True):
                    self._cycle_button.send_value(127) 
                else:
                    self._cycle_button.send_value(0) 
                self._flash_on = not self._flash_on
                self._flash_counter = self._flash_counter % 4                                                  
コード例 #5
0
class QuNeo(ControlSurface):
    __doc__ = " Minimal Script for Volume control via _Framework by @djnsm / Data Mafia "
    __module__ = __name__
    
    # INIT FUNCTION FOR QUNEO   
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance) # in aaa
        with self.component_guard(): # new for Live9 / Py
          self._suppress_session_highlight = True
          self._suppress_send_midi = True
       #   self.session = None #===========
          self.mixer = None
          self.box_width = box_width
         # self.transport = None -----marwei
         # self.led_value = None ------marwei
          #self._note_input = [] -------marwei
          
          # marwei added for web app++
          self.gutter = gutter # see param info
 
          self.volume_control = None
 
          self._setup_mixer_control() #------- needed
          #self._setup_session_control() # -----------
          #self.session.set_mixer(self.mixer) #----------
 
          # @marwei --- needed? 8apr
          self._suppress_session_highlight = False
                  
    # DISCONNECT FUNCTION
    def disconnect(self):
        self.mixer
        self.session
            
       #self._note_input = None
        ControlSurface.disconnect(self)
        return None

    
    # CREATE A SLIDER @marwei reqd
    def slider(self, channel, value):
        if (value != -1):
            return SliderElement(MIDI_CC_TYPE, channel, value)
        else:
            return None
            
            
    # REASSIGN MIXER
    def _reassign_mixer_control(self, shift_value):
        self.volume_control = self.slider(midi_channel, SELECTED_VOL)
        if (self.volume_control != None):
            self.mixer.selected_strip().set_volume_control(self.volume_control)
        else:
            self.mixer.selected_strip().set_volume_control(None)
    
    # SETUP MIXER
    def _setup_mixer_control(self):
        
        self.mixer = SpecialMixerComponent(self.box_width, self) # get a local mixer object ready
        self.mixer.name = 'Mixer' # name
        self.mixer.set_track_offset(self.gutter)  # gutter ----marwei
        # compare width with track vol count to qualify -- put somewhere else 
        for index in range(self.box_width): # @marwei must kill this style and count
            self.mixer.channel_strip(index).set_volume_control(self.slider(midi_channel, track_volume[index]))
            
コード例 #6
0
ファイル: QuNeo.py プロジェクト: uniphonic/MidiScripts
class QuNeo(ControlSurface):
    """ Script for Keith McMillen's QuNeo Multi-Touchpad Controller """
    __module__ = __name__
    _active_instances = []

    def _combine_active_instances():
        support_devices = False
        for instance in QuNeo._active_instances:
            support_devices |= instance._device_component != None

        track_offset = 0
        for instance in QuNeo._active_instances:
            instance._activate_combination_mode(track_offset, support_devices)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(True)
        self._suppress_session_highlight = True
        self._suppress_send_midi = True
        self._suggested_input_port = 'QUNEO'
        self._suggested_output_port = 'QUNEO'
        self.num_tracks = 7
        self.num_scenes = 4
        self.session = None
        self.mixer = None
        self.transport = None
        self.led_value = None
        self._note_input = []
        self.shift_button = None
        self.sequencer_button = None
        self.launch_button = None
        self.seq_offset_down = None
        self.seq_offset_up = None
        self.seq_offset_left = None
        self.seq_offset_right = None
        self.stop_all_clips = None
        self.track_bank_right = None
        self.track_bank_left = None
        self.scene_bank_down = None
        self.scene_bank_up = None
        self.beat_table = []
        self.sends = []
        self.arm_buttons = None
        self.mute_buttons = None
        self.solo_buttons = None
        self.shift_buttons = []
        self.sequencer_buttons = None
        self.scene_launch_buttons = None
        self.stop_track_buttons = None
        self.clip_slot_buttons = None
        self.instrument_buttons = None
        self.volume_control = None
        self.pan_control = None
        self.current_mode = 0
        self.set_shift_button(ConfigurableButtonElement(True, MIDI_NOTE_TYPE, PAD_CHANNEL, SHIFT_BUTTON, 127))
        self._setup_transport_control()
        self._setup_mixer_control()
        self._setup_session_control()
        self.session.set_mixer(self.mixer)
        self._shift_mode(0)
        self._set_mode(0)
        app = Live.Application.get_application()
        maj = app.get_major_version()
        min = app.get_minor_version()
        bug = app.get_bugfix_version()
        self.show_message(str(maj) + '.' + str(min) + '.' + str(bug))
        self.set_suppress_rebuild_requests(False)

    def disconnect(self):
        self.mixer
        self.session
        if self.shift_button != None:
            self.shift_button.remove_value_listener(self._shift_value)
            self.shift_button = None
        if self.shift_buttons != None:
            for button in self.shift_buttons:
                button.remove_value_listener(self._shift_buttons_value)

            self.shift_buttons = None
        self._note_input = None
        ControlSurface.disconnect(self)

    def refresh_state(self):
        ControlSurface.refresh_state(self)

    def set_shift_button(self, button):
        if not (button == None or isinstance(button, ButtonElement)):
            raise AssertionError
            if self.shift_button != button:
                if self.shift_button != None:
                    self.shift_button.remove_value_listener(self._shift_value)
                self.shift_button = button
                self.shift_button != None and self.shift_button.add_value_listener(self._shift_value)

    def update_mode(self, mode):
        if mode != None:
            self._set_mode(mode)
            self.current_mode = mode

    def set_shift_buttons(self, buttons):
        if buttons != None:
            if self.shift_buttons != buttons:
                self.shift_buttons.remove_value_listener(self._shift_buttons_value)
            self.shift_buttons = buttons
            if self.shift_buttons != None:
                for button in self.shift_buttons:
                    raise isinstance(button, ButtonElement) or AssertionError
                    button.add_value_listener(self._shift_buttons_value, identify_sender=True)

        else:
            if self.shift_buttons != None:
                for button in self.shift_buttons:
                    button.remove_value_listener(self._shift_buttons_value)

            self.shift_buttons = None

    def _shift_buttons_value(self, value, sender):
        raise self.shift_buttons != None or AssertionError
        raise value in range(128) or AssertionError
        mode = int(sender._note * 0.5)
        self.update_mode(mode)

    def _shift_value(self, value):
        if not value in range(128):
            raise AssertionError
            raise self.shift_button != None or AssertionError
            value != 0 and self._shift_mode(1)
            self.shift_button.turn_on()
        else:
            self._shift_mode(0)
            self.shift_button.turn_off()

    def _shift_mode(self, value):
        if value != 0:
            self.set_suppress_rebuild_requests(True)
            self._reassign_grid(0)
            self._reassign_mixer_control(1)
            self.set_suppress_rebuild_requests(False)
        else:
            None
            self._set_mode(self.current_mode)
            self._reassign_mixer_control(1)

    def _update_grid(self):
        if self.sequencer_buttons != None:
            self.session.set_sequencer_buttons(self.sequencer_buttons)
        else:
            self.session.set_sequencer_buttons(None)
        if self.seq_offset_left != None and self.seq_offset_right != None:
            self.session.set_seq_measure_offset(self.seq_offset_left, self.seq_offset_right)
        else:
            self.session.set_seq_measure_offset(None, None)
        if self.seq_offset_up != None and self.seq_offset_down != None:
            self.session.set_seq_note_offset(self.seq_offset_up, self.seq_offset_down)
        else:
            self.session.set_seq_note_offset(None, None)
        if self.launch_button != None:
            self.session.set_slot_launch_button(self.launch_button)
        else:
            self.session.set_slot_launch_button(None)
        if self.scene_launch_buttons != None:
            for index in range(len(self.scene_launch_buttons)):
                self.session.scene(index).set_launch_button(self.scene_launch_buttons[index])

        else:
            for index in range(4):
                self.session.scene(index).set_launch_button(None)

        if self.stop_track_buttons != None:
            self.session.set_stop_track_clip_buttons(tuple(self.stop_track_buttons))
        else:
            self.session.set_stop_track_clip_buttons(None)
        if self.stop_all_clips != None:
            self.session.set_stop_all_clips_button(self.stop_all_clips)
        else:
            self.session.set_stop_all_clips_button(None)
        if self.track_bank_right != None and self.track_bank_left != None:
            self.session.set_track_bank_buttons(self.track_bank_right, self.track_bank_left)
        else:
            self.session.set_track_bank_buttons(None, None)
        if self.scene_bank_up != None and self.scene_bank_down != None:
            self.session.set_scene_bank_buttons(self.scene_bank_up, self.scene_bank_down)
        else:
            self.session.set_scene_bank_buttons(None, None)
        for row in range(4):
            for col in range(7):
                self.clip = self.session.scene(row).clip_slot(col)
                if self.clip_slot_buttons != None:
                    self.clip.set_triggered_to_play_value(30)
                    self.clip.set_triggered_to_record_value(RED_HI)
                    self.clip.set_started_value(30)
                    self.clip.set_recording_value(RED_HI)
                    self.clip.set_stopped_value(80)
                    self.clip.set_triggered_to_record_value(6)
                    self.clip.set_launch_button(self.clip_slot_buttons[row][col])
                else:
                    self.clip.set_launch_button(None)

    def turn_off_all_buttons(self):
        self.arm_buttons = None
        self.mute_buttons = None
        self.solo_buttons = None
        self.scene_launch_buttons = None
        self.stop_track_buttons = None
        if self.clip_slot_buttons != None:
            for row in range(4):
                for col in range(7):
                    button = self.clip_slot_buttons[row][col]
                    button.turn_off()

        self.clip_slot_buttons = None
        if self.shift_buttons != None:
            for button in self.shift_buttons:
                button.turn_off()
                button.remove_value_listener(self._shift_buttons_value)

        if self.sequencer_buttons != None:
            for button in self.sequencer_buttons:
                button.count = 0
                button.note_on()

        self.instrument_buttons = None
        self.shift_buttons = None
        self.sequencer_buttons = None
        self.clip_slot_buttons = None
        self.launch_button = None
        self.stop_all_clips = None
        self.track_bank_left = None
        self.track_bank_right = None
        self.scene_bank_up = None
        self.scene_bank_down = None
        self.seq_offset_left = None
        self.seq_offset_right = None
        self.seq_offset_up = None
        self.seq_offset_down = None

    def _set_mode(self, mode):
        self.turn_off_all_buttons()
        if mode == 0:
            self.stop_track_buttons = []
            self.scene_launch_buttons = []
            self.track_bank_left = self.button(PAD_CHANNEL, SESSION_LEFT)
            self.track_bank_right = self.button(PAD_CHANNEL, SESSION_RIGHT)
            self.scene_bank_up = self.button(PAD_CHANNEL, SESSION_UP)
            self.scene_bank_down = self.button(PAD_CHANNEL, SESSION_DOWN)
            self.stop_all_clips = self.led_button(GRID_CHANNEL, STOP_ALL_CLIPS, 100)
            self.launch_button = self.led_button(GRID_CHANNEL, SLOT_LAUNCH, RED_HI)
            self.clip_slot_buttons = []
            for row in range(4):
                self.clip_slot_buttons.append([])
                for col in range(7):
                    self.clip_slot_buttons[row].append(self.button(GRID_CHANNEL, CLIP_NOTE_MAP[row][col]))

            self.mute_buttons = []
            self.solo_buttons = []
            self.arm_buttons = []
            for index in range(7):
                self.mute_buttons.append(self.led_button(GRID_CHANNEL, TRACK_MUTE[index], GREEN_HI))
                self.solo_buttons.append(self.led_button(GRID_CHANNEL, TRACK_SOLO[index], ORANGE_HI))
                self.arm_buttons.append(self.led_button(GRID_CHANNEL, TRACK_ARM[index], RED_HI))
                self.stop_track_buttons.append(self.led_button(GRID_CHANNEL, STOP_TRACK[index], 100))

            for scene in range(4):
                self.scene_launch_buttons.append(self.led_button(GRID_CHANNEL, SCENE_LAUNCH[scene], GREEN_LO))

            self._update_session()
            self._update_grid()
        elif mode == 1:
            self.seq_offset_left = self.button(PAD_CHANNEL, SESSION_LEFT)
            self.seq_offset_right = self.button(PAD_CHANNEL, SESSION_RIGHT)
            self.seq_offset_up = self.button(PAD_CHANNEL, SESSION_UP)
            self.seq_offset_down = self.button(PAD_CHANNEL, SESSION_DOWN)
            self.sequencer_buttons = []
            for row in range(8):
                for col in range(8):
                    self.sequencer_buttons.append(self.led_button(GRID_CHANNEL, CLIP_NOTE_MAP[row][col], GREEN_HI))

            self._update_session()
            self._update_grid()
            self.session.clear_led()
            self.session.update_notes()
            self.session.on_device_changed()
        else:
            self.track_bank_left = self.button(PAD_CHANNEL, SESSION_LEFT)
            self.track_bank_right = self.button(PAD_CHANNEL, SESSION_RIGHT)
            self.scene_bank_up = self.button(PAD_CHANNEL, SESSION_UP)
            self.scene_bank_down = self.button(PAD_CHANNEL, SESSION_DOWN)
            self._update_session()
            self._update_grid()

    def _reassign_grid(self, value):
        if value == 0:
            self.turn_off_all_buttons()
            self.shift_buttons = []
            for index in range(2):
                self.shift_buttons.append(self.led_button(GRID_CHANNEL, TRACK_ARM[index], 127))
                if index == self.current_mode:
                    self.shift_buttons[index].send_value(127, True)
                else:
                    self.shift_buttons[index].send_value(40, True)

            self._update_session()
            self._update_grid()
        else:
            None

    def button(self, channel, value):
        is_momentary = True
        if value != -1:
            return ButtonElement(is_momentary, MIDI_NOTE_TYPE, channel, value)
        else:
            return None

    def led_button(self, channel, value, vel):
        is_momentary = True
        if value != -1:
            return ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, channel, value, vel)
        else:
            return None

    def slider(self, channel, value):
        if value != -1:
            return SliderElement(MIDI_CC_TYPE, channel, value)
        else:
            return None

    def assign_encoder(self, channel, value):
        if value != -1:
            return EncoderElement(MIDI_CC_TYPE, channel, value, Live.MidiMap.MapMode.relative_two_compliment)
        else:
            return None

    def _reassign_mixer_control(self, shift_value):
        if shift_value == 1:
            for index in range(2):
                self.sends.append(self.slider(SLIDER_CHANNEL, SELECTED_SENDS[index]))

            self.volume_control = self.slider(SLIDER_CHANNEL, SELECTED_VOL)
            self.pan_control = self.slider(SLIDER_CHANNEL, SELECTED_PAN)
        if self.sends != None:
            self.mixer.selected_strip().set_send_controls(tuple(self.sends))
        else:
            self.mixer.selected_strip().set_send_controls(tuple(None))
        if self.volume_control != None:
            self.mixer.selected_strip().set_volume_control(self.volume_control)
        else:
            self.mixer.selected_strip().set_volume_control(None)
        if self.pan_control != None:
            self.mixer.selected_strip().set_pan_control(self.pan_control)
        else:
            self.mixer.selected_strip().set_pan_control(None)

    def _update_session(self):
        if self.shift_buttons != None:
            self.set_shift_buttons(self.shift_buttons)
        else:
            self.set_shift_buttons(None)
        for index in range(7):
            if self.arm_buttons != None:
                self.mixer.channel_strip(index).set_arm_button(self.arm_buttons[index])
            else:
                self.mixer.channel_strip(index).set_arm_button(None)
            if self.solo_buttons != None:
                self.mixer.channel_strip(index).set_solo_button(self.solo_buttons[index])
            else:
                self.mixer.channel_strip(index).set_solo_button(None)
            if self.mute_buttons != None:
                self.mixer.channel_strip(index).set_invert_mute_feedback(True)
                self.mixer.channel_strip(index).set_mute_button(self.mute_buttons[index])
            else:
                self.mixer.channel_strip(index).set_mute_button(None)

    def _setup_transport_control(self):
        self.transport = SpecialTransportComponent()
        self.transport.set_metronome_button(self.led_button(PAD_CHANNEL, METRONOME, 127))
        self.transport.set_play_button(self.led_button(PAD_CHANNEL, PLAY, 127))
        self.transport.set_stop_button(self.led_button(PAD_CHANNEL, STOP, 127))
        self.transport.set_record_button(self.led_button(PAD_CHANNEL, REC, 127))
        self.transport.set_overdub_button(self.led_button(PAD_CHANNEL, OVERDUB, 127))
        self.transport.set_tempo_buttons(self.led_button(PAD_CHANNEL, TEMPO_UP, 127), self.led_button(PAD_CHANNEL, TEMPO_DOWN, 127))

    def _setup_mixer_control(self):
        self.mixer = SpecialMixerComponent(self.num_tracks, self)
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(0)
        self.mixer.set_select_buttons(self.button(PAD_CHANNEL, TRACK_RIGHT), self.button(PAD_CHANNEL, TRACK_LEFT))
        self.mixer.set_crossfader_control(self.slider(SLIDER_CHANNEL, CROSSFADER))
        for index in range(4):
            self.mixer.channel_strip(index).set_volume_control(self.slider(SLIDER_CHANNEL, TRACK_VOL[index]))

        self.num_o_tracks = self.song().visible_tracks
        if self.num_o_tracks != None:
            index_count = -1
            index_table = []
            for index in self.song().visible_tracks:
                index_count += 1
                if index.has_midi_output != True:
                    index_table.append(index_count)
                else:
                    None

            if index_table != None:
                for index in range(len(index_table)):
                    x = index_table[index]
                    if x > 3:
                        None
                    else:
                        None

    def _setup_session_control(self):
        self.session = SpecialSessionComponent(self.num_tracks, self.num_scenes, self)
        self.session.set_offsets(0, 0)
        self.session.set_select_buttons(self.button(PAD_CHANNEL, SCENE_DOWN), self.button(PAD_CHANNEL, SCENE_UP))
        self.session.set_clip_loop_start(self.slider(SLIDER_CHANNEL, 6))
        self.session.set_clip_loop_length(self.slider(SLIDER_CHANNEL, 7))

    def _on_selected_scene_changed(self):
        ControlSurface._on_selected_scene_changed(self)

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)

    def _activate_combination_mode(self, track_offset, support_devices):
        self._session.link_with_track_offset(track_offset)
コード例 #7
0
class NanoKontrolShift(ControlSurface):
    __module__ = __name__
    __doc__ = " NanoKontrolShift controller script "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn off rebuild MIDI map until after we're done setting up
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        with self.component_guard():
            # OBJECTS
            self.session = None #session object
            self.mixer = None #mixer object
            self.view = None #clip/device view object
            self.device = None #device object
            self.transport = None #transport object
            # MODES
            self._shift_button = None
            self._shift_button_pressed = False
            self._alt_button = None
            self._alt_button_pressed = False
            self._ctrl_button = None
            self._ctrl_button_pressed = False
            # INITIALIZE MIXER, SESSIONS
            self._setup_session_control()  # Setup the session object
            self._setup_mixer_control() # Setup the mixer object
            self._setup_view_control() # Setup the clip/view toggler
            self.session.set_mixer(self.mixer) # Bind mixer to session
            self._setup_device_control() # Setup the device object
            self._setup_transport_control() # Setup transport object
            self.set_device_component(self.device) # Bind device to control surface
            # SET INITIAL SESSION/MIXER AND MODIFIERS BUTTONS
            self._set_modifiers_buttons()
            self.__update_matrix()
            # self.set_highlighting_session_component(self.session)

            for component in self.components:
                component.set_enabled(True)

        # self._suppress_session_highlight = True
        self._suppress_send_midi = True # Turn rebuild back on, once we're done setting up

    def _setup_session_control(self):
        self.show_message("#################### SESSION: ON ##############################")
        is_momentary = True
        # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX
        self.session = SessionComponent(num_tracks, num_scenes) #(num_tracks, num_scenes)
        self.session.set_offsets(0, 0)
        # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_down), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_up))
        # self.session.set_track_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_right), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_left)) # (right_button, left_button) This moves the "red box" selection set left & right. We'll use the mixer track selection instead...

    def _setup_mixer_control(self):
        is_momentary = True
        #CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON)
        self.mixer = SpecialMixerComponent(num_tracks, 0, False, False) # 4 tracks, 2 returns, no EQ, no filters
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)

    def _setup_view_control(self):
        # CREATES OBJECT SO WE CAN TOGGLE DEVICE/CLIP, LOCK DEVICE
        self.view = ViewTogglerComponent(num_tracks, self)

    def _setup_device_control(self):
        # CREATE DEVICE TO ASSIGN PARAMETERS BANK
        self.device = DeviceComponent()
        self.device.name = 'Device_Component'

    def _setup_transport_control(self):
        # CREATE TRANSPORT DEVICE
        self.transport = SpecialTransportComponent(self)


    def _on_selected_scene_changed(self):
        # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        if (track.devices is not None):
            self._ignore_track_selection = True
            device_to_select = track.devices[0]
            self.song().view.select_device(device_to_select)
            self._device_component.set_device(device_to_select)
        self._ignore_track_selection = False

    """                                 LED ON, OFF, FLASH WITH SESSION CLIPS                                             """

    # UPDATING BUTTONS FROM CLIP MATRIX IN NK AS SESSION MOVES
    def __update_matrix(self):
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                button = clip_slot._launch_button_value.subject
                value_to_send = -1
                if clip_slot._clip_slot != None:
                    if clip_slot.has_clip():
                        value_to_send = 127
                        if clip_slot._clip_slot.clip.is_triggered:
                            if clip_slot._clip_slot.clip.will_record_on_start:
                                value_to_send = clip_slot._triggered_to_record_value
                            else:
                                value_to_send = clip_slot._triggered_to_play_value
                        '''
                        elif clip_slot._clip_slot.clip.is_playing:
                            if clip_slot._clip_slot.clip.is_recording:
                                value_to_send = 127
                                #########      CLIPS PLAYING WILL FLASH
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                            else:
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                        '''
                    elif clip_slot._clip_slot.is_triggered:
                        if clip_slot._clip_slot.will_record_on_start:
                            value_to_send = clip_slot._triggered_to_record_value
                        else:
                            value_to_send = clip_slot._triggered_to_play_value
                    elif clip_slot._clip_slot.is_playing:
                        if clip_slot._clip_slot.is_recording:
                            value_to_send = clip_slot._recording_value
                        else:
                            value_to_send = clip_slot._started_value
                    elif clip_slot._clip_slot.controls_other_clips:
                        value_to_send = 0
                '''
                if value_to_send in range(128):
                    button.send_value(value_to_send)
                else:
                    button.turn_off()
                '''

    """                                 MODIFIERS, MODES, KEYS CONFIG                                             """

    #MODES ARE HERE: INITIALIZATIONS, DISCONNECTS BUTTONS, SLIDERS, ENCODERS
    def _clear_controls(self):
        # TURNING OFF ALL LEDS IN MATRIX
        self._turn_off_matrix()
        # SESSION
        resetsend_controls = []
        self.mixer.send_controls = []
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            scene.set_launch_button(None)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_launch_button(None)
        self.session.set_stop_track_clip_buttons(None)
        self.session.set_stop_all_clips_button(None)
            # REMOVE LISTENER TO SESSION MOVES
        if self.session.offset_has_listener(self.__update_matrix):
            self.session.remove_offset_listener(self.__update_matrix)
        self.session.set_stop_all_clips_button(None)
        # MIXER
        self.mixer._set_send_nav(None, None)
        for track_index in range(num_tracks):
            strip = self.mixer.channel_strip(track_index)
            strip.set_solo_button(None)
            strip.set_mute_button(None)
            strip.set_arm_button(None)
            resetsend_controls.append(None)
            strip.set_select_button(None)
            for i in range(12):
                self.mixer.send_controls.append(None)
            strip.set_send_controls(tuple(self.mixer.send_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        # VIEW
        self.view.set_device_nav_buttons(None, None)
        detailclip_view_controls = []
        for track_index in range(num_tracks):
            detailclip_view_controls.append(None)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE PARAMETERS
        device_param_controls = []
        self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(None)
        self.device.set_lock_button(None)
        # TRANSPORT
        self.transport.set_stop_button(None)
        self.transport.set_play_button(None)
        self.transport.set_record_button(None)
        self.transport._set_quant_toggle_button(None)
        self.transport.set_metronome_button(None)
        self.transport._set_tempo_buttons(None, None)

        self.log_message("Controls Cleared")

    def _set_normal_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.name = 'Mixer_ChannelStrip_' + str(index)
            self.mixer._update_send_index(self.mixer.sends_index)
            strip.set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_volumefader_cc[index]))
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        ### SET ARM, SOLO, MUTE
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip.set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_solo_cc[index]))
            strip.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_mute_cc[index]))
            strip.set_arm_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_arm_cc[index]))
            # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
            for i in range(12):
                self.mixer.send_controls.append(None)
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        self.mixer._update_send_index(self.mixer.sends_index)


    def _set_alt_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        stop_track_controls = []
        resetsend_controls = []
        button = None
        buttons = None
        # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_select_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_select_cc[index]))
            button = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, stop_track_cc[index])
            stop_track_controls.append(button)
            buttons = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_resetsend_cc[index])
            resetsend_controls.append(buttons)
        self.session.set_stop_track_clip_buttons(tuple(stop_track_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self.mixer._update_send_index(self.mixer.sends_index)


    def _set_ctrl_mode(self):
        # CLIP/DEVICE VIEW TOGGLE
        is_momentary = True
        self.view.set_device_nav_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_left_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_right_cc))
        button = None
        detailclip_view_controls = []
        for index in range(num_tracks):
            button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, detailclip_view_cc[index])
            detailclip_view_controls.append(button)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE ON/OFF, LOCK AND PARAMETERS
        device_param_controls = []
        onoff_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, onoff_device_cc)
        setlock_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, lock_device_cc)
        for index in range(num_tracks):
            knob = None
            knob = EncoderElement(MIDI_CC_TYPE, CHANNEL, device_param_cc[index], Live.MidiMap.MapMode.absolute)
            device_param_controls.append(knob)
        if None not in device_param_controls:
            self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(onoff_control)
        self.device.set_lock_button(setlock_control)
        # TRANSPORT
        # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
        # self.transport.set_play_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_play_cc))
        # self.transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_record_cc))
        self.transport._set_quant_toggle_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_quantization_cc))
        self.transport.set_metronome_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_metronome_cc))
        self.transport._set_tempo_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempodown_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempoup_cc))
        # SESSION STOP ALL CLIPS AND SCENE LAUNCH
        self.session.set_stop_all_clips_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_stopall_cc))
        for index in range(num_scenes):
            self.session.scene(index).set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_scenelaunch_cc[index]))

    def _set_modifiers_buttons(self):
        is_momentary = True
        self._shift_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, shift_mod)
        self._alt_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, alt_mod)
        self._ctrl_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, ctrl_mod)

        if (self._shift_button != None):
            self._shift_button.add_value_listener(self._shift_value)

        if (self._alt_button != None):
            self._alt_button.add_value_listener(self._alt_value)

        if (self._ctrl_button != None):
            self._ctrl_button.add_value_listener(self._ctrl_value)
        #INIT NORMAL MODE
        self._manage_modes(0)

    # MODIFIERS LISTENERS FUNCS ARE HERE
    def _shift_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._shift_button, ButtonElement)
        if value == 127:
            if self._shift_button_pressed is False:
                self._unpress_modes()
                self._shift_button_pressed = True
                self._manage_modes(0)

    def _alt_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._alt_button, ButtonElement)
        if value == 127:
            if self._alt_button_pressed is False:
                self._unpress_modes()
                self._alt_button_pressed = True
                self._manage_modes(2)

    def _ctrl_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._ctrl_button, ButtonElement)
        if value == 127:
            if self._ctrl_button_pressed is False:
                self._unpress_modes()
                self._ctrl_button_pressed = True
                self._manage_modes(3)

    def _manage_modes(self, mode_index):
        if mode_index == 0:
            self._clear_controls()
            self._set_normal_mode()
            # self._shift_button.turn_on()
            self._alt_button.turn_on()
            self._ctrl_button.turn_on()
            self.log_message("NORMAL ON")
        elif mode_index == 2:
            self._clear_controls()
            self._set_alt_mode()
            self._alt_button.turn_on()
            self._shift_button.turn_off()
            self._ctrl_button.turn_off()
            self.log_message("ALT ON")
        elif mode_index == 3:
            self._clear_controls()
            self._set_ctrl_mode()
            self._ctrl_button.turn_on()
            self._shift_button.turn_off()
            self._alt_button.turn_off()
            self.log_message("CTRL ON")

    def _unpress_modes(self):
        self._shift_button_pressed = False
        self._alt_button_pressed = False
        self._ctrl_button_pressed = False

    def _turn_off_matrix(self):
        for index in range(24):
            self._send_midi(tuple([176,index+16,0]))

    def disconnect(self):
        """clean things up on disconnect"""
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log closed =--------------") #Create entry in log file
        self._clear_controls()
        self.session = None
        self.mixer = None
        self.view = None
        self.device = None
        self.transport = None
        # MODES
        self._shift_button = None
        self._alt_button = None
        self._ctrl_button = None
        # SENDS
        self.send_button_up = None
        self.send_button_down = None
        self.send_controls = []
        self.send_reset = []

        self.set_device_component(None)
        ControlSurface.disconnect(self)
        return None
コード例 #8
0
class NanoKontrolShift(ControlSurface):
    __module__ = __name__
    __doc__ = " NanoKontrolShift controller script "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn off rebuild MIDI map until after we're done setting up
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= NanoKontrolShift log opened =--------------"
        )  # Writes message into Live's main log file. This is a ControlSurface method.
        with self.component_guard():
            # OBJECTS
            self.session = None  # session object
            self.mixer = None  # mixer object
            self.view = None  # clip/device view object
            self.device = None  # device object
            self.transport = None  # transport object
            # MODES
            self._shift_button = None
            self._shift_button_pressed = False
            self._alt_button = None
            self._alt_button_pressed = False
            self._ctrl_button = None
            self._ctrl_button_pressed = False
            # INITIALIZE MIXER, SESSIONS
            self._setup_session_control()  # Setup the session object
            self._setup_mixer_control()  # Setup the mixer object
            self._setup_view_control()  # Setup the clip/view toggler
            self.session.set_mixer(self.mixer)  # Bind mixer to session
            self._setup_device_control()  # Setup the device object
            self._setup_transport_control()  # Setup transport object
            self.set_device_component(
                self.device)  # Bind device to control surface
            # SET INITIAL SESSION/MIXER AND MODIFIERS BUTTONS
            self._set_modifiers_buttons()
            self.__update_matrix()
            self.set_highlighting_session_component(self.session)

            for component in self.components:
                component.set_enabled(True)

        # self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn rebuild back on, once we're done setting up

    def _setup_session_control(self):
        self.show_message(
            "#################### SESSION: ON ##############################")
        is_momentary = True
        # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX
        self.session = SessionComponent(num_tracks,
                                        num_scenes)  # (num_tracks, num_scenes)
        self.session.set_offsets(0, 0)
        # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_down), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_up))
        self.session.set_track_bank_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_right),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_left)
        )  # (right_button, left_button) This moves the "red box" selection set left & right. We'll use the mixer track selection instead...

    def _setup_mixer_control(self):
        is_momentary = True
        # CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON)
        self.mixer = SpecialMixerComponent(
            num_tracks, 0, False,
            False)  # 4 tracks, 2 returns, no EQ, no filters
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(
            0)  # Sets start point for mixer strip (offset from left)

    def _setup_view_control(self):
        # CREATES OBJECT SO WE CAN TOGGLE DEVICE/CLIP, LOCK DEVICE
        self.view = ViewTogglerComponent(num_tracks, self)

    def _setup_device_control(self):
        # CREATE DEVICE TO ASSIGN PARAMETERS BANK
        self.device = DeviceComponent()
        self.device.name = 'Device_Component'

    def _setup_transport_control(self):
        # CREATE TRANSPORT DEVICE
        self.transport = SpecialTransportComponent(self)

    def _on_selected_scene_changed(self):
        # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        if (track.devices is not None):
            self._ignore_track_selection = True
            device_to_select = track.devices[0]
            self.song().view.select_device(device_to_select)
            self._device_component.set_device(device_to_select)
        self._ignore_track_selection = False

    """                                 LED ON, OFF, FLASH WITH SESSION CLIPS                                             """

    # UPDATING BUTTONS FROM CLIP MATRIX IN NK AS SESSION MOVES
    def __update_matrix(self):
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                button = clip_slot._launch_button_value.subject
                value_to_send = -1
                if clip_slot._clip_slot != None:
                    if clip_slot.has_clip():
                        value_to_send = 127
                        if clip_slot._clip_slot.clip.is_triggered:
                            if clip_slot._clip_slot.clip.will_record_on_start:
                                value_to_send = clip_slot._triggered_to_record_value
                            else:
                                value_to_send = clip_slot._triggered_to_play_value
                        '''
                        elif clip_slot._clip_slot.clip.is_playing:
                            if clip_slot._clip_slot.clip.is_recording:
                                value_to_send = 127
                                #########      CLIPS PLAYING WILL FLASH
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                            else:
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                        '''
                    elif clip_slot._clip_slot.is_triggered:
                        if clip_slot._clip_slot.will_record_on_start:
                            value_to_send = clip_slot._triggered_to_record_value
                        else:
                            value_to_send = clip_slot._triggered_to_play_value
                    elif clip_slot._clip_slot.is_playing:
                        if clip_slot._clip_slot.is_recording:
                            value_to_send = clip_slot._recording_value
                        else:
                            value_to_send = clip_slot._started_value
                    elif clip_slot._clip_slot.controls_other_clips:
                        value_to_send = 0
                '''
                if value_to_send in range(128):
                    button.send_value(value_to_send)
                else:
                    button.turn_off()
                '''

    """                                 MODIFIERS, MODES, KEYS CONFIG                                             """

    # MODES ARE HERE: INITIALIZATIONS, DISCONNECTS BUTTONS, SLIDERS, ENCODERS
    def _clear_controls(self):
        # TURNING OFF ALL LEDS IN MATRIX
        self._turn_off_matrix()
        # SESSION
        resetsend_controls = []
        self.mixer.send_controls = []
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            scene.set_launch_button(None)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_launch_button(None)
        self.session.set_stop_track_clip_buttons(None)
        self.session.set_stop_all_clips_button(None)
        # REMOVE LISTENER TO SESSION MOVES
        if self.session.offset_has_listener(self.__update_matrix):
            self.session.remove_offset_listener(self.__update_matrix)
        self.session.set_stop_all_clips_button(None)
        # MIXER
        self.mixer._set_send_nav(None, None)
        for track_index in range(num_tracks):
            strip = self.mixer.channel_strip(track_index)
            strip.set_solo_button(None)
            strip.set_mute_button(None)
            strip.set_arm_button(None)
            resetsend_controls.append(None)
            strip.set_select_button(None)
            for i in range(12):
                self.mixer.send_controls.append(None)
            strip.set_send_controls(tuple(self.mixer.send_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        # VIEW
        self.view.set_device_nav_buttons(None, None)
        detailclip_view_controls = []
        for track_index in range(num_tracks):
            detailclip_view_controls.append(None)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE PARAMETERS
        device_param_controls = []
        self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(None)
        self.device.set_lock_button(None)
        # TRANSPORT
        self.transport.set_stop_button(None)
        self.transport.set_play_button(None)
        self.transport.set_record_button(None)
        self.transport._set_quant_toggle_button(None)
        self.transport.set_metronome_button(None)
        self.transport._set_tempo_buttons(None, None)

        self.log_message("Controls Cleared")

    def _set_normal_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.name = 'Mixer_ChannelStrip_' + str(index)
            self.mixer._update_send_index(self.mixer.sends_index)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, CHANNEL,
                              mixer_volumefader_cc[index]))
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(
                MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index],
                Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        ### SET ARM, SOLO, MUTE
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip.set_solo_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_solo_cc[index]))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_mute_cc[index]))
            strip.set_arm_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_arm_cc[index]))
            # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
            for i in range(12):
                self.mixer.send_controls.append(None)
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(
                MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index],
                Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        self.mixer._update_send_index(self.mixer.sends_index)

    def _set_alt_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        stop_track_controls = []
        resetsend_controls = []
        button = None
        buttons = None
        # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_select_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_select_cc[index]))
            button = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                   stop_track_cc[index])
            stop_track_controls.append(button)
            buttons = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                    track_resetsend_cc[index])
            resetsend_controls.append(buttons)
        self.session.set_stop_track_clip_buttons(tuple(stop_track_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self.mixer._update_send_index(self.mixer.sends_index)

    def _set_ctrl_mode(self):
        # CLIP/DEVICE VIEW TOGGLE
        is_momentary = True
        self.view.set_device_nav_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_left_cc),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          device_right_cc))
        button = None
        detailclip_view_controls = []
        for index in range(num_tracks):
            button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL,
                                   detailclip_view_cc[index])
            detailclip_view_controls.append(button)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE ON/OFF, LOCK AND PARAMETERS
        device_param_controls = []
        onoff_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                      onoff_device_cc)
        setlock_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                        lock_device_cc)
        for index in range(num_tracks):
            knob = None
            knob = EncoderElement(MIDI_CC_TYPE, CHANNEL,
                                  device_param_cc[index],
                                  Live.MidiMap.MapMode.absolute)
            device_param_controls.append(knob)
        if None not in device_param_controls:
            self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(onoff_control)
        self.device.set_lock_button(setlock_control)
        # TRANSPORT
        # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
        # self.transport.set_play_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_play_cc))
        # self.transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_record_cc))
        self.transport._set_quant_toggle_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_quantization_cc))
        self.transport.set_metronome_button(
            ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_metronome_cc))
        self.transport._set_tempo_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_tempodown_cc),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_tempoup_cc))
        # SESSION STOP ALL CLIPS AND SCENE LAUNCH
        self.session.set_stop_all_clips_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          session_stopall_cc))
        for index in range(num_scenes):
            self.session.scene(index).set_launch_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              session_scenelaunch_cc[index]))

    def _set_modifiers_buttons(self):
        is_momentary = True
        self._shift_button = ButtonElement(not is_momentary, MIDI_CC_TYPE,
                                           CHANNEL, shift_mod)
        self._alt_button = ButtonElement(not is_momentary, MIDI_CC_TYPE,
                                         CHANNEL, alt_mod)
        self._ctrl_button = ButtonElement(not is_momentary, MIDI_CC_TYPE,
                                          CHANNEL, ctrl_mod)

        if (self._shift_button != None):
            self._shift_button.add_value_listener(self._shift_value)

        if (self._alt_button != None):
            self._alt_button.add_value_listener(self._alt_value)

        if (self._ctrl_button != None):
            self._ctrl_button.add_value_listener(self._ctrl_value)
        # INIT NORMAL MODE
        self._manage_modes(0)

    # MODIFIERS LISTENERS FUNCS ARE HERE
    def _shift_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._shift_button, ButtonElement)
        if value == 127:
            if self._shift_button_pressed is False:
                self._unpress_modes()
                self._shift_button_pressed = True
                self._manage_modes(0)

    def _alt_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._alt_button, ButtonElement)
        if value == 127:
            if self._alt_button_pressed is False:
                self._unpress_modes()
                self._alt_button_pressed = True
                self._manage_modes(2)

    def _ctrl_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._ctrl_button, ButtonElement)
        if value == 127:
            if self._ctrl_button_pressed is False:
                self._unpress_modes()
                self._ctrl_button_pressed = True
                self._manage_modes(3)

    def _manage_modes(self, mode_index):
        if mode_index == 0:
            self._clear_controls()
            self._set_normal_mode()
            # self._shift_button.turn_on()
            self._alt_button.turn_on()
            self._ctrl_button.turn_on()
            self.log_message("NORMAL ON")
        elif mode_index == 2:
            self._clear_controls()
            self._set_alt_mode()
            self._alt_button.turn_on()
            self._shift_button.turn_off()
            self._ctrl_button.turn_off()
            self.log_message("ALT ON")
        elif mode_index == 3:
            self._clear_controls()
            self._set_ctrl_mode()
            self._ctrl_button.turn_on()
            self._shift_button.turn_off()
            self._alt_button.turn_off()
            self.log_message("CTRL ON")

    def _unpress_modes(self):
        self._shift_button_pressed = False
        self._alt_button_pressed = False
        self._ctrl_button_pressed = False

    def _turn_off_matrix(self):
        for index in range(24):
            self._send_midi(tuple([176, index + 16, 0]))

    def disconnect(self):
        """clean things up on disconnect"""
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= NanoKontrolShift log closed =--------------"
        )  # Create entry in log file
        self._clear_controls()
        self.session = None
        self.mixer = None
        self.view = None
        self.device = None
        self.transport = None
        # MODES
        self._shift_button = None
        self._alt_button = None
        self._ctrl_button = None
        # SENDS
        self.send_button_up = None
        self.send_button_down = None
        self.send_controls = []
        self.send_reset = []

        self.set_device_component(None)
        ControlSurface.disconnect(self)
        return None