Beispiel #1
0
	def _setup_mixer_control(self):
		is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant
		num_tracks = 7 # Here we define the mixer width in tracks (a mixer has only one dimension)
		global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
		mixer = MixerComponent(num_tracks, 0) #(num_tracks, num_returns, with_eqs, with_filters)
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		"""set up the mixer buttons"""		  
		self.song().view.selected_track = mixer.channel_strip(0)._track
		mixer.selected_strip().set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 64))
		#mixer.selected_strip().set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 44))
		mixer.selected_strip().set_arm_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 72))
		track_select_notes = [65, 73, 66, 74, 67, 75, 68, 76] #more note numbers need to be added if num_scenes is increased
		slider_select_notes = [23, 22, 15, 14, 5, 7, 6, 4]
		pan_select_notes = [21, 20, 13, 12, 3, 1, 0, 2]
		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 4)
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 76)
		prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 26, Live.MidiMap.MapMode.absolute)
		crossfader = SliderElement(MIDI_CC_TYPE, 0, 24)
		for index in range(num_tracks):
			mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, track_select_notes[index]))
			mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, slider_select_notes[index]))
			mixer.channel_strip(index).set_pan_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, pan_select_notes[index], Live.MidiMap.MapMode.absolute))
		crossfader.name = 'Crossfader'
		master_volume_control.name = 'Master_Volume_Control'
		master_select_button.name = 'Master_Select_Button'
		prehear_control.name = 'Prehear_Volume_Control'
		mixer.set_crossfader_control(crossfader)
		mixer.set_prehear_volume_control(prehear_control)
		mixer.master_strip().set_volume_control(master_volume_control)
		mixer.master_strip().set_select_button(master_select_button)
Beispiel #2
0
    def _setup_mixer_control(self):
        is_momentary = True

        """ Instantiate a Mixer Component """
        global mixer  # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
        mixer = MixerComponent(mixer_num_tracks, 2, with_eqs=True, with_filters=True)  # (num_tracks, num_returns, with_eqs, with_filters)
        mixer.set_track_offset(0)  # Sets start point for mixer strip (offset from left)
        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

        """ Buttons and Sliders association """
        # Master channel
        mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, midi_channel, midi_mixer_volume_master))  # sets the continuous controller for volume

        # Other channels, same size as mixer_num_tracks
        # Set volume control, solo and mute buttons
        for index in range(mixer_num_tracks):  # launch_button assignment must match number of scenes
            mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, midi_channel, midi_mixer_volume_channels[index]))  # sets the continuous controller for volume
            mixer.channel_strip(index).set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_mixer_solo_channels[index]))  # sets the solo button
            mixer.channel_strip(index).set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_mixer_mute_channels[index]))  # sets the mute ("activate") button

        """ Buttons to select track """
        button_next_track = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_track_select_next)
        button_previous_track = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_track_select_previous)
        mixer.set_select_buttons(button_next_track, button_previous_track)

        """ Listeners """
        # When selected track if changed
        self.song().view.add_selected_track_listener(self.on_track_selected)
Beispiel #3
0
	def _setup_mixer_control(self):
		is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant
		num_tracks = 7 # Here we define the mixer width in tracks (a mixer has only one dimension)
		global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
		mixer = MixerComponent(num_tracks, 0) #(num_tracks, num_returns, with_eqs, with_filters)
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		"""set up the mixer buttons"""		  
		self.song().view.selected_track = mixer.channel_strip(0)._track
		mixer.selected_strip().set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 64))
		#mixer.selected_strip().set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 44))
		mixer.selected_strip().set_arm_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 72))
		track_select_notes = [65, 73, 66, 74, 67, 75, 68, 76] #more note numbers need to be added if num_scenes is increased
		slider_select_notes = [3, 2, 1, 0, 5, 4, 6, 7]
		#pan_select_notes = [21, 20, 13, 12, 3, 1, 0, 2]
		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 7)
		#master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 76)
		#prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 26, Live.MidiMap.MapMode.absolute)
		#crossfader = SliderElement(MIDI_CC_TYPE, 0, 24)
		for index in range(num_tracks):
			#mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, track_select_notes[index]))
			mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, slider_select_notes[index]))
			#mixer.channel_strip(index).set_pan_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, pan_select_notes[index], Live.MidiMap.MapMode.absolute))
		#crossfader.name = 'Crossfader'
		master_volume_control.name = 'Master_Volume_Control'
		#master_select_button.name = 'Master_Select_Button'
		#prehear_control.name = 'Prehear_Volume_Control'
		#mixer.set_crossfader_control(crossfader)
		#mixer.set_prehear_volume_control(prehear_control)
		mixer.master_strip().set_volume_control(master_volume_control)
    def _MG_setup(self):
        mixer = MixerComponent(8)
        mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        transport = TransportComponent()
        mixer.set_track_offset(0)

        for i in xrange(len(KNOBS)):  #set the functions of the knobs
            volume_knob = SliderElement(MIDI_CC_TYPE, 0, KNOBS[i])
            pan_knob = SliderElement(MIDI_CC_TYPE, 1, KNOBS[i])

            send_a = SliderElement(MIDI_CC_TYPE, 2, KNOBS[i])
            send_b = SliderElement(MIDI_CC_TYPE, 3, KNOBS[i])
            send_c = SliderElement(MIDI_CC_TYPE, 4, KNOBS[i])
            send_d = SliderElement(MIDI_CC_TYPE, 5, KNOBS[i])
            send_e = SliderElement(MIDI_CC_TYPE, 6, KNOBS[i])
            send_f = SliderElement(MIDI_CC_TYPE, 7, KNOBS[i])

            mixer.channel_strip(i).set_volume_control(volume_knob)
            mixer.channel_strip(i).set_pan_control(pan_knob)
            mixer.channel_strip(i).set_send_controls(
                [send_a, send_b, send_c, send_d, send_e, send_f])

        # scenes are locked to channel 14
        transport.set_overdub_button(
            ButtonElement(False, MIDI_CC_TYPE, 0, SCENES[0]))
        transport.set_stop_button(
            ButtonElement(False, MIDI_CC_TYPE, 0, SCENES[1]))
 def _setup_mixer_control(self):
     is_momentary = True
     num_tracks = 7  #A mixer is one-dimensional; here we define the width in tracks - seven columns, which we will map to seven "white" notes
     """Here we set up the global mixer"""  #Note that it is possible to have more than one mixer...
     global mixer  #We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
     mixer = MixerComponent(
         num_tracks, 2, with_eqs=True, with_filters=True
     )  #(num_tracks, num_returns, with_eqs, with_filters)
     mixer.set_track_offset(
         0)  #Sets start point for mixer strip (offset from left)
     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
     """set up the mixer buttons"""
     mixer.set_select_buttons(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 56),
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       54))  #left, right track select
     mixer.master_strip().set_select_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       94))  #jump to the master track
     mixer.selected_strip().set_mute_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       42))  #sets the mute ("activate") button
     mixer.selected_strip().set_solo_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       44))  #sets the solo button
     mixer.selected_strip().set_arm_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       46))  #sets the record arm button
     """set up the mixer sliders"""
     mixer.selected_strip().set_volume_control(
         SliderElement(MIDI_CC_TYPE, CHANNEL,
                       14))  #sets the continuous controller for volume
     """note that we have split the mixer functions across two scripts, in order to have two session highlight boxes (one red, one yellow), so there are a few things which we are not doing here..."""
Beispiel #6
0
    def _create_mixer_control(self):
        is_momentary = True
        num_tracks = 7
        """Here we set up the global mixer"""
        global mixer
        mixer = MixerComponent(name='Mixer',
                               num_tracks=num_tracks,
                               is_enabled=False,
                               num_returns=2)
        mixer.set_enabled(True)
        mixer.set_track_offset(0)
        self.song().view.selected_track = mixer.channel_strip(0)._track
        mixer.channel_strip(0)
        """set up the mixer buttons"""
        mixer.set_select_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 56),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 54))
        mixer.master_strip().set_select_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 94))
        mixer.selected_strip().set_mute_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 42))
        mixer.selected_strip().set_solo_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 44))
        mixer.selected_strip().set_arm_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 46))
        """set up the mixer sliders"""
        mixer.selected_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, CHANNEL, 14))
        """note that we have split the mixer functions across two scripts, in order to have two session highlight 
        boxes (one red, one yellow), so there are a few things which we are not doing here... """

        self.log_message("Captain's log stardate 2")
Beispiel #7
0
 def setup_mixer(self):
     global mixer
     mixer = MixerComponent(2, 2)
     mixer.set_track_offset(0)
     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
     send_a = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_A, mode_absolute)
     send_b = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_B, mode_absolute)
     send_c = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_C, mode_absolute)
     send_d = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_D, mode_absolute)
     pan = EncoderElement(MIDI_CC_TYPE, CHANNEL, PAN, mode_absolute)
     mixer.selected_strip().set_send_controls(
         [send_a, send_b, send_c, send_d])
     mixer.selected_strip().set_pan_control(pan)
Beispiel #8
0
	def _setup_mixer_control(self):
		is_momentary = True # We use non-latching buttons (keys) throughout, so we'll set this as a constant
		num_tracks = 4 # Here we define the mixer width in tracks (a mixer has only one dimension)
		global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
		mixer = MixerComponent(num_tracks, 2, with_eqs=True, with_filters=False) #(num_tracks, num_returns, with_eqs, with_filters)
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		"""set up the mixer buttons"""		  
		self.song().view.selected_track = mixer.channel_strip(0)._track
		#mute_notes = [1,5,9,13]
		#solo_notes = [2,6,10,14]
		#arm_notes = [3,7,11,15]
		track_select_notes = [38,39,40,41]#more note numbers need to be added if num_scenes is increased
		send_ccs = [2,6,10,14,1,5,9,13]
		pan_ccs = [3,7,11,15]
		slider_ccs = [4,8,12,16]
		for index in range(num_tracks):
			mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, track_select_notes[index]))
			mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHAN, slider_ccs[index]))
			mixer.channel_strip(index).set_pan_control(EncoderElement(MIDI_CC_TYPE, CHAN, pan_ccs[index], Live.MidiMap.MapMode.absolute))
			#put send A and send B controllers into an array, which is then "tupled" for set_send_controls:
			send_controlers = [EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index], Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index+num_tracks], Live.MidiMap.MapMode.absolute)]
			mixer.channel_strip(index).set_send_controls(tuple(send_controlers))
		
		crossfader = SliderElement(MIDI_CC_TYPE, CHAN, 28)
		master_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 32)
		returna_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 19)
		returna_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 20)
		returnb_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 23)
		returnb_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 24)
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN, 31)
		prehear_control = EncoderElement(MIDI_CC_TYPE, CHAN, 30, Live.MidiMap.MapMode.absolute)
		crossfader.name = 'Crossfader'
		master_volume_control.name = 'Master_Volume_Control'
		returna_pan_control.name = 'ReturnA_Pan_Control'
		returna_volume_control.name = 'ReturnA_Volume_Control'
		returnb_pan_control.name = 'ReturnB_Pan_Control'
		returnb_volume_control.name = 'ReturnB_Volume_Control'
		master_select_button.name = 'Master_Select_Button'
		prehear_control.name = 'Prehear_Volume_Control'
		mixer.set_crossfader_control(crossfader)
		mixer.master_strip().set_volume_control(master_volume_control)
		mixer.master_strip().set_select_button(master_select_button)
		mixer.set_prehear_volume_control(prehear_control)
		mixer.return_strip(0).set_pan_control(returna_pan_control)
		mixer.return_strip(0).set_volume_control(returna_volume_control)
		mixer.return_strip(1).set_pan_control(returnb_pan_control)
		mixer.return_strip(1).set_volume_control(returnb_volume_control)
Beispiel #9
0
	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (COLS)
		global mixer
		mixer = MixerComponent(COLS, 0, True, True)
		mixer.name = 'Mixer'
		self._mixer = mixer
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(COLS):
			#use the bottom row of encoders for volume, so add 24 to offset the index
			mixer.channel_strip(index).set_volume_control(self._dial[index+24])
		for index in range(COLS):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.track_filter(index).name = 'Mixer_Filter_' + str(index)  #added by a
			mixer.channel_strip(index)._invert_mute_feedback = True
			#mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]))
		self.song().view.selected_track = mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
Beispiel #10
0
    def _setup_mixer_control(self):
        num_tracks = GRIDSIZE[0] # Here we define the mixer width in tracks (a mixer has only one dimension)
        global mixer # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
        mixer = MixerComponent(num_tracks) #(num_tracks, num_returns, with_eqs, with_filters)
        mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
        """set up the mixer buttons"""
        self.song().view.selected_track = mixer.channel_strip(0)._track
        master = mixer.master_strip()
        master.set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_USER, MASTER_VOLUME))
        mixer.set_prehear_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_USER, PREHEAR))

        for index in xrange(GRIDSIZE[0]):
            mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, MIX_FADERS[index]))
            # mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL_INST, MIX_FADERS[index]))
            mixer.channel_strip(index).set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, PAN_CONTROLS[index]))
            mixer.channel_strip(index).set_arm_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, ARM_BUTTONS[index])) #sets the record arm button
            mixer.channel_strip(index).set_solo_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, SOLO_BUTTONS[index]))
            mixer.channel_strip(index).set_mute_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, MUTE_BUTTONS[index]))
            mixer.channel_strip(index).set_select_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL_INST, TRACK_SELECTS[index]))
            mixer.channel_strip(index).set_send_controls([SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][0]),
                                                              SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][1]),
                                                              SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][2]),
                                                              SliderElement(MIDI_CC_TYPE, CHANNEL_MIXER, SEND_CONTROLS[index][3])])




        """TRANSPORT CONTROLS"""
        stop_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL_MIXER, STOP_BUTTON)
        play_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL_MIXER, PLAY_BUTTON)
        record_button = ButtonElement(False,MIDI_CC_TYPE,CHANNEL_MIXER,RECORD_BUTTON)
        overdub_button = ButtonElement(False,MIDI_CC_TYPE,CHANNEL_MIXER,OVERDUB_BUTTON)
        transport = TransportComponent()
        transport.TEMPO_TOP = 188
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_overdub_button(overdub_button)
        transport.set_record_button(record_button)
        transport.set_seek_buttons(ButtonElement(False,MIDI_CC_TYPE,0,SEEK_LEFT),ButtonElement(False,MIDI_CC_TYPE,0,SEEK_RIGHT))
        transport.set_tempo_control(SliderElement(MIDI_CC_TYPE, CHANNEL_USER, TEMPO))
        transport.set_metronome_button(ButtonElement(False,MIDI_CC_TYPE,CHANNEL_USER, METRONOME))
        transport.set_tap_tempo_button(ButtonElement(False,MIDI_CC_TYPE,CHANNEL_USER,TAP_TEMPO))
Beispiel #11
0
    def _init_mixer_component(self):
        is_momentary = True
        global mixer
        mixer = MixerComponent(8)
        mixer.name = 'Mixer'
        mixer.set_track_offset(0)
        self.song().view.selected_track = mixer.channel_strip(0)._track

        for track in range(8):
            #self.log_message("Adding track " + str(track))
            strip = mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            volume_control = SliderElement(MIDI_CC_TYPE, track, VOL_CC)
            snd_A_control = SliderElement(MIDI_CC_TYPE, track, SND_A_CC)
            snd_B_control = SliderElement(MIDI_CC_TYPE, track, SND_B_CC)
            pan_control = SliderElement(MIDI_CC_TYPE, track, PAN_CC)

            arm_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, track, ARM_CC)
            select_button = ButtonElement(is_momentary, MIDI_CC_TYPE, track, SEL_CC)
            mute_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, track, MUTE_CC)


            volume_control.name = str(track) + '_Volume_Control'
            snd_A_control.name = str(track) + '_Send_A_Control'
            snd_B_control.name = str(track) + '_Send_B_Control'
            pan_control.name = str(track) + '_Pan_Control'

            arm_button.name = str(track) + '_arm_Button'
            select_button.name = str(track) + '_Select_Button'
            mute_button.name = str(track) + '_Mute_Button'


            strip.set_volume_control(volume_control)
            strip.set_send_controls([snd_A_control, snd_B_control])
            strip.set_pan_control(pan_control)

            strip.set_arm_button(arm_button)
            strip.set_select_button(select_button)
            strip.set_mute_button(mute_button)

        return mixer
Beispiel #12
0
 def _setup_mixer_control(self):
     is_momentary = True  # We use non-latching buttons (keys) throughout, so we'll set this as a constant
     num_tracks = 8  # Here we define the mixer width in tracks (a mixer has only one dimension)
     global mixer  # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
     mixer = MixerComponent(
         num_tracks, 0, with_eqs=False, with_filters=False
     )  #(num_tracks, num_returns, with_eqs, with_filters)
     mixer.set_track_offset(
         0)  #Sets start point for mixer strip (offset from left)
     """set up the mixer buttons"""
     self.song().view.selected_track = mixer.channel_strip(0)._track
     master_volume_control = SliderElement(MIDI_CC_TYPE, CHANNEL, 9)
     for index in range(num_tracks):
         mixer.channel_strip(index).set_mute_button(
             ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                           (index + 19)))
         mixer.channel_strip(index).set_volume_control(
             SliderElement(MIDI_CC_TYPE, CHANNEL, (index + 1)))
         #mixer.channel_strip(index).set_pan_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, (index+10), Live.MidiMap.MapMode.absolute))
     master_volume_control.name = 'Master_Volume_Control'
     mixer.master_strip().set_volume_control(master_volume_control)
Beispiel #13
0
    def _setup_mixer_control(self):
        num_tracks = 7
        global mixer
        mixer = MixerComponent(num_tracks)
        mixer.set_track_offset(0)
        self.song().view.selected_track = mixer.channel_strip(0)._track

        master_volume_fader = SliderElement(MIDI_CC_TYPE, CHANNEL,
                                            MASTER_FADER)
        mixer.master_strip().set_volume_control(master_volume_fader)

        for index in range(num_tracks):
            mixer.channel_strip(index).set_volume_control(
                SliderElement(MIDI_CC_TYPE, CHANNEL, FADERS[index]))
            mixer.channel_strip(index).set_mute_button(
                ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL,
                              TRACK_MUTE_BUTTONS[index]))
            mixer.channel_strip(index).set_select_button(
                ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL,
                              TRACK_SELECT_BUTTONS[index]))
            #mixer.channel_strip(index).set_send_controls(SliderElement(MIDI_CC_TYPE, CHANNEL, SEND_KNOBS[index]))
            '''for index in range(6):
Beispiel #14
0
    def _setup_mixer_control(self):
        num_tracks = GRIDSIZE[
            1]  # Here we define the mixer width in tracks (a mixer has only one dimension)
        global mixer  # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
        mixer = MixerComponent(
            num_tracks)  #(num_tracks, num_returns, with_eqs, with_filters)
        mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        """set up the mixer buttons"""
        self.song().view.selected_track = mixer.channel_strip(0)._track
        #master_volume_control = SliderElement(MIDI_CC_TYPE, 1, 17)
        for index in range(GRIDSIZE[1]):
            mixer.channel_strip(index).set_volume_control(
                SliderElement(MIDI_CC_TYPE, CHANNEL, MIX_FADERS[index]))

            mixer.channel_strip(index).set_arm_button(
                ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL,
                              ARM_BUTTONS[index]))  #sets the record arm button
            mixer.channel_strip(index).set_solo_button(
                ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL,
                              SOLO_BUTTONS[index]))
            mixer.channel_strip(index).set_mute_button(
                ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL,
                              MUTE_BUTTONS[index]))
            mixer.channel_strip(index).set_select_button(
                ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL,
                              TRACK_SELECTS[index]))
        """TRANSPORT CONTROLS"""
        stop_button = ButtonElement(False, MIDI_CC_TYPE, 0, STOP_BUTTON)
        play_button = ButtonElement(False, MIDI_CC_TYPE, 0, PLAY_BUTTON)
        record_button = ButtonElement(False, MIDI_CC_TYPE, 0, RECORD_BUTTON)
        transport = TransportComponent()
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_overdub_button(record_button)
        transport.set_overdub_button(record_button)
        transport.set_seek_buttons(
            ButtonElement(False, MIDI_CC_TYPE, 0, SEEK_LEFT),
            ButtonElement(False, MIDI_CC_TYPE, 0, SEEK_RIGHT))
Beispiel #15
0
 def _setup_mixer_control(self):
     is_momentary = True
     self._num_tracks = (COLS)
     global mixer
     mixer = MixerComponent(COLS, 0, True, True)
     mixer.name = 'Mixer'
     self._mixer = mixer
     mixer.set_track_offset(
         0)  #Sets start point for mixer strip (offset from left)
     for index in range(COLS):
         #use the bottom row of encoders for volume, so add 24 to offset the index
         mixer.channel_strip(index).set_volume_control(self._dial[index +
                                                                  24])
     for index in range(COLS):
         mixer.channel_strip(
             index).name = 'Mixer_ChannelStrip_' + str(index)
         mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
         mixer.track_filter(index).name = 'Mixer_Filter_' + str(
             index)  #added by a
         mixer.channel_strip(index)._invert_mute_feedback = True
         #mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]))
     self.song().view.selected_track = mixer.channel_strip(
         0
     )._track  #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
Beispiel #16
0
class Baseline_script_by_modern_dj_ch2(ControlSurface):
    __module__ = __name__ # Edie Brickell song
    __doc__ = " modern.dj baseline MRS controller script  for live 9 http://modern.dj/app" #shamless self promotion
    
    # Getting issues on Channel switching via Livid Base.  The log is clean - but is the issue fixed? please email em [email protected] if you know or can help.
    def handle_sysex(self, midi_bytes):
        return None
    
    # bootstrap method
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance) # bootstrap into the API/_Framework
        ''' live 9 onlye
        with self.component_guard(): # live9 / new requirement
        '''
        self.log_message(" - ")
        self.log_message("**************************************************")
        self.version_information() # log information from the readme.py file
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "..::|| Modern.DJ LIVE8 ch2 baseline MRS opened ||::..")
        self._suppress_session_highlight = True # stop the "Red box" for a second
        self._suppress_send_midi = True # sounds like a good idea
        #self.set_suppress_rebuild_requests(True) #deprecated for 9 !! Legacy note keep here for repository ref, remove later!!
        # Look for matrix option
        if enable_matrix == 1: # yes, matrix aka "red box"
            self.log_message("[matrix enabled]")
            self.volume_offset = volume_offset # see param info / offset for volume
            self.box_width = box_width # track width 
            self.box_height = box_height # track height aka scene count
            self.session = None # local session object
            self._setup_session_control() # init the session via subclass pattern
            # Turn on volume is needed. Nested as Volume has session / matrix dependencies
            if enable_volume_control == 1:
                self.log_message("[volume control enabled]")
                self.volume_control = None # param container inside the obj
                self.mixer = None # holds the obj mixer object
                # should volume be static or not?
                if enable_static_volume == 1 :
                    self.track_volume_static = track_volume_static # localize tuple of CCs for volume control
                    self.mixer_custom = None
                    self.custom_offset_mixer() 
                else :
                    self .track_volume = track_volume # localize tuple of CCs for volume control
                    self._setup_mixer_control()
                self.session.set_mixer(self.mixer) # for the red box to move left/right w/session
            else:
                self.log_message("[volume control not enabled")
        else:
            self.log_message("[matrix not enabled]")        
        # Check for tempo control option
        if enable_tempo_control == 1: 
            self.log_message("[tempo enabled]")
            self._setup_transport_control()
        else:
            self.log_message("[tempo not enabled]")
            # turn on "red box" again --  drops mic, walks off stage
            ''' live 9 only
            self._suppress_session_highlight = False
            '''

    ## tempo via  @bitNomad  / http://github.com/bitnomad 
    # @todo : Move this off and pass the object along newer subclassing patterns
    def _setup_transport_control(self):
        transport = CustomTransportComponent() #Instantiate a Transport Component
        transport.set_tempo_bumpers(transport.button(tempo_button_up), transport.button(tempo_button_down)) # yells "DO IT!!" at tempo code

    # pass session component through a bunch of subclassing
    def _setup_session_control(self):
        self.session = CustomSessionComponent(self.box_width, self.box_height, self) # subclass from _Framework
        is_momentary = True # what exactly does this do in the _Framework?
        if up_button_note_number >= 0 and down_button_note_number >= 0: # opt in enable UP/DOWN nav
            up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, up_button_note_number) 
            up_button.name = 'Bank_Select_Up_Button' # sure, why not
            down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, down_button_note_number)
            down_button.name = 'Bank_Select_Down_Button' #sure, why not
            self.session.set_scene_bank_buttons(down_button, up_button)
        if right_button_note_number >= 0 and left_button_note_number >= 0: # opt in enable LEFT/RIGHT nav
            right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, right_button_note_number)
            right_button.name = 'Bank_Select_Right_Button' #sure, why not
            left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, left_button_note_number)
            left_button.name = 'Bank_Select_Left_Button' #sure, why not
            self.session.set_track_bank_buttons(right_button, left_button)
        self.session.name = 'Session_Control' #sure, why not
        matrix = ButtonMatrixElement() # @todo subclass this via established new patterns
        matrix.name = 'Button_Matrix' #sure, why not
        # I loop a little different. The goal is readbility, flexibility, and the web app...incase you did not notice yet
        if len(scene_launch_notes) > 0 and len(scene_launch_notes) == self.box_height: # logic check have launch notes and scene = box height
            for index in range(self.box_height): 
                self.session.scene(index).set_launch_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, scene_launch_notes[index])) 
        else :
            self.log_message("..::|| Scene launch not in use or error on case of use. Modern.DJ ||::..")
        if len(stop_track_buttons) >0 and len(stop_track_buttons) == self.box_width: #logic check have track stop assignments and 
            track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, stop_track_buttons[index]) for index in range(len(stop_track_buttons))]
            for index in range(len(track_stop_buttons)):
                track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button' # sure, why not
            self.session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        else :
            self.log_message("..::|| Stop notes not in use or error found Modern.DJ ||::..")
        # Check for stop all clips option
        if stop_all_clips >=0 : 
            self.session.set_stop_all_clips_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, stop_all_clips))
        # creating the matrix of buttons from the launch_button_list (tuple)
        launch_button_list_len = len(launch_button_list) # var used multiple times. This is a performance modification
        if (self.box_height*self.box_width) ==  launch_button_list_len : # check box size against number of button vars sent
            launch_ctr = launch_button_list_len -1 # decrement for zero offset in list/tuple
            launch_button_list.reverse() #reverse list from human readable for decrement use (performance tweak)
            ## check for use of RGB
            if use_velocity_for_RGB != 1: # if not enabled use these defaults
                self.log_message("..::|| RGB not in effect assigning defaults ||::..")
                self.clip_loaded_stopped = 1
                self.clip_currently_playing = 127
                self.clip_triggered_to_play = 64
            else: # yes RGB in effect...assign per the parameters script
                self.clip_loaded_stopped = clip_loaded_stopped
                self.clip_currently_playing = clip_currently_playing
                self.clip_triggered_to_play = clip_triggered_to_play

            for scene_index in range(self.box_height): # loop on the notes matrix
                scene = self.session.scene(scene_index) # part of the martix built, think rows
                scene.name = 'Scene_' + str(scene_index) # sure, why not
                button_row = [] # create recepticle
                # loop across the tracks
                for track_index in range(self.box_width): 
                    button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, midi_channel, launch_button_list[launch_ctr]) # button instance for _Framework
                    launch_ctr = launch_ctr -1# decrement is faster than increment
                    button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button' # sure, why not
                    button_row.append(button) # add to our growing list
                    clip_slot = scene.clip_slot(track_index) # clips slot and buttons are not the same thing, this aligns these ideas in the red box
                    clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index) # sure, why not
                    # assign the button and and status in th refrech update
                    clip_slot.set_stopped_value(self.clip_loaded_stopped ) # this number is sent back to the machine allowing diff colors for stopped
                    clip_slot.set_started_value(self.clip_currently_playing) # this number is sent back to the machine allowing diff colors for started/is-playing
                    clip_slot.set_triggered_to_play_value(self.clip_triggered_to_play) # this number is sent back to the machine allowing diff colors for cued, will play next                   
                    clip_slot.set_launch_button(button) # part of the slit+button = go time paradigm
                matrix.add_row(tuple(button_row)) # close out the matrix build. @todo - possible subclass here?
        else : # log message
            self.log_message("..::|| Number of notes defined does not match box height and width Modern.DJ ||::..")
        ''' live 9 only
        self.set_highlighting_session_component(self.session) # new for live9 -- this is for the box. via aumhaa/bitnomad
        '''
        return None
    
    # Volume control specific
    # Creation of a slider for volume. Not a small burger
    def slider(self, channel, value):
        if (value != -1): 
            return SliderElement(MIDI_CC_TYPE, channel, value) # assign data to slider object
        else:
            return None

    # Static volume control offset via volume_offset param
    def custom_offset_mixer(self):
        # skipped the subclass
        # for some reason this pattern will allow the offset and static volume control.
        # looking for explaination and insight on this...Bueller?
        self.mixer_custom = MixerComponent(self.box_width) # get a local mixer object ready
        self.mixer_custom.name = 'Mixer Custom' # name
        self.mixer_custom.set_track_offset(self.volume_offset)  # the offset
        # 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_custom.channel_strip(index).set_volume_control(self.slider(midi_channel, self.track_volume_static[index]))
    
    # volume control specific, will move with red box
    # Set up mixer locally / object
    def _setup_mixer_control(self):
       self.mixer = CustomMixerComponent(self.box_width, self)  # essentially grab the super class
       self.mixer.name = 'Mixer' # sure, why not
       self.mixer.set_track_offset(0)  # not sure if needed, seems not to hurt.
       # check box width and tuple size. Forward compatibility
       if len(self.track_volume) == self.box_width:  # error checking per established app standard
           # loop on the CCs and create strip/volume control
           for index in range(self.box_width): #  @todo kill this and count in reverse via decrement (performance)
               self.mixer.channel_strip(index).set_volume_control(self.slider(midi_channel, self.track_volume[index]))
       else: # bad math, error messAge, fail
           self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "..::|| volume param bad math message. box_width != len(track_volume) ||::..")
    
    def disconnect(self):
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "..::|| Modern.DJ LIVE8 ch2 baseline MRS opened ||::..")
        self.log_message("**************************************************")
        self.log_message(" - ")
        ControlSurface.disconnect(self)
        return None
    
    def version_information(self):
        baseline_version = str(baseline_script_version_major)
        baseline_version += '.'+str(baseline_script_version_minor)
        baseline_version += '.'+str(baseline_script_version_patch)
        self.log_message('Modern.Dj Baseline Script Version '+baseline_version)
        self.log_message('Modern.Dj Baseline Script Release Note : '+baseline_script_version_note)
Beispiel #17
0
class Codec(ControlSurface):
    __module__ = __name__
    __doc__ = " MonoCode controller script "

    def __init__(self, c_instance):
        """everything except the '_on_selected_track_CHANNELged' override and 'disconnect' runs from here"""
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(
            True
        )  # Turn off rebuild MIDI map until after we're done setting up
        self._monomod_version = 'b995'
        self._version_check = 'b995'
        self._host_name = 'Codec'
        self._color_type = 'Monochrome'
        self._link_mixer = LINK_MIXER
        self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec ' +
                         str(self._monomod_version) +
                         ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
        self._hosts = []
        self._linked_script = None
        self._local_ring_control = True
        self.set_local_ring_control(1)
        self._setup_controls()
        self._last_device = None
        self._device_list = [None, None, None, None]
        self._device_select_buttons = None
        self._last_device_component = None
        self._timer = 0
        self._touched = 0
        self._locked = False
        self.flash_status = 1
        self._shift_button = None
        self._shift_pressed = 0
        self._shift_pressed_timer = 0
        self._shift_thresh = SHIFT_THRESH
        self._use_device_selector = USE_DEVICE_SELECTOR
        self._device_selection_follows_track_selection = FOLLOW
        self.set_suppress_rebuild_requests(
            False)  #Turn rebuild back on, now that we're done setting up
        self.song().view.add_selected_track_listener(
            self._update_selected_device)
        self.show_message('Codec Control Surface Loaded')
        #self.local_ring_control(True)
        #self.set_absolute_mode(True)
        self._setup_monobridge()
        self._setup_device_controls()
        self._setup_special_device_control()
        self._device.append(
            self._special_device
        )  #necessary for device browsing to work with special device
        self._setup_device_chooser()
        self._setup_mixer_controls()
        self._setup_monomod()
        self._setup_modes()
        self._setup_device_selector()
        self._setup_send_reset()
        self._setup_default_buttons()
        self._initialize_code()
        self.request_rebuild_midi_map()
        #Monomodular.create_instance(c_instance)
        #self._setup_disconnect()

    """script initialization methods"""

    def _initialize_code(self):
        self._send_midi(factoryreset)
        self._send_midi(btn_channels)
        self._send_midi(enc_channels)
        #pass

    def _setup_monobridge(self):
        self._monobridge = MonoBridgeElement(self)
        self._monobridge.name = 'MonoBridge'

    def _setup_controls(self):
        is_momentary = True
        self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                            CHANNEL, LIVID, 'Livid_Button',
                                            self)

        self._dial = [None for index in range(8)]
        for column in range(8):
            self._dial[column] = [None for index in range(4)]
            for row in range(4):
                self._dial[column][row] = CodecEncoderElement(
                    MIDI_CC_TYPE, CHANNEL, CODE_DIALS[row][column],
                    Live.MidiMap.MapMode.absolute,
                    'Dial_' + str(column) + '_' + str(row),
                    (column + (row * 8)), self)  #CODE_DIALS[row][column]

        self._button = [None for index in range(8)]
        for column in range(8):
            self._button[column] = [None for index in range(4)]
            for row in range(4):
                self._button[column][row] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                    CODE_BUTTONS[row][column],
                    'Button_' + str(column) + '_' + str(row), self)

        self._column_button = [None for index in range(8)]
        for index in range(8):
            self._column_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                CODE_COLUMN_BUTTONS[index], 'Column_Button_' + str(index),
                self)

        self._row_button = [None for index in range(4)]
        for index in range(4):
            self._row_button[index] = FlashingButtonElement(
                is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_ROW_BUTTONS[index],
                'Row_Button_' + str(index), self)

        self._dial_matrix = EncoderMatrixElement(self)
        self._dial_matrix.name = 'Encoder_Matrix'
        for row in range(4):
            dial_row = tuple([self._dial[column][row] for column in range(8)])
            self._dial_matrix.add_row(dial_row)

        self._button_matrix = ButtonMatrixElement()
        self._button_matrix.name = 'Button_Matrix'
        for row in range(4):
            button_row = [self._button[column][row] for column in range(8)]
            button_row.append(self._row_button[row])
            self._button_matrix.add_row(tuple(button_row))
        self._button_matrix.add_row(tuple(self._column_button + [self._livid]))

    def _setup_modes(self):
        self._monomod_mode = MonomodModeComponent(self)
        self._monomod_mode.name = 'Monomod_Mode'
        self._monomod_mode.update = self._mod_mode_update
        #self._monomod_mode.set_mode_toggle(self._livid)
        self.set_shift_button(self._livid)
        self._shift_mode = ShiftModeComponent(self, self._shift_update)
        self._shift_mode.name = 'Shift_Mode'
        self._shift_mode.set_mode_buttons(
            tuple([
                self._row_button[0], self._row_button[1], self._row_button[2],
                self._row_button[3]
            ]))

    def _setup_transport_control(self):
        self._transport = TransportComponent()
        self._transport.name = 'Transport'

    def _setup_monomod(self):
        self._host = MonomodComponent(self)
        self._host.name = 'Monomod_Host'
        self._host._set_dial_matrix(self._dial_matrix, self._button_matrix)
        self.hosts = [self._host]
        encs = []
        for row in range(4):
            for col in range(8):
                encs.append(self._dial[col][row])
        self._host._set_parameter_controls(encs)

    def _setup_mixer_controls(self):
        is_momentary = True
        self._num_tracks = (8)
        self._session = SessionComponent(self._num_tracks, 0)
        self._session.name = 'Session'
        self._mixer = MixerComponent(self._num_tracks, 0, False, False)
        self._mixer.name = 'Mixer'
        self._mixer._next_track_value = self._mixer_next_track_value(
            self._mixer)
        self._mixer._prev_track_value = self._mixer_prev_track_value(
            self._mixer)
        self._mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        #for index in range(8):
        #use the bottom row of encoders for volume, so add 24 to offset the index
        #	self._mixer.channel_strip(index).set_volume_control(self._dial[index+24])
        for index in range(8):
            self._mixer.channel_strip(
                index).name = 'Mixer_ChannelStrip_' + str(index)
            self._mixer.channel_strip(index)._invert_mute_feedback = True
            self._mixer.channel_strip(
                index)._mute_value = self._channelstrip_mute_value(
                    self._mixer.channel_strip(index))
            self._mixer.channel_strip(
                index)._solo_value = self._channelstrip_solo_value(
                    self._mixer.channel_strip(index))
            #mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]))
        self.song().view.selected_track = self._mixer.channel_strip(
            0
        )._track  #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
        self._session.set_mixer(self._mixer)

    def _setup_device_controls(self):
        self._device = [None for index in range(4)]
        for index in range(4):
            self._device[index] = CodecDeviceComponent(self)
            self._device[index].name = 'CodecDevice_Component_' + str(index)
            device_param_controls = []
            for control in range(8):
                device_param_controls.append(self._dial[control][index])
            self._device[index].set_on_off_button(self._button[1][index])
            self._device[index].set_lock_button(self._button[2][index])
            self._device[index].set_bank_nav_buttons(self._button[4][index],
                                                     self._button[5][index])
            self._device[index].set_nav_buttons(self._button[6][index],
                                                self._button[7][index])
            self._device[index].set_parameter_controls(
                tuple(device_param_controls))
        self.set_device_component(self._device[0])
        self._last_device_component = self._device[0]

    def _setup_special_device_control(self):
        self._special_device = SpecialCodecDeviceComponent(self)
        self._special_device.name = 'SpecialCodecDeviceComponent'
        self._special_device.set_on_off_button(self._button[1][0])
        self._special_device.set_lock_button(self._button[2][0])
        self._special_device.set_bank_nav_buttons(self._button[4][0],
                                                  self._button[5][0])
        self._special_device.set_nav_buttons(self._button[6][0],
                                             self._button[7][0])
        device_param_controls = []
        for row in range(4):
            for column in range(8):
                device_param_controls.append(self._dial[column][row])
        self._special_device.set_parameter_controls(
            tuple(device_param_controls))

    def _setup_device_chooser(self):
        self._selected_device = self._device[0]
        self._last_selected_device = self._device[0]
        self._device_select_buttons = [
            self._button[0][index] for index in range(4)
        ]
        for button in self._device_select_buttons:
            button.add_value_listener(self._device_select_value, True)

    def _setup_device_selector(self):
        self._device_selector = CodecDeviceSelectorComponent(
            self, 'c', self._device + [self._special_device])
        self._device_selector.name = 'Device_Selector'
        self._device_selector.set_mode_buttons(self._column_button)
        #self._device_selector.set_mode_toggle(self._livid)

    def _setup_send_reset(self):
        self._send_reset = CodecResetSendsComponent(self)
        self._send_reset.set_buttons(self._button)

    def _setup_default_buttons(self):
        self._value_default = ParameterDefaultComponent(self)
        buttons = []
        dials = []
        for column in self._button:
            for button in column:
                buttons.append(button)
        for column in self._dial:
            for dial in column:
                dials.append(dial)
        self._value_default.set_buttons(buttons)
        self._value_default.set_dials(dials)

    """multiple device support"""

    def _device_select_value(self, value, sender):
        #self.log_message('device_select_value ' + str(value) + ' ' + str(self._device_select_buttons.index(sender)))
        if not self._shift_pressed:
            if sender.is_momentary or value > 0:
                if self._shift_mode._mode_index == 2:
                    self.set_device_component(self._device[
                        self._device_select_buttons.index(sender)])
                    self._last_device_component = self._device_component
                    if self._device_component != None and isinstance(
                            self._device_component._device,
                            Live.Device.Device):
                        if self._device_component.find_track(
                                self._device_component._device) == self.song(
                                ).view.selected_track:
                            self._device_component.display_device()

    """livid double press mechanism"""

    def set_shift_button(self, button):
        assert ((button == None)
                or (isinstance(button, FlashingButtonElement)))
        if self._shift_button != None:
            self._shift_button.remove_value_listener(self._shift_value)
        self._shift_button = button
        if self._shift_button != None:
            self._shift_button.add_value_listener(self._shift_value)

    def _shift_value(self, value):
        self._shift_pressed = int(value != 0)
        if self._shift_pressed > 0:
            self._send_midi(SLOWENCODER)
            if (self._shift_pressed_timer + self._shift_thresh) > self._timer:
                #if(self._host.is_enabled() != True)
                self._monomod_mode.set_mode(
                    abs(self._monomod_mode._mode_index - 1))
                #else:
                #	self._monomod_mode.set_mode(0)
            self._shift_pressed_timer = self._timer % 256
        else:
            self._send_midi(NORMALENCODER)

    def _mod_mode_update(self):
        if (self._monomod_mode._mode_index == 0):
            self._host._set_shift_button(None)
            self._host.set_enabled(False)
            self._dial_matrix.reset()
            self._shift_mode.set_enabled(True)
            self._shift_update()
            self.request_rebuild_midi_map()
            self._livid.turn_off()
        elif (self._monomod_mode._mode_index == 1):
            self._shift_mode.set_enabled(False)
            self._deassign_all()
            self._dial_matrix.reset()
            self._button_matrix.reset()
            self._livid.turn_on()
            if not self._host._active_client == None:
                self._host.set_enabled(True)
                self._host._set_shift_button(self._livid)
            else:
                self._assign_alternate_mappings(1)
            self.request_rebuild_midi_map()

    """Mode Functions"""

    def _shift_update(self):
        if (self._shift_mode.is_enabled()):
            self.allow_updates(False)
            if (not self._in_build_midi_map):
                self.set_suppress_rebuild_requests(True)
            self._deassign_all()
            if (self._shift_mode._mode_index is 0):
                self._assign_volume()
            elif (self._shift_mode._mode_index is 1):
                self._assign_sends()
            elif (self._shift_mode._mode_index is 2):
                self._assign_devices()
            elif (self._shift_mode._mode_index is 3):
                self._assign_special_device()
            for index in range(self._shift_mode.number_of_modes()):
                if index == self._shift_mode._mode_index:
                    self._shift_mode._modes_buttons[index].turn_on()
                else:
                    self._shift_mode._modes_buttons[index].turn_off()
            self.allow_updates(True)
            self.set_suppress_rebuild_requests(False)
            self.request_rebuild_midi_map()

    def _deassign_all(self):
        self._assign_alternate_mappings(0)
        self._device_selector.set_enabled(False)
        for index in range(8):
            self._mixer.channel_strip(index).set_volume_control(None)
            self._mixer.channel_strip(index).set_pan_control(None)
            self._mixer.channel_strip(index).set_send_controls(
                tuple([None, None, None, None]))
        for index in range(4):
            self._device[index].set_enabled(False)
            self._device[index]._parameter_controls = None
            #self._device_navigator[index].set_enabled(False)
        self._special_device.set_enabled(False)
        self._special_device._parameter_controls = None
        self._device_selector.set_enabled(False)
        self._deassign_buttons()
        for control in self.controls:
            control.reset()
        self.request_rebuild_midi_map()

    def _deassign_buttons(self):
        for index in range(8):
            self._mixer.channel_strip(index).set_select_button(None)
            self._mixer.channel_strip(index).set_solo_button(None)
            self._mixer.channel_strip(index).set_mute_button(None)
        self._mixer.set_select_buttons(None, None)
        self._send_reset.set_enabled(False)

    def _assign_volume(self):
        for index in range(8):
            self._mixer.channel_strip(index).set_volume_control(
                self._dial[index][3])
            self._mixer.channel_strip(index).set_pan_control(
                self._dial[index][2])
            self._mixer.channel_strip(index).set_send_controls(
                tuple([self._dial[index][0], self._dial[index][1]]))
            self._mixer.channel_strip(index).set_select_button(
                self._column_button[index])
            self._mixer.channel_strip(index).set_solo_button(
                self._button[index][2])
            self._mixer.channel_strip(index).set_mute_button(
                self._button[index][3])
        self._mixer.set_select_buttons(self._button[7][0], self._button[6][0])

    def _assign_sends(self):
        for index in range(8):
            self._mixer.channel_strip(index).set_send_controls(
                tuple([
                    self._dial[index][0], self._dial[index][1],
                    self._dial[index][2], self._dial[index][3]
                ]))
            self._mixer.channel_strip(index).set_select_button(
                self._column_button[index])
            self._send_reset.set_enabled(True)

    def _assign_devices(self):
        self.set_device_component(self._last_device_component)
        self._device_select_value(
            1, self._device_select_buttons[self._device.index(
                self._device_component)])
        for index in range(4):
            device_param_controls = []
            for control in range(8):
                device_param_controls.append(self._dial[control][index])
            self._device[index].set_parameter_controls(
                tuple(device_param_controls))
            self._device[index].set_enabled(True)
        self._device_selector.set_enabled(self._use_device_selector)
        if not self._use_device_selector:
            for index in range(8):
                self._mixer.channel_strip(index).set_select_button(
                    self._column_button[index])

    def _assign_special_device(self):
        self.set_device_component(self._special_device)
        device_param_controls = []
        for row in range(4):
            for column in range(8):
                device_param_controls.append(self._dial[column][row])
        self._special_device.set_parameter_controls(
            tuple(device_param_controls))
        self._special_device.set_enabled(True)
        self._device_selector.set_enabled(self._use_device_selector)
        if not self._use_device_selector:
            for index in range(8):
                self._mixer.channel_strip(index).set_select_button(
                    self._column_button[index])

    def _assign_alternate_mappings(self, chan):
        for column in self._dial:
            for control in column:
                control.set_channel(chan)
                control.set_enabled(chan is 0)
        for column in self._button:
            for control in column:
                control.set_channel(chan)
                control.set_enabled(chan is 0)
        for control in self._column_button:
            control.set_channel(chan)
            control.set_enabled(chan is 0)
        for control in self._row_button:
            control.set_channel(chan)
            control.set_enabled(chan is 0)

    """general functionality"""

    def disconnect(self):
        """clean things up on disconnect"""
        if not self._shift_button is None:
            if self._shift_button.value_has_listener(self._shift_value):
                self._shift_button.remove_value_listener(self._shift_value)
        for button in self._device_select_buttons:
            if button.value_has_listener(self._device_select_value):
                button.remove_value_listener(self._device_select_value)
        if self._session._is_linked():
            self._session._unlink()
        self.song().view.remove_selected_track_listener(
            self._update_selected_device)
        """for cs in self._control_surfaces():
			for host in self._hosts:
				self.log_message('installed: ' + str(cs) + ' vs. ' + str(host))
				if str(type(cs)) == str(type(host)):
					self.log_message('disconnecting: ' + str(type(cs)))
					cs.disconnect(cs)"""
        #self._host._set_parameter_controls(None)
        self._hosts = []
        if self._linked_script != None:
            self._linked_script._update_linked_device_selection = None
        self._linked_script = None
        #self._disconnect_notifier.set_mode(0)
        self.log_message(
            '<<<<<<<<<<<<<<<<<<<<<<<<< Codec log closed >>>>>>>>>>>>>>>>>>>>>>>>>'
        )
        ControlSurface.disconnect(self)
        return None

    def connect_script_instances(self, instanciated_scripts):
        found = False
        for s in instanciated_scripts:
            if '_codec_version' in dir(s):
                if s._codec_version == self._version_check:
                    if s._host_name == ('MonOhm'):
                        self.log_message('found codec version ' +
                                         str(s._codec_version) +
                                         ' in script ' + str(s._host_name))
                        found = True
                        self._linked_script = s
                        self._linked_script._update_linked_device_selection = self._update_linked_device_selection
                        if not self._session._is_linked(
                        ) and self._link_mixer is True:
                            self._session.set_offsets(LINK_OFFSET[0],
                                                      LINK_OFFSET[1])
                            self._session._link()
                else:
                    self.log_message('version mismatch: Monomod version ' +
                                     str(self._version_check) +
                                     ' vs. Host version ' +
                                     str(s._codec_version))

        if found == False:
            for s in instanciated_scripts:
                if '_codec_version' in dir(s):
                    if s._codec_version == self._version_check:
                        if s._host_name == 'BlockMod':
                            self.log_message('found codec version ' +
                                             str(s._codec_version) +
                                             ' in script ' + str(s._host_name))
                            self._linked_script = s
                            self._linked_script._update_linked_device_selection = self._update_linked_device_selection
                        if not self._session._is_linked(
                        ) and self._link_mixer is True:
                            self._session.set_offsets(LINK_OFFSET[0],
                                                      LINK_OFFSET[1])
                            self._session._link()
                    else:
                        self.log_message('version mismatch: Monomod version ' +
                                         str(self._version_check) +
                                         ' vs. Host version ' +
                                         str(s._codec_version))
        #self.log_message('hosts: ' + str(self._hosts))"""

    def update_display(self):
        ControlSurface.update_display(
            self
        )  #since we are overriding this from the inherited method, we need to call the original routine as well
        self._timer = (self._timer + 1) % 256
        if (self._timer == 0):
            self._shift_pressed_timer = -12
        if (self._local_ring_control is False):
            self.send_ring_leds()
        self.flash()

    def handle_sysex(self, midi_bytes):
        #self._send_midi(tuple([240, 00, 01, 97, 04, 15, 01, 247]))
        #response = [long(0),long(0)]
        #self.log_message(response)
        pass

    def flash(self):
        if (self.flash_status > 0):
            for control in self.controls:
                if isinstance(control, FlashingButtonElement):
                    control.flash(self._timer)

    def send_ring_leds(self):
        leds = [240, 0, 1, 97, 4, 31]
        for column in range(8):
            for row in range(4):
                wheel = self._dial[column][row]
                bytes = wheel._get_ring()
                leds.append(bytes[0])
                leds.append(int(bytes[1]) + int(bytes[2]))
                #if(row == 1 and column == 0):
                #	self.log_message(str(leds) + ' ' + str(bytes[0]) + ' ' + str(bytes[1]) + ' ' + str(bytes[2]))
        leds.append(247)
        self._send_midi(tuple(leds))

    def set_absolute_mode(self, val=1):
        self._absolute_mode = (val != 0)
        if self._absolute_mode is True:
            self._send_midi(
                tuple([240, 0, 1, 97, 4, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247]))
        else:
            self._send_midi(
                tuple([
                    240, 0, 1, 97, 4, 17, 127, 127, 127, 127, 127, 127, 127,
                    127, 247
                ]))

    def set_local_ring_control(self, val=1):
        self._local_ring_control = (val != 0)
        if (self._local_ring_control is True):
            #self._send_midi(tuple([240, 0, 1, 97, 4, 32, 0, 247]))
            self._send_midi(tuple([240, 0, 1, 97, 4, 8, 72, 247]))
        else:
            #self._send_midi(tuple([240, 0, 1, 97, 4, 32, 1, 247]))
            self._send_midi(tuple([240, 0, 1, 97, 4, 8, 64, 247]))

    def device_follows_track(self, val):
        self._device_selection_follows_track_selection = (val == 1)
        return self

    """m4l bridge"""

    def generate_strip_string(self, display_string):
        NUM_CHARS_PER_DISPLAY_STRIP = 12
        if (not display_string):
            return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
        if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1))
                and (display_string.endswith('dB') and
                     (display_string.find('.') != -1))):
            display_string = display_string[:-2]
        if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
            for um in [' ', 'i', 'o', 'u', 'e', 'a']:
                while ((len(display_string) >
                        (NUM_CHARS_PER_DISPLAY_STRIP - 1))
                       and (display_string.rfind(um, 1) != -1)):
                    um_pos = display_string.rfind(um, 1)
                    display_string = (display_string[:um_pos] +
                                      display_string[(um_pos + 1):])
        else:
            display_string = display_string.center(
                (NUM_CHARS_PER_DISPLAY_STRIP - 1))
        ret = u''
        for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
            if ((ord(display_string[i]) > 127)
                    or (ord(display_string[i]) < 0)):
                ret += ' '
            else:
                ret += display_string[i]

        ret += ' '
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

    def notification_to_bridge(self, name, value, sender):
        if (isinstance(sender, CodecEncoderElement)):
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))

    def touched(self):
        if not self._host.is_enabled():
            if self._touched is 0:
                self._monobridge._send('touch', 'on')
                self.schedule_message(2, self.check_touch)
            self._touched += 1

    def check_touch(self):
        if self._touched > 5:
            self._touched = 5
        elif self._touched > 0:
            self._touched -= 1
        if self._touched is 0:
            self._monobridge._send('touch', 'off')
        else:
            self.schedule_message(2, self.check_touch)

    def get_clip_names(self):
        clip_names = []
        for scene in self._session._scenes:
            for clip_slot in scene._clip_slots:
                if clip_slot.has_clip() is True:
                    clip_names.append(clip_slot._clip_slot)  ##.clip.name)
                    return clip_slot._clip_slot
                    ##self.log_message(str(clip_slot._clip_slot.clip.name))
        return clip_names

    """overrides"""

    def allow_updates(self, allow_updates):
        for component in self.components:
            component.set_allow_update(int(allow_updates != 0))

    def set_device_component(self, device_component):
        if self._device_component != None:
            self._device_component._lock_callback = None
        assert (device_component != None)
        assert isinstance(device_component, DeviceComponent)
        self._device_component = device_component
        self._device_component._lock_callback = self._toggle_lock  #old:  self._device_component.set_lock_callback(self._toggle_lock)
        if self._device_select_buttons != None:
            for button in self._device_select_buttons:
                button.send_value(
                    self._device_select_buttons.index(button) ==
                    self._device.index(self._device_component))
        self._update_device_selection()
        return None

    def _update_selected_device(self):
        if self._device_selection_follows_track_selection is True:
            self._update_device_selection()
        return None

    def _update_linked_device_selection(self, device):
        #self.log_message('codec received ' + str(device.name))
        if self._device_component != None and device != None:
            if not self._device_component.is_locked():
                self._device_component.set_device(device)

    def _get_num_tracks(self):
        return self.num_tracks

    def _update_device_selection(self):  #new method: code to verify
        #self.log_message('_update_device_selection')
        if self._device_component != None:
            if not self._device_component.is_locked():
                track = self.song().view.selected_track
                device_to_select = track.view.selected_device
                if ((device_to_select == None) and (len(track.devices) > 0)):
                    device_to_select = track.devices[0]
                if (device_to_select != None):
                    self.song().view.select_device(device_to_select)
                self._device_component.set_device(device_to_select)

    def _channelstrip_mute_value(self, channelstrip):
        def _mute_value(value):
            if not self._shift_pressed:
                self.log_message('shift not pressed')
                ChannelStripComponent._mute_value(channelstrip, value)

        return _mute_value

    def _channelstrip_solo_value(self, channelstrip):
        def _solo_value(value):
            if not self._shift_pressed:
                ChannelStripComponent._solo_value(channelstrip, value)

        return _solo_value

    def _mixer_next_track_value(self, mixer):
        def _next_track_value(value):
            if not self._shift_pressed:
                MixerComponent._next_track_value(mixer, value)

        return _next_track_value

    def _mixer_prev_track_value(self, mixer):
        def _prev_track_value(value):
            if not self._shift_pressed:
                MixerComponent._prev_track_value(mixer, value)

        return _prev_track_value
def _setup_mixer_control(self):
is_momentary = True
num_tracks = 4 #A mixer is one-dimensional; here we define the width in tracks - seven columns,
global mixer #We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
mixer = MixerComponent(num_tracks, 0, with_eqs=False, with_filters=False) #(num_tracks, num_returns, with_eqs, with_filters)
mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
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
#"""set up the mixer buttons"""
#mixer.set_select_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 56),ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 54)) #left, right track select
#mixer.master_strip().set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 94)) #jump to the master track
#mixer.selected_strip().set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 42)) #sets the mute ("activate") button
#mixer.selected_strip().set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 44)) #sets the solo button
#mixer.selected_strip().set_arm_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 46)) #sets the record arm button
#"""set up the mixer sliders"""
mixer.selected_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, 48)) #sets the continuous controller for volume
#"""note that we have split the mixer functions across two scripts, in order to have two session highlight boxes (one red, one yellow), so there are a few things which we are not doing here..."""











# this tells Live the filename in which to look for my code

import wfK1


# this is the standardized function with which Live loads
# any script. c_instance is the Control Surface slot in Live's
# prefs, as far as I can tell

def create_instance(c_instance):
    # this is what it should load
    # (the thing inside my file that's called 'K1')

    return wfK1.K1(c_instance)


# this lets me use Live's own generic Control Surface code
# to handle a bunch of background tasks in interfacing
# with the app, so I will only have to customize the behavior
# I want and not re-do all the plumbing

from _Framework.ControlSurface import ControlSurface


# this is the thing that'll be loaded in the __init__.py file.
# it's going to be based on the generic Control Surface
# (the slot that was called c_instance in __init__.py)

class K1(ControlSurface):

    # this defines the function to construct what code
    # ('self', i.e. this very thing I wrote below) the slot
    # ('instance') will be assigned

    def __init__(self, instance):
        # this tells the compiler (which turns the script into
        # instructions Live can actually execute) to start with
        # the generic Control Surface initial setup. Super
        # means that we're executing a command in there
        # instead of code in here.

        super(K1, self).__init__(instance, False)

        # this is, as far as I can tell, a protection against crashes,
        # everything I do will be encapsulated in this guard. I
        # found a bunch of sources and scripts that
        # recommended to import the 'with' command, which
        # wasn't available in older versions of the script language,
        # but that turned out to not be necessary in Live 10

        with self.component_guard():
            # now we can do things! The first line shows a message
            # in Live's own status bar, the second adds a line to Log.txt

            self.show_message("Hello World")
            self.log_message("wayfinder K1 remote script loaded")




# code snippet from The Rabbits at Ableton forum for RACKS
def get_device_list(self, container):
    # add each device in order. if device is a rack, process each chain recursively
    # don't add racks that are not showing devices.
    lst = []
    for dev in container:
        lst.append(dev)
        if dev.can_have_chains:  # is a rack and it's open
            if dev.view.is_showing_chain_devices:
                for ch in dev.chains:
                    lst += self.get_device_list(ch.devices)
    return lst

# Called this way.
device_list = self.get_device_list(current_track.devices)


# for foldable groups
if track.is_foldable:
    track.fold_state = not track.fold_state
else:
    track.view.is_collapsed = not track.view.is_collapsed

# fold_state refers to groups .is_foldable is true for Groups.
# .is_collapsed refers to tracks that are collapsed in Arrangement view.

# I combined the two because it means one less pad used and the two are never both true.
Beispiel #19
0
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
Beispiel #20
0
class AumTroll_G(AumTroll):
    def __init__(self, *a, **k):
        super(AumTroll_G, self).__init__(*a, **k)
        with self.component_guard():
            self._setup_session_recording_component()
            self._setup_APC_detail_component()
        self.log_message('Aumtroll G 4')

    def _setup_session_recording_component(self):
        self._recorder = SessionRecordingComponent(ClipCreator(),
                                                   ViewControlComponent())

    def _setup_APC_detail_component(self):
        self._alt_device_navigator = DetailViewCntrlComponent()

    """the mixer component corresponds and moves with our selection in Live, and allows us to assign physical controls"""
    """to Live's mixer functions without having to make all the links ourselves"""

    def _setup_mixer_control(self):
        is_momentary = True
        self._num_tracks = (8)  #A mixer is one-dimensional;
        self._mixer = MixerComponent(
            8, 2, True, False
        )  #These values represent the (Number_of_tracks, Number_of_returns, EQ_component, Filter_component)
        self._mixer.name = 'Mixer'  #We name everything that we might want to access in m4l
        self._mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        for index in range(8):
            #self._mixer.channel_strip(index).set_volume_control(self._fader[index])		#Since we gave our mixer 4 tracks above, we'll now assign our fader controls to it
            self._mixer.channel_strip(
                index
            ).name = 'Mixer_ChannelStrip_' + str(
                index
            )  #We also name the individual channel_strip so we can access it
            self._mixer.track_eq(index).name = 'Mixer_EQ_' + str(
                index
            )  #We also name the individual EQ_component so we can access it
            self._mixer.channel_strip(
                index
            )._invert_mute_feedback = True  #This makes it so that when a track is muted, the corresponding button is turned off
        self.song().view.selected_track = self._mixer.channel_strip(
            0
        )._track  #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
        self._send_reset = ResetSendsComponent(
            self
        )  #This creates a custom MonoComponent that allows us to reset all the sends on a track to zero with a single button
        self._send_reset.name = 'Sends_Reset'  #We name it so that we can access it from m4l

    """the session component represents a grid of buttons that can be used to fire, stop, and navigate clips in the session view"""

    def _setup_session_control(self):
        is_momentary = True
        num_tracks = 8  #we are working with a 4x4 grid,
        num_scenes = 4  #so the height and width are both set to 4
        self._session = SessionComponent(
            num_tracks, num_scenes
        )  #we create our SessionComponent with the variables we set above it
        self._session.name = "Session"  #we name it so we can access it in m4l
        self._session.set_offsets(
            0, 0
        )  #we set the initial offset to the far left, top of the session grid
        self._session._track_banking_increment = 4
        self._session.set_stop_clip_value(
            STOP_CLIP[self._rgb]
        )  #we assign the colors that will be displayed when the stop_clip button is pressed. This value comes from CNTRLR_Map.py, which is imported in the header of our script
        self._scene = [
            None for index in range(4)
        ]  #we create an array to hold the Scene subcomponents so that we can get to them if we need them.
        for row in range(
                num_scenes
        ):  #now we'll fill the array with different objects that were created when we called the SessionComponent() module
            self._scene[row] = self._session.scene(
                row)  #each session row is a SceneComponent
            self._scene[row].name = 'Scene_' + str(
                row)  #name it so we can access it in m4l
            for column in range(
                    num_tracks
            ):  #now we'll create holders and names for the contents of each scene
                clip_slot = self._scene[row].clip_slot(
                    column
                )  #we use our assignment of the scene above to gain access to the individual clipslots.  Here, we are just assigning 'clip_slot' each time as a local variable so we can manipulated it's properties
                clip_slot.name = str(column) + '_Clip_Slot' + str(
                    row)  #name it so that we can acces it in m4l
                clip_slot.set_triggered_to_play_value(
                    CLIP_TRG_PLAY[self._rgb])  #set its triggered to play color
                clip_slot.set_triggered_to_record_value(
                    CLIP_TRG_REC[
                        self._rgb])  #set its triggered to record color
                clip_slot.set_stopped_value(
                    CLIP_STOP[self._rgb])  #set its stop color
                clip_slot.set_started_value(
                    CLIP_STARTED[self._rgb])  #set its started color
                clip_slot.set_recording_value(
                    CLIP_RECORDING[self._rgb])  #set its recording value
        self._session.set_mixer(
            self._mixer
        )  #now we link the MixerComponent we created in _setup_mixer_control() to our session component so that they will follow each other when either is navigated
        self.set_highlighting_session_component(self._session)
        self._session_zoom = SessionZoomingComponent(
            self._session
        )  #this creates the ZoomingComponent that allows navigation when the shift button is pressed
        self._session_zoom.name = 'Session_Overview'  #name it so we can access it in m4l
        self._session_zoom.set_stopped_value(
            ZOOM_STOPPED[self._rgb])  #set the zooms stopped color
        self._session_zoom.set_playing_value(
            ZOOM_PLAYING[self._rgb])  #set the zooms playing color
        self._session_zoom.set_selected_value(
            ZOOM_SELECTED[self._rgb])  #set the zooms selected color
        self._session_zoom.set_button_matrix(
            self._matrix
        )  #assign the ButtonMatrixElement that we created in _setup_controls() to the zooming component so that we can control it
        self._session_zoom.set_zoom_button(
            self._button[31]
        )  #assign a shift button so that we can switch states between the SessionComponent and the SessionZoomingComponent

    """this section is used so that we can reassign the color properties of each state.  Legacy, from the OhmModes script, to support either RGB or Monochrome"""

    def _assign_session_colors(self):
        num_tracks = 8
        num_scenes = 4
        self._session.set_stop_clip_value(STOP_ALL[self._rgb])
        for row in range(num_scenes):
            for column in range(num_tracks):
                self._scene[row].clip_slot(column).set_triggered_to_play_value(
                    CLIP_TRG_PLAY[self._rgb])
                self._scene[row].clip_slot(
                    column).set_triggered_to_record_value(
                        CLIP_TRG_REC[self._rgb])
                self._scene[row].clip_slot(column).set_stopped_value(
                    CLIP_STOP[self._rgb])
                self._scene[row].clip_slot(column).set_started_value(
                    CLIP_STARTED[self._rgb])
                self._scene[row].clip_slot(column).set_recording_value(
                    CLIP_RECORDING[self._rgb])
        self._session_zoom.set_stopped_value(ZOOM_STOPPED[self._rgb])
        self._session_zoom.set_playing_value(ZOOM_PLAYING[self._rgb])
        self._session_zoom.set_selected_value(ZOOM_SELECTED[self._rgb])
        self.refresh_state()

    def deassign_live_controls(self, *a, **k):
        for index in range(4):
            self._encoder[index].send_value(0, True)
            self._encoder[index].clear_send_cache()
            self._mixer.channel_strip(index + 4).set_volume_control(
                None
            )  #Since we gave our mixer 4 tracks above, we'll now assign our fader controls to it																#for the left side of the mixer
            self._mixer.channel_strip(index + 4).set_solo_button(
                None)  #remove the solo button assignments
            self._mixer.channel_strip(index + 4).set_arm_button(
                None)  #remove the arm button assignments
            self._mixer.channel_strip(index + 4).set_mute_button(
                None)  #remove the mute button assignments
            self._mixer.channel_strip(index + 4).set_select_button(
                None)  #remove the select button assignments
        #self._alt_device_navigator.set_arrange_session_toggle_button(None)
        self._alt_device_navigator.set_device_clip_toggle_button(None)
        self._alt_device_navigator.set_detail_toggle_button(None)
        self._alt_device_navigator.set_enabled(False)
        #self._alt_device_navigator.set_shift_button(None)
        self._transport.set_nudge_buttons(None, None)
        self._recorder.set_record_button(None)
        self._recorder.set_re_enable_automation_button(None)

        super(AumTroll_G, self).deassign_live_controls(*a, **k)

    def assign_live_controls(self):
        """the following lines update all of the controls' last_sent properties, so that they forward the next value they receive regardless of whether or not it is the same as the last it recieved"""
        """we also reset the encoder rings and buttons, since the device component will not update them if it is not locked to a device in Live"""
        for index in range(16):
            self._grid[index].force_next_send()
        for index in range(32):
            #self._button[index].set_on_off_values(0, 127)
            self._button[index].send_value(0, True)
            self._button[index].force_next_send()
        for index in range(8):
            self._encoder_button[index + 4].send_value(0, True)
            self._encoder_button[index + 4].force_next_send()
        for index in range(12):
            self._encoder[index].send_value(0, True)
            self._encoder[index].force_next_send()
        """here we assign the left side of our mixer's buttons on the lower 32 keys"""
        if self._monohm is None:
            with self.component_guard():
                for index in range(
                        4
                ):  #we set up a recursive loop to assign all four of our track channel strips' controls
                    self._button[index + 16].set_on_value(
                        MUTE[self._rgb])  #set the mute color from the Map.py
                    self._mixer.channel_strip(index).set_mute_button(
                        self._button[index + 16]
                    )  #assign the mute buttons to our mixer channel strips
                    self._button[index + 28].set_on_value(
                        MUTE[self._rgb])  #set the mute color from the Map.py
                    self._mixer.channel_strip(index + 4).set_mute_button(
                        self._button[index + 28]
                    )  #assign the mute buttons to our mixer channel strips

                    self._button[index].set_on_off_values(
                        SELECT[self._rgb], SELECT_OFF[self._rgb])
                    self._mixer.channel_strip(index).set_select_button(
                        self._button[index]
                    )  #assign the select buttons to our mixer channel strips
                    self._button[index + 12].set_on_off_values(
                        SELECT[self._rgb], SELECT_OFF[
                            self._rgb])  #set the select color from the Map.py
                    self._mixer.channel_strip(index + 4).set_select_button(
                        self._button[index + 12]
                    )  #assign the select buttons to our mixer channel strips

                #self._session.set_stop_track_clip_buttons(tuple(self._button[index+4] for index in range(8)))	#these last two lines assign the send_reset buttons and the stop_clip buttons for each track
                for index in range(8):
                    #self._button[index + 4].set_on_off_values(SOLO[self._rgb], SOLO[self._rgb])	#this assigns the custom colors defined in the Map.py file to the stop_clip buttons.  They have seperate on/off values, but we assign them both the same value so we can always identify them
                    self._mixer.channel_strip(index).set_solo_button(
                        self._button[index + 4])
                    #self._button[index + 4].send_value(STOP_CLIP[self._rgb], True)				#finally, we send the on/off colors out to turn the LEDs on for the stop clip buttons
                for index in range(
                        4
                ):  #set up a for loop to generate an index for assigning the session nav buttons' colors
                    self._button[index + 20].set_on_off_values(
                        SESSION_NAV[self._rgb], SESSION_NAV_OFF[self._rgb]
                    )  #assign the colors from Map.py to the session nav buttons
                self._session.set_track_bank_buttons(
                    self._button[21], self._button[20]
                )  #set the track bank buttons for the Session navigation controls
                self._session.set_scene_bank_buttons(
                    self._button[23], self._button[22]
                )  #set the scnee bank buttons for the Session navigation controls
                """this section assigns the grid to the clip launch functionality of the SessionComponent"""
                for column in range(
                        4
                ):  #we need to set up a double recursion so that we can generate the indexes needed to assign the grid buttons
                    for row in range(
                            4
                    ):  #the first recursion passes the column index, the second the row index
                        self._scene[row].clip_slot(column).set_launch_button(
                            self._grid[(row * 4) + column]
                        )  #we use the indexes to grab the first the scene and then the clip we assigned above, and then we use them again to define the button held in the grid array that we want to assign to the clip slot from the session component

                for index in range(
                        4
                ):  #set up a for loop to generate an index for assigning the session nav buttons' colors
                    self._button[index + 24].set_on_off_values(
                        SHIFTS[self._rgb], SHIFTS_OFF[self._rgb]
                    )  #assign the colors from Map.py to the session nav buttons

                self._session.update(
                )  #tell the Session component to update so that the grid will display the currently selected session region
                self._session.set_enabled(True)  #enable the Session Component
                self._session_zoom.set_enabled(True)  #enable the Session Zoom

                #self._alt_device_navigator.set_arrange_session_toggle_button(self._encoder_button[4])
                self._alt_device_navigator.set_device_clip_toggle_button(
                    self._encoder_button[5])
                self._alt_device_navigator.set_detail_toggle_button(
                    self._encoder_button[6])
                #self._device_navigator.set_shift_button(self._encoder_button[7])
                self._session_zoom.set_zoom_button(
                    self._encoder_button[7]
                )  #assign the lower right key button to the shift function of the Zoom component

                self._session.set_scene_bank_buttons(self._button[25],
                                                     self._button[24])
                self._recorder.set_record_button(self._button[27])
                self._recorder.set_re_enable_automation_button(
                    self._button[26])
        else:
            for index in range(8):
                self._mixer2.channel_strip(index).set_volume_control(
                    self._fader[index])
            self._mixer2.set_track_offset(TROLL_OFFSET)
            self._device_selector.set_mode_buttons(self._grid)
            if not self._shifted:
                self._assign_monomodular_controls()
            else:
                self._assign_shifted_controls()
            self._device1.set_parameter_controls(
                tuple([self._knobs[index] for index in range(8)]))
            self._device2.set_parameter_controls(
                tuple([self._knobs[index + 12] for index in range(8)]))
            self._device1.set_enabled(True)
            self._device2.set_enabled(True)
            self._find_devices()
            self._device1.update()
            self._device2.update()
        """this section assigns the encoders and encoder buttons"""
        self._device.set_parameter_controls(
            tuple([self._encoder[index + 4] for index in range(8)])
        )  #assign the encoders from the device component controls - we are doing this here b
        #self._encoder_button[7].set_on_value(DEVICE_LOCK[self._rgb])					#set the on color for the Device lock encoder button
        #self._device.set_lock_button(self._encoder_button[7])							#assign encoder button 7 to the device lock control
        #self._encoder_button[4].set_on_value(DEVICE_ON[self._rgb])						#set the on color for the Device on/off encoder button
        #self._device.set_on_off_button(self._encoder_button[4])							#assing encoder button 4 to the device on/off control
        for index in range(
                2
        ):  #setup a recursion to generate indexes so that we can reference the correct controls to assing to the device_navigator functions
            self._encoder_button[index + 8].set_on_value(
                DEVICE_NAV[
                    self._rgb])  #assign the on color for the device navigator
            self._encoder_button[index + 10].set_on_value(
                DEVICE_BANK[self._rgb]
            )  #assign the on color for the device bank controls
        self._device_navigator.set_nav_buttons(
            self._encoder_button[10], self._encoder_button[11]
        )  #set the device navigators controls to encoder buttons 10 and 11
        self._device.set_bank_nav_buttons(
            self._encoder_button[8], self._encoder_button[9]
        )  #set the device components bank nav controls to encoder buttons 8 and 9
        """now we turn on and update some of the components we've just made assignments to"""
        self._device.set_enabled(True)  #enable the Device Component
        self._device_navigator.set_enabled(True)  #enable the Device Navigator
        self._alt_device_navigator.set_enabled(True)
        self._device.update(
        )  #tell the Device component to update its assingments so that it will detect the currently selected device parameters and display them on the encoder rings
Beispiel #21
0
class Codec(ControlSurface):
	__module__ = __name__
	__doc__ = " MonoCode controller script "


	def __init__(self, c_instance, *a, **k):
		super(Codec, self).__init__(c_instance, *a, **k)
		self._monomod_version = 'b995'
		self._version_check = 'b995'
		self._host_name = 'Codec'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self._hosts = []
		self._linked_script = None
		self._local_ring_control = True
		self._last_device = None
		self._device_list = [None, None, None, None]
		self._device_select_buttons = None
		self._last_device_component = None
		self._timer = 0
		self._touched = 0
		self._locked = False
		self.flash_status = 1
		self._shift_button = None
		self._shift_pressed = 0
		self._shift_pressed_timer = 0
		self._shift_thresh = SHIFT_THRESH
		self._use_device_selector = USE_DEVICE_SELECTOR
		self._device_selection_follows_track_selection=FOLLOW
		with self.component_guard():
			#self.local_ring_control(True)
			#self.set_absolute_mode(True)
			self._setup_controls()
			self._setup_monobridge()
			self._setup_device_controls()
			self._setup_special_device_control() 
			self._device.append(self._special_device)			#necessary for device browsing to work with special device
			self._setup_device_chooser()
			self._setup_mixer_controls()
			self._setup_monomod()
			self._setup_modes() 
			self._setup_device_selector()
			self._setup_send_reset()
			self._setup_default_buttons()
			self.set_local_ring_control(1)
			self.song().view.add_selected_track_listener(self._update_selected_device)
			self._initialize_code()
			#self._shift_mode.set_mode(0)
			#self._monomod_mode.set_mode(0)
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec ' + str(self._monomod_version) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
		self.show_message('Codec Control Surface Loaded')
		self.request_rebuild_midi_map()
	


	"""script initialization methods"""
	def _initialize_code(self):
		self._send_midi(factoryreset)
		self._send_midi(btn_channels)
		self._send_midi(enc_channels)	
	

	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def _setup_controls(self):
		is_momentary = True
		self._livid = CodecMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		
		self._dial = [None for index in range(8)]
		for column in range(8):
			self._dial[column] = [None for index in range(4)]
			for row in range(4):
				self._dial[column][row] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, CODE_DIALS[row][column], Live.MidiMap.MapMode.absolute, 'Dial_' + str(column) + '_' +	str(row), (column + (row*8)), self)	#CODE_DIALS[row][column]
				
		self._button = [None for index in range(8)]
		for column in range(8):
			self._button[column] = [None for index in range(4)]
			for row in range(4):
				self._button[column][row] = CodecMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_BUTTONS[row][column], 'Button_' + str(column) + '_' + str(row), self) 
		

		self._column_button = [None for index in range(8)]
		for index in range(8):
			self._column_button[index] = CodecMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_COLUMN_BUTTONS[index], 'Column_Button_' + str(index), self)		
			
		self._row_button = [None for index in range(4)]
		for index in range(4):
			self._row_button[index] = CodecMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CODE_ROW_BUTTONS[index], 'Row_Button_' + str(index), self)		

		self._dial_matrix = EncoderMatrixElement(self)
		self._dial_matrix.name = 'Encoder_Matrix'
		for row in range(4):
			dial_row = tuple([self._dial[column][row] for column in range(8)])
			self._dial_matrix.add_row(dial_row)

		self._button_matrix = ButtonMatrixElement()
		self._button_matrix.name = 'Button_Matrix'
		for row in range(4):
			button_row = [self._button[column][row] for column in range(8)]
			button_row.append(self._row_button[row])
			self._button_matrix.add_row(tuple(button_row))
		self._button_matrix.add_row(tuple(self._column_button + [self._livid]))
	

	def _setup_modes(self):
		self._monomod_mode = MonomodModeComponent(self._mod_mode_update, self)
		self._monomod_mode.name = 'Monomod_Mode'
		self.set_shift_button(self._livid)
		self._shift_mode = ShiftModeComponent(self._shift_update, self) 
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_buttons(tuple([self._row_button[0], self._row_button[1], self._row_button[2], self._row_button[3]]))
	

	def _setup_transport_control(self):
		self._transport = TransportComponent() 
		self._transport.name = 'Transport'
	

	def _setup_monomod(self):
		self._host = CodecMonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self._host._set_dial_matrix(self._dial_matrix, self._button_matrix)
		self.hosts = [self._host]
		encs = []
		for row in range(4):
			for col in range(8):
				encs.append(self._dial[col][row])
		self._host._set_parameter_controls(encs)
	

	def _setup_mixer_controls(self):
		is_momentary = True
		self._num_tracks = (8)
		self._session = SessionComponent(self._num_tracks, 0)
		self._session.name = 'Session'
		self._mixer = MixerComponent(self._num_tracks, 0, False, False)
		self._mixer.name = 'Mixer'
		self._mixer._next_track_value = self._mixer_next_track_value(self._mixer)
		self._mixer._prev_track_value = self._mixer_prev_track_value(self._mixer)
		self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		#for index in range(8):
			#use the bottom row of encoders for volume, so add 24 to offset the index
		#	self._mixer.channel_strip(index).set_volume_control(self._dial[index+24])
		for index in range(8):
			self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			self._mixer.channel_strip(index)._invert_mute_feedback = True
			self._mixer.channel_strip(index)._mute_value = self._channelstrip_mute_value(self._mixer.channel_strip(index))
			self._mixer.channel_strip(index)._solo_value = self._channelstrip_solo_value(self._mixer.channel_strip(index))
			#mixer.channel_strip(index).set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CH, track_select_notes[index]))
		self.song().view.selected_track = self._mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
		self._session.set_mixer(self._mixer)
	

	def _setup_device_controls(self):
		self._device = [None for index in range(4)]
		for index in range(4):
			self._device[index] = CodecDeviceComponent(self)
			self._device[index].name = 'CodecDevice_Component_' + str(index)
			device_param_controls = []
			for control in range(8):
				device_param_controls.append(self._dial[control][index])
			self._device[index].set_on_off_button(self._button[1][index])
			self._device[index].set_lock_button(self._button[2][index])
			self._device[index].set_bank_nav_buttons(self._button[4][index], self._button[5][index])
			self._device[index].set_nav_buttons(self._button[6][index], self._button[7][index])
			self._device[index].set_parameter_controls(tuple(device_param_controls))
		self.set_device_component(self._device[0])
		self._last_device_component = self._device[0]
	

	def _setup_special_device_control(self):
		self._special_device = SpecialCodecDeviceComponent(self)
		self._special_device.name = 'SpecialCodecDeviceComponent'
		self._special_device.set_on_off_button(self._button[1][0])
		self._special_device.set_lock_button(self._button[2][0])
		self._special_device.set_bank_nav_buttons(self._button[4][0], self._button[5][0])
		self._special_device.set_nav_buttons(self._button[6][0], self._button[7][0])
		device_param_controls = []
		for row in range(4):
			for column in range(8):
				device_param_controls.append(self._dial[column][row])
		self._special_device.set_parameter_controls(tuple(device_param_controls))
	

	def _setup_device_chooser(self):
		self._selected_device = self._device[0]
		self._last_selected_device = self._device[0]
		self._device_select_buttons = [self._button[0][index] for index in range(4)]
		for button in self._device_select_buttons:
			button.add_value_listener(self._device_select_value, True)
	

	def _setup_device_selector(self):
		self._device_selector = CodecDeviceSelectorComponent(self, 'c', self._device + [self._special_device])
		self._device_selector.name = 'Device_Selector'
		self._device_selector.set_mode_buttons(self._column_button)
		#self._device_selector.set_mode_toggle(self._livid)
	

	def _setup_send_reset(self):
		self._send_reset = CodecResetSendsComponent(self)
		self._send_reset.set_buttons(self._button)
	

	def _setup_default_buttons(self):
		self._value_default = ParameterDefaultComponent(self)
		buttons = []
		dials = []
		for column in self._button:
			for button in column:
				buttons.append(button)
		for column in self._dial:
			for dial in column:
				dials.append(dial)
		self._value_default.set_buttons(buttons)
		self._value_default.set_dials(dials)
	


	"""multiple device support"""
	def _device_select_value(self, value, sender):
		#self.log_message('device_select_value ' + str(value) + ' ' + str(self._device_select_buttons.index(sender)))
		if not self._shift_pressed:
			if sender.is_momentary or value > 0:
				if self._shift_mode._mode_index == 2:
					self.set_device_component(self._device[self._device_select_buttons.index(sender)])
					self._last_device_component = self._device_component
					if self._device_component != None and isinstance(self._device_component._device, Live.Device.Device):
						if self._device_component.find_track(self._device_component._device) == self.song().view.selected_track:
							self._device_component.display_device()
	


	"""livid double press mechanism"""
	def set_shift_button(self, button):
		assert ((button == None) or (isinstance(button, MonoButtonElement)))
		if self._shift_button != None:
			self._shift_button.remove_value_listener(self._shift_value)
		self._shift_button = button
		if self._shift_button != None:
			self._shift_button.add_value_listener(self._shift_value)
	

	def _shift_value(self, value):
		self._shift_pressed = int(value != 0)
		if self._shift_pressed > 0:
			self._send_midi(SLOWENCODER)
			if (self._shift_pressed_timer + self._shift_thresh) > self._timer:
				#if(self._host.is_enabled() != True)
				self.log_message('mod mode: ' + str(abs(self._monomod_mode._mode_index - 1)))
				self._monomod_mode.set_mode(max(0, min(1, abs(self._monomod_mode._mode_index - 1))))
				#else:
				#	self._monomod_mode.set_mode(0)
			self._shift_pressed_timer = self._timer % 256
		else:
			self._send_midi(NORMALENCODER)
	

	def _mod_mode_update(self):
		if(self._monomod_mode._mode_index == 0):
			self._host._set_shift_button(None)
			self._host.set_enabled(False)
			self._dial_matrix.reset()
			self._shift_mode.set_enabled(True)
			self._shift_update()
			self.request_rebuild_midi_map()
			self._livid.turn_off()
		elif(self._monomod_mode._mode_index == 1):
			self._shift_mode.set_enabled(False)
			self._deassign_all()
			self._dial_matrix.reset()
			self._button_matrix.reset()			
			self._livid.turn_on()
			if not self._host._active_client == None:
				self._host.set_enabled(True)
				self._host._set_shift_button(self._livid)
			else:
				self._assign_alternate_mappings(1)
			self.request_rebuild_midi_map()
	


	"""Mode Functions"""
	def _shift_update(self):
		if(self._shift_mode.is_enabled()):
			with self.component_guard():
				self.allow_updates(False)
				#if(not self._in_build_midi_map):
				#	self.set_suppress_rebuild_requests(True)
				self._deassign_all()
				if(self._shift_mode._mode_index is 0):
					self._assign_volume()
				elif(self._shift_mode._mode_index is 1):
					self._assign_sends()
				elif(self._shift_mode._mode_index is 2):
					self._assign_devices()
				elif(self._shift_mode._mode_index is 3):
					self._assign_special_device()
				for index in range(self._shift_mode.number_of_modes()):
					if index == self._shift_mode._mode_index:
						self._shift_mode._modes_buttons[index].turn_on()
					else:
						self._shift_mode._modes_buttons[index].turn_off()
				self.allow_updates(True)
				#self.set_suppress_rebuild_requests(False)
				self.request_rebuild_midi_map()
	

	def _deassign_all(self):
		self._assign_alternate_mappings(0)
		self._device_selector.set_enabled(False)
		for index in range(8):
			self._mixer.channel_strip(index).set_volume_control(None)
			self._mixer.channel_strip(index).set_pan_control(None)
			self._mixer.channel_strip(index).set_send_controls(tuple([None, None, None, None]))
		for index in range(4):
			self._device[index].set_enabled(False)
			self._device[index]._parameter_controls = None
			#self._device_navigator[index].set_enabled(False)
		self._special_device.set_enabled(False)
		self._special_device._parameter_controls = None
		self._device_selector.set_enabled(False)
		self._deassign_buttons()
		for control in self.controls:
			control.reset()
		self.request_rebuild_midi_map()
	

	def _deassign_buttons(self):
		for index in range(8):
			self._mixer.channel_strip(index).set_select_button(None)
			self._mixer.channel_strip(index).set_solo_button(None)
			self._mixer.channel_strip(index).set_mute_button(None)
		self._mixer.set_select_buttons(None, None)
		self._send_reset.set_enabled(False)
	

	def _assign_volume(self):
		for index in range(8):
			self._mixer.channel_strip(index).set_volume_control(self._dial[index][3])
			self._mixer.channel_strip(index).set_pan_control(self._dial[index][2])
			self._mixer.channel_strip(index).set_send_controls(tuple([self._dial[index][0], self._dial[index][1]]))
			self._mixer.channel_strip(index).set_select_button(self._column_button[index])
			self._mixer.channel_strip(index).set_solo_button(self._button[index][2])
			self._mixer.channel_strip(index).set_mute_button(self._button[index][3])
		self._mixer.set_select_buttons(self._button[7][0], self._button[6][0])
	

	def _assign_sends(self):
		for index in range(8):
			self._mixer.channel_strip(index).set_send_controls(tuple([self._dial[index][0], self._dial[index][1], self._dial[index][2], self._dial[index][3]]))
			self._mixer.channel_strip(index).set_select_button(self._column_button[index])
			self._send_reset.set_enabled(True)
	

	def _assign_devices(self):
		self.set_device_component(self._last_device_component)
		self._device_select_value(1, self._device_select_buttons[self._device.index(self._device_component)])
		for index in range(4):
			device_param_controls = []
			for control in range(8):
				device_param_controls.append(self._dial[control][index])
			self._device[index].set_parameter_controls(tuple(device_param_controls))
			self._device[index].set_enabled(True)
		self._device_selector.set_enabled(self._use_device_selector)
		if not self._use_device_selector:
			for index in range(8):
				self._mixer.channel_strip(index).set_select_button(self._column_button[index])				
	

	def _assign_special_device(self):
		self.set_device_component(self._special_device)
		device_param_controls = []
		for row in range(4):
			for column in range(8):
				device_param_controls.append(self._dial[column][row])
		self._special_device.set_parameter_controls(tuple(device_param_controls))
		self._special_device.set_enabled(True)
		self._device_selector.set_enabled(self._use_device_selector)
		if not self._use_device_selector:
			for index in range(8):
				self._mixer.channel_strip(index).set_select_button(self._column_button[index])	
	

	def _assign_alternate_mappings(self, chan):
		for column in self._dial:
			for control in column:
				control.set_channel(chan)
				control.set_enabled(chan is 0)
		for column in self._button:
			for control in column:
				control.set_channel(chan)
				control.set_enabled(chan is 0)
		for control in self._column_button:
			control.set_channel(chan)
			control.set_enabled(chan is 0)
		for control in self._row_button:
			control.set_channel(chan)
			control.set_enabled(chan is 0)
	


	"""general functionality"""
	def disconnect(self):
		"""clean things up on disconnect"""
		if not self._shift_button is None:
			if self._shift_button.value_has_listener(self._shift_value):
				self._shift_button.remove_value_listener(self._shift_value)
		for button in self._device_select_buttons:
			if button.value_has_listener(self._device_select_value):
				button.remove_value_listener(self._device_select_value)
		if self._session._is_linked():
			self._session._unlink()
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		"""for cs in self._control_surfaces():
			for host in self._hosts:
				self.log_message('installed: ' + str(cs) + ' vs. ' + str(host))
				if str(type(cs)) == str(type(host)):
					self.log_message('disconnecting: ' + str(type(cs)))
					cs.disconnect(cs)"""
		#self._host._set_parameter_controls(None)
		self._hosts = []
		if self._linked_script != None:
			self._linked_script._update_linked_device_selection = None
		self._linked_script = None
		#self._disconnect_notifier.set_mode(0)
		self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< Codec log closed >>>>>>>>>>>>>>>>>>>>>>>>>')
		ControlSurface.disconnect(self)
		return None
		
	

	def connect_script_instances(self, instanciated_scripts):
		found = False
		for s in instanciated_scripts:
			if '_codec_version' in dir(s):
				if s._codec_version == self._version_check:
					if s._host_name == ('MonOhm'):
						self.log_message('found codec version ' + str(s._codec_version) + ' in script ' + str(s._host_name))
						found = True
						self._linked_script = s
						self._linked_script._update_linked_device_selection = self._update_linked_device_selection
						if not self._session._is_linked() and self._link_mixer is True:
							self._session.set_offsets(LINK_OFFSET[0], LINK_OFFSET[1])
							self._session._link()
				else:
					self.log_message('version mismatch: Monomod version ' + str(self._version_check) + ' vs. Host version ' + str(s._codec_version))
					

		if found == False:
			for s in instanciated_scripts:
				if '_codec_version' in dir(s):
					if s._codec_version == self._version_check:
						if s._host_name == 'BlockMod':
							self.log_message('found codec version ' + str(s._codec_version) + ' in script ' + str(s._host_name))
							self._linked_script = s
							self._linked_script._update_linked_device_selection = self._update_linked_device_selection
						if not self._session._is_linked() and self._link_mixer is True:
							self._session.set_offsets(LINK_OFFSET[0], LINK_OFFSET[1])
							self._session._link()
					else:
						self.log_message('version mismatch: Monomod version ' + str(self._version_check) + ' vs. Host version ' + str(s._codec_version))
		#self.log_message('hosts: ' + str(self._hosts))"""
	

	def update_display(self):
		ControlSurface.update_display(self)		#since we are overriding this from the inherited method, we need to call the original routine as well
		self._timer = (self._timer + 1) % 256
		if(self._timer == 0):
			self._shift_pressed_timer = -12
		if(self._local_ring_control is False):
			self.send_ring_leds()
		self.flash()
	

	def handle_sysex(self, midi_bytes):
		#self._send_midi(tuple([240, 00, 01, 97, 04, 15, 01, 247]))
		#response = [long(0),long(0)]
		#self.log_message(response)
		pass
	

	def flash(self):
		if(self.flash_status > 0):
			for control in self.controls:
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)
	

	def send_ring_leds(self):
		leds = [240, 0, 1, 97, 4, 31]
		for column in range(8):
			for row in range(4):
				wheel = self._dial[column][row]
				bytes = wheel._get_ring()
				leds.append(bytes[0])
				leds.append(int(bytes[1]) + int(bytes[2]))
				#if(row == 1 and column == 0):
				#	self.log_message(str(leds) + ' ' + str(bytes[0]) + ' ' + str(bytes[1]) + ' ' + str(bytes[2]))
		leds.append(247)
		self._send_midi(tuple(leds))
	

	def set_absolute_mode(self, val = 1):
		self._absolute_mode = (val!=0)
		if self._absolute_mode is True:
			self._send_midi(tuple([240, 0, 1, 97, 4, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247]))
		else:
			self._send_midi(tuple([240, 0, 1, 97, 4, 17, 127, 127, 127, 127, 127, 127, 127, 127, 247]))
	

	def set_local_ring_control(self, val = 1):
		self._local_ring_control = (val!=0)
		if(self._local_ring_control is True):
			#self._send_midi(tuple([240, 0, 1, 97, 4, 32, 0, 247]))
			self._send_midi(tuple([240, 0, 1, 97, 4, 8, 72, 247]))
		else:
			#self._send_midi(tuple([240, 0, 1, 97, 4, 32, 1, 247]))
			self._send_midi(tuple([240, 0, 1, 97, 4, 8, 64, 247]))
	

	def device_follows_track(self, val):
		self._device_selection_follows_track_selection = (val == 1)
		return self
	


	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if (not display_string):
			return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
		if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))):
			display_string = display_string[:-2]
		if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)):
					um_pos = display_string.rfind(um, 1)
					display_string = (display_string[:um_pos] + display_string[(um_pos + 1):])
		else:
			display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1))
		ret = u''
		for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)):
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		if(isinstance(sender, CodecEncoderElement)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

	def touched(self):
		if not self._host.is_enabled():
			if self._touched is 0:
				self._monobridge._send('touch', 'on')
				self.schedule_message(2, self.check_touch)
			self._touched +=1
	

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)
	

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)##.clip.name)
					return clip_slot._clip_slot
					##self.log_message(str(clip_slot._clip_slot.clip.name))
		return clip_names
	


	"""overrides"""
	def allow_updates(self, allow_updates):
		for component in self.components:
			component.set_allow_update(int(allow_updates!=0))
	

	def set_device_component(self, device_component):
		if self._device_component != None:
			self._device_component._lock_callback = None
		assert (device_component != None)
		assert isinstance(device_component, DeviceComponent)
		self._device_component = device_component
		self._device_component._lock_callback = self._toggle_lock	#old:  self._device_component.set_lock_callback(self._toggle_lock)
		if self._device_select_buttons != None:
			for button in self._device_select_buttons:
				button.send_value(self._device_select_buttons.index(button) == self._device.index(self._device_component))
		self._update_device_selection()
		return None
	

	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			self._update_device_selection()
		return None 
	

	def _update_linked_device_selection(self, device):
		#self.log_message('codec received ' + str(device.name))
		if self._device_component != None and device != None:
			if not self._device_component.is_locked():
				self._device_component.set_device(device)
	

	def _get_num_tracks(self):
		return self.num_tracks
	

	def _update_device_selection(self):
		#self.log_message('_update_device_selection')
		if self._device_component != None:
			if not self._device_component.is_locked():
				track = self.song().view.selected_track
				device_to_select = track.view.selected_device
				if ((device_to_select == None) and (len(track.devices) > 0)):
					device_to_select = track.devices[0]
				if (device_to_select != None):
					self.song().view.select_device(device_to_select)
				self._device_component.set_device(device_to_select)
 	

	def _channelstrip_mute_value(self, channelstrip):
		def _mute_value(value):
			if not self._shift_pressed:
				self.log_message('shift not pressed')
				ChannelStripComponent._mute_value(channelstrip, value)
		return _mute_value
		
	

	def _channelstrip_solo_value(self, channelstrip):
		def _solo_value(value):
			if not self._shift_pressed:
				ChannelStripComponent._solo_value(channelstrip, value)
		return _solo_value
		
	

	def _mixer_next_track_value(self, mixer):
		def _next_track_value(value):
			if not self._shift_pressed:
				MixerComponent._next_track_value(mixer, value)
		return _next_track_value
		
	

	def _mixer_prev_track_value(self, mixer):
		def _prev_track_value(value):
			if not self._shift_pressed:
				MixerComponent._prev_track_value(mixer, value)
		return _prev_track_value
Beispiel #22
0
class Tweaker(ControlSurface):
	__module__ = __name__
	__doc__ = " Tweaker control surface script "


	def __init__(self, c_instance, *a, **k):
		super(Tweaker, self).__init__(c_instance, *a, **k)
		with self.component_guard():
			self._update_linked_device_selection = None
			self._tweaker_version_check = '0.3'
			self.log_message("--------------= Tweaker Session " + str(self._tweaker_version_check) + " log opened =--------------") 
			self._timer = 0
			self.flash_status = 1
			self._last_selected_strip_number = 0
			self._device_selection_follows_track_selection = False
			#self._pad_translations = PAD_TRANSLATION
			self._linked_session = None
			self._mixer_offset = 0
			self._nav_lock = True
			self._setup_controls()
			self._setup_transport_control() 
			self._setup_device_control()
			self._setup_mixer_control()
			self._setup_session_control()
			self._setup_crossfader()
			self._setup_modes() 
			self._setup_pads()
			self._setup_navigation_lock()
			self._setup_arrange_session_toggle()
			#self.assign_main_configuration()
			#self.request_rebuild_midi_map()
			#self._mixer._reassign_tracks()	#this is to update rebuild the cf_assign closure, otherwise the colors aren't correct
			#self.schedule_message(30, self._detect_devices)

			self.show_message('Tweaker Control Surface Loaded')
		self.show_message('Tweaker Control Surface Loaded')
		#self._shift_value(0)  #this updates the pads so that they transmit to Live on the assigned PAD_CHANNEL...also, lights shift button
		self.assign_main_configuration()
		#self.schedule_message(2, self._shift_value, 0)
		self.schedule_message(3, self._mixer._reassign_tracks)
	

	"""script initialization methods"""
	def _setup_controls(self):
		is_momentary = True
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column + (row * 8) + 1, 'Grid_' + str(column) + '_' + str(row), self) for row in range(4)]
		self._button = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_BUTTONS[index], 'Button_' + str(index), self) for index in range(len(TWEAKER_BUTTONS))]
		self._nav = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_NAVS[index], 'Nav_' + str(index), self) for index in range(len(TWEAKER_NAVS))]
		self._encoder_button = [TweakerMonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_ENCODER_BUTTONS[index], 'Encoder_Button_' + str(index), self) for index in range(len(TWEAKER_ENCODER_BUTTONS))]
		self._dial = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_DIALS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_DIALS))]
		self._fader = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_FADERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_FADERS))]
		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._encoder = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_ENCODERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_ENCODERS))]
		self._pad = [TweakerMonoButtonElement(False, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_PADS[index], 'Pad_' + str(index), self) for index in range(len(TWEAKER_PADS))]
		for index in range(4):
			self._pad[index].set_enabled(False)
			self._pad[index].set_channel(PAD_CHANNEL)
			self._pad[index].set_identifier(index + 4)
			self._pad[index+4].set_enabled(False)
			self._pad[index+4].set_channel(PAD_CHANNEL)
			self._pad[index+4].set_identifier(index)
		self._pad_pressure = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_PAD_PRESSURES[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_PADS))]
		for index in range(8):
			self._pad_pressure[index]._last_sent = 0
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		for row in range(4):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 	
		self._send_midi(tuple([240,0,1,106,01,07,21,21,247])) #set all pots to walk mode
		self._send_midi(tuple([240, 0, 1, 106, 1, 6, 127 , 127, 25, 0, 15, 0, 9, PAD_SENSITIVITY, 247]))	#set pads to sensitivity set in Map file
	

	def _setup_transport_control(self):
		self._transport = TransportComponent() 
		self._transport.name = 'Transport'
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (2) #A mixer is one-dimensional; 
		self._mixer = MixerComponent(2, 0, False, False)
		self._mixer.name = 'Mixer'
		self._mixer.tracks_to_use = self._mixer_tracks_to_use(self._mixer)
		self._device_navigator = [None for index in range(2)]
		self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(2):
			self._mixer.channel_strip(index).set_volume_control(self._fader[index])
			self._mixer.channel_strip(index)._on_cf_assign_changed = self._channelstrip_on_cf_assign_changed(self._mixer.channel_strip(index))
			self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			#mixer.track_filter(index).name = 'Mixer_TrackFilter_' + str(index)
			self._mixer.channel_strip(index)._invert_mute_feedback = True
			self._mixer.channel_strip(index)._device_component = self._device[index]
			self._mixer.channel_strip(index).update = self._channelstrip_update(self._mixer.channel_strip(index))
			self._mixer.channel_strip(index)._select_value = self._channelstrip_select_value(self._mixer.channel_strip(index), index)
			self._device_navigator[index] = DetailViewControllerComponent(self, self._mixer.channel_strip(index))
			self._device_navigator[index].name = 'Device_Navigator_'+str(index)
		self._mixer.channel_strip(0).set_track = self._channelstrip_set_track(self._mixer.channel_strip(0), self._channelstrip1_cb)
		self._mixer.channel_strip(1).set_track = self._channelstrip_set_track(self._mixer.channel_strip(1), self._channelstrip2_cb)
		self.song().view.selected_track = self._mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
		#self._mixer._reassign_tracks()
	

	def _setup_session_control(self):
		is_momentary = True
		num_tracks = NUM_TRACKS
		num_scenes = NUM_SCENES
		self._session = SessionComponent(num_tracks, num_scenes)
		self._session.name = "Session"
		self._session.set_offsets(0, 0)	 
		self._session.set_stop_track_clip_value(STOP_CLIP)
		self._scene = [None for index in range(3)]
		for row in range(num_scenes):
			self._scene[row] = self._session.scene(row)
			self._scene[row].name = 'Scene_' + str(row)
			for column in range(num_tracks):
				clip_slot = self._scene[row].clip_slot(column)
				clip_slot.name = str(column) + '_Clip_Slot_' + str(row)
				clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY)
				clip_slot.set_triggered_to_record_value(CLIP_TRG_REC)
				clip_slot.set_stopped_value(CLIP_STOP)
				clip_slot.set_started_value(CLIP_STARTED)
				clip_slot.set_recording_value(CLIP_RECORDING)
		self._session._stop_track_value = self._session_stop_track_value(self._session)
		self._session._on_fired_slot_index_changed = self._session_on_fired_slot_index_changed(self._session)
		self._session._change_offsets = self._session_change_offsets(self._session)
		self._session.update = self._session_update(self._session)
		#self._session.add_offset_listener(self._update_navigation_view)
		self._session.set_mixer(self._mixer)
		self.set_highlighting_session_component(self._session)
		self._session_zoom = SessionZoomingComponent(self._session)	 
		self._session_zoom.name = 'Session_Overview'
		self._session_zoom.set_stopped_value(ZOOM_STOPPED)
		self._session_zoom.set_playing_value(ZOOM_PLAYING)
		self._session_zoom.set_selected_value(ZOOM_SELECTED)
		#self._session_zoom.set_enabled(True)
	

	def _setup_device_control(self):
		self._device = [None for index in range(2)]
		for index in range(2):
			self._device[index] = DeviceComponent()
			self._device[index].name = 'Device_Component_'+str(index)
			self._device[index].set_enabled(True)
			self._device[index]._number_of_parameter_banks = self._device_number_of_parameter_banks(self._device[index])
			self._device[index]._assign_parameters = self._device_assign_parameters(self._device[index])
			self._device[index]._device_banks = DEVICE_DICT
			self._device[index]._device_best_banks = DEVICE_BOB_DICT
			self._device[index]._device_bank_names = BANK_NAME_DICT
	

	def _setup_crossfader(self):
		self._mixer.set_crossfader_control(self._crossfader)
	

	def _setup_modes(self):
		self._pad_offset = PadOffsetComponent(self)
		self._pad_offset._set_protected_mode_index(0)
		self._pad_offset.set_enabled(False)
	

	def _setup_pads(self):
		for pad in self._pad_pressure:
			pad.add_value_listener(self._light_pad, True)
	

	def _setup_navigation_lock(self):
		if(self._encoder_button[0].value_has_listener(self._nav_lock_value)):
			self._encoder_button[0].remove_value_listener(self._nav_lock_value)
		self._encoder_button[0].add_value_listener(self._nav_lock_value)
	

	def _setup_arrange_session_toggle(self):
		if(self._nav[1].value_has_listener(self._arrange_session_value)):
			self._nav[1].remove_value_listener(self._arrange_session_value)
		self._nav[1].add_value_listener(self._arrange_session_value)
	

	"""configuration methods"""
	def assign_main_configuration(self):
		for column in range(7):
			for row in range(3):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		self._session.set_stop_track_clip_buttons(tuple([self._grid[index][3] for index in range(7)]))
		for row in range(3):
			self._scene[row].set_launch_button(self._grid[7][row])
		self._device[0].set_parameter_controls(tuple([self._encoder[index+1] for index in range(3)]))
		self._device[0].set_enabled(True)
		self._device[1].set_parameter_controls(tuple([self._encoder[index+4] for index in range(3)]))
		self._device[1].set_enabled(True)
		for track in range(2):
			self._mixer.channel_strip(track).set_volume_control(self._fader[track])
			self._mixer.channel_strip(track).set_solo_button(self._button[track*3])
			self._button[track*3].set_on_off_values(SOLO, 0)
			self._mixer.channel_strip(track).set_arm_button(self._button[1 + (track*3)])
			self._button[1 + (track*3)].set_on_off_values(ARM, 0)
			self._mixer.channel_strip(track).set_crossfade_toggle(self._button[2 + (track*3)])
		self._mixer.master_strip().set_volume_control(self._dial[1])
		self._mixer.set_prehear_volume_control(self._dial[0])
		self._session.set_track_bank_buttons(self._nav[4], self._nav[3])
		self._session.set_scene_bank_buttons(self._nav[2], self._nav[0])
		self._session_zoom.set_zoom_button(self._grid[7][3])
		self._session_zoom.set_nav_buttons(self._nav[0], self._nav[2], self._nav[3], self._nav[4])
		self._session_zoom.set_button_matrix(self._matrix)
		self._device[0].set_on_off_button(self._encoder_button[1])
		self._device_navigator[0].set_device_nav_buttons(self._encoder_button[2], self._encoder_button[3]) 
		self._device[1].set_on_off_button(self._encoder_button[4])
		self._device_navigator[1].set_device_nav_buttons(self._encoder_button[5], self._encoder_button[6]) 
		for track in range(2):
			self._update_device(self._mixer.channel_strip(track))
		#self._device.set_bank_nav_buttons(self._menu[0], self._menu[3])
		self.assign_track_selector(self._encoder[0])
		#for index in range(8):
		#	self._pad[index].send_value(1, True)
		#	self._pad[index].set_channel(1)
		#	self._pad[index].set_identifier(index)
		#	self._pad[index].set_enabled(False)	 #this has to happen for translate to work
		if not self._grid[7][3].value_has_listener(self._shift_value):
			self._grid[7][3].add_value_listener(self._shift_value)
		self._grid[7][3].send_value(127, True)
		self.request_rebuild_midi_map()	
	

	"""Tweaker custom methods"""
	def _shift_value(self, value):
		self._pad_offset.set_enabled(value>0)
		if value > 0:
			self._update_navigation_view()
			for pad in self._pad:
				pad.use_default_message()
				pad.set_enabled(True)
			self._pad_offset.set_mode_buttons(tuple(self._pad))
			self.schedule_message(1, self._pad_offset.update)
			if self._session.is_enabled():
				#self._update_navigation_view()
				#self.schedule_message(1, self._update_navigation_veiw)
				self._update_navigation_view()
			self._grid[7][3].send_value(SHIFT_ON)
			for track in range(2):
				self._mixer.channel_strip(track).set_crossfade_toggle(None)
				self._mixer.channel_strip(track).set_select_button(self._button[2 + (track*3)])
		else:
			self._pad_offset.set_mode_buttons(None)
			for index in range(4):
				self._pad[index].set_enabled(False)
				self._pad[index].set_channel(PAD_CHANNEL)
				self._pad[index].set_identifier(index + 4 + (self._pad_offset._mode_index * 8))
				self._pad[index+4].set_enabled(False)
				self._pad[index+4].set_channel(PAD_CHANNEL)
				self._pad[index+4].set_identifier(index + (self._pad_offset._mode_index * 8))
			self._grid[7][3].send_value(SHIFT_OFF)
			for track in range(2):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_crossfade_toggle(self._button[2 + (track*3)])
	

	def assign_track_selector(self, encoder):
		assert isinstance(encoder, EncoderElement)
		if not encoder.value_has_listener(self._track_selector_value):
			encoder.add_value_listener(self._track_selector_value)
	

	def deassign_track_selector(self, encoder):
		if encoder.value_has_listener(self._track_selector_value):
			encoder.remove_value_listener(self._track_selector_value)
	

	def _nav_lock_value(self, value):
		if value > 0:
			if self._nav_lock:
				self._mixer_offset = self._mixer_offset + self._session._track_offset
				self._mixer.set_track_offset(self._mixer_offset)
			else:
				if self._mixer_offset in range(self._session._track_offset, self._session._track_offset + 5):
					self._mixer_offset = self._mixer_offset - self._session._track_offset
				elif self._mixer_offset < self._session._track_offset:
					self._mixer_offset = 0
				else:
					self._mixer_offset = min(self._session._track_offset+5, len(self._session.tracks_to_use())-2)
				self._mixer.set_track_offset(self._session._track_offset + self._mixer_offset)
			self._nav_lock = not self._nav_lock
			self._session.update()
	

	def _arrange_session_value(self, value):
		if value > 0:
			if (self.application().view.is_view_visible('Arranger')):
				self.application().view.show_view('Session') 
			else:
				self.application().view.show_view('Arranger')	  
	

	def _track_selector_value(self, value):
		if(value is 1):
			if self._nav_lock:
				self._mixer_offset = min(self._mixer_offset + 1, min(NUM_TRACKS - 2, len(self._session.tracks_to_use())-self._session._track_offset-2))
			else:
				self._mixer_offset = min(self._mixer_offset + 1, len(self._session.tracks_to_use())-2)
		elif(value is 127):
				self._mixer_offset = max(self._mixer_offset - 1, 0)
		if self._nav_lock:
			self._mixer.set_track_offset(self._session._track_offset + self._mixer_offset)
			#self._session.set_offsets(self._session._track_offset)  ??
		else:
			self._mixer.set_track_offset(self._mixer_offset)
		self._session.update()
		if self._mixer.channel_strip(self._last_selected_strip_number)._track != None:
			self.song().view.selected_track = self._mixer.channel_strip(self._last_selected_strip_number)._track
		if self._linked_session != None:
			if self._linked_session._is_linked():
				self._linked_session._unlink()
			self._linked_session.set_offsets(self._mixer._track_offset, self._linked_session._scene_offset)
			self._linked_session._link()
	

	def _update_navigation_view(self):
		dif = self._mixer._track_offset - self._session._track_offset
		for index in range(7):
			#if (index + self._session._track_offset) in range(len(self._session.tracks_to_use())):
			if (index + self._session._track_offset) in range(0, len(self.song().visible_tracks)):
				self._grid[index][3].send_value(NAV_COLORS[int(index in range(dif, dif + 2))], True)
			elif (index + self._session._track_offset) in range(len(self.song().visible_tracks), len(self._session.tracks_to_use())):
				self._grid[index][3].send_value(RETURN_NAV_COLORS[int(index in range(dif, dif + 2))], True)
			else:
				self._grid[index][3].send_value(0, True)
		self._send_midi(tuple([240,0,1,106,01,07,21,21,247])) #set all pots to walk mode
		
	

	def _update_device(self, channelstrip):
		for control in channelstrip._device_component._parameter_controls:
			control.send_value(0, True)
		if channelstrip._device_component._on_off_button != None:
			channelstrip._device_component._on_off_button.turn_off()
		if not channelstrip._track is None:
			if not channelstrip._device_component._device in channelstrip._track.devices:
				track = channelstrip._track
				device_to_select = track.view.selected_device
				if (device_to_select == None) and (len(track.devices) > 0):
					device_to_select = track.devices[0]
				elif channelstrip._device_component and not type(channelstrip._device_component) is type(None):
					channelstrip._device_component.set_device(device_to_select)
				else:
					channelstrip._device_component.set_device(None)	
			else:
				pass
		else:
			channelstrip._device_component.set_device(None)	
		channelstrip._device_component._on_on_off_changed()	
	

	def _light_pad(self, value, sender):
		if not self._pad_offset.is_enabled():
			if value > sender._last_sent:
				if self._pad[self._pad_pressure.index(sender)]._last_sent_value < 1:
					self._pad[self._pad_pressure.index(sender)].send_value(127, True)
			else:
				self._pad[self._pad_pressure.index(sender)].send_value(0, True)
		sender._last_sent = value
	

	"""called on timer"""
	def update_display(self):
		super(Tweaker, self).update_display()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

	def flash(self):
		if(self.flash_status > 0):
			for control in self.controls:
				if isinstance(control, TweakerMonoButtonElement):
					control.flash(self._timer)
	

	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if (not display_string):
			return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
		if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))):
			display_string = display_string[:-2]
		if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)):
					um_pos = display_string.rfind(um, 1)
					display_string = (display_string[:um_pos] + display_string[(um_pos + 1):])
		else:
			display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1))
		ret = u''
		for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)):
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		if(isinstance(sender, MonoEncoderElement2)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

	def touched(self):
		if(self._shift_mode._mode_index < 2):
			if self._touched is 0:
				self._monobridge._send('touch', 'on')
				self.schedule_message(2, self.check_touch)
			self._touched +=1
	

	def check_touch(self):
		if(self._shift_mode._mode_index < 2):
			if self._touched > 5:
				self._touched = 5
			elif self._touched > 0:
				self._touched -= 1
			if self._touched is 0:
				self._monobridge._send('touch', 'off')
			else:
				self.schedule_message(2, self.check_touch)
	

	def	handle_sysex(self, midi_bytes):
		pass
	

	"""general functionality"""
	def disconnect(self):
		"""clean things up on disconnect"""
		#self._update_linked_device_selection = None
		if self._session.offset_has_listener(self._update_navigation_view):
			self._session.remove_offset_listener(self._update_navigation_view)
		if(self._nav[1].value_has_listener(self._arrange_session_value)):
			self._nav[1].remove_value_listener(self._arrange_session_value)
		if(self._encoder_button[0].value_has_listener(self._nav_lock_value)):
			self._encoder_button[0].remove_value_listener(self._nav_lock_value)
		for pad in self._pad_pressure:
			if pad.value_has_listener(self._light_pad):
				pad.remove_value_listener(self._light_pad)
		if self._grid[7][3].value_has_listener(self._shift_value):
			self._grid[7][3].remove_value_listener(self._shift_value)
		if self._session._is_linked():
			self._session._unlink()
		self.deassign_track_selector(self._encoder[0])
		self.log_message("--------------= Tweaker Session " + str(self._tweaker_version_check) + " log closed =--------------") #Create entry in log file
		super(Tweaker, self).disconnect()
		return None
	

	def _get_num_tracks(self):
		return self.num_tracks
	

 	def _on_selected_track_changed(self):
		super(Tweaker, self)._on_selected_track_changed()
		if self._session.is_enabled():
			self._session.update()
		for index in range(2):
			self._update_device(self._mixer.channel_strip(index))
			self._mixer.on_selected_track_changed()
	

	def connect_script_instances(self, instanciated_scripts):
		link = False
		for s in instanciated_scripts:
			if '_tweaker_version' in dir(s):
				if s._tweaker_version == self._tweaker_version_check:
					link = True
					break
		if link == True:
			if not self._session._is_linked():
				self._session._link()
	

	"""SessionComponent overrides"""
	def _session_update(self, session):
		def _update():
			SessionComponent.update(session)
			if session.is_enabled():
				self._update_navigation_view()
		return _update
		
	

	def _session_change_offsets(self, session): 
		def _change_offsets(track_increment, scene_increment):
			offsets_changed = (track_increment != 0) or (scene_increment != 0)
			if offsets_changed:
				session._track_offset += track_increment
				session._scene_offset += scene_increment
				assert (session._track_offset >= 0)
				assert (session._scene_offset >= 0)
				if (session._mixer != None):
					if(self._nav_lock):
						if (session.track_offset() + self._mixer_offset) > (len(session.tracks_to_use())-2):
							self._mixer_offset = max(len(session.tracks_to_use()) - session._track_offset - 2, 0)
						session._mixer.set_track_offset(max(0, session.track_offset() + self._mixer_offset))
			session._reassign_tracks()
			if offsets_changed:
				session._reassign_scenes()
				# this is replaced by notify_offset() in Live9 #for callback in session._offset_callbacks:
				# this is replaced by notify_offset() in Live9 #	callback()
				session.notify_offset()
				self._update_navigation_view()
				if self._mixer.channel_strip(self._last_selected_strip_number)._track != None:
					self.song().view.selected_track = self._mixer.channel_strip(self._last_selected_strip_number)._track
				if ((session.width() > 0) and (session.height() > 0)):
					session._do_show_highlight()
		return _change_offsets
		
	

	def _session_on_fired_slot_index_changed(self, session):
		def _on_fired_slot_index_changed(index):
			tracks_to_use = tuple(self.song().visible_tracks) + tuple(self.song().return_tracks)
			track_index = index + session.track_offset()
			if session.is_enabled() and session._stop_track_clip_buttons != None:
				if index < len(session._stop_track_clip_buttons):
					button = session._stop_track_clip_buttons[index]
					if button != None:
						if(track_index < len(tracks_to_use)) and (tracks_to_use[track_index].clip_slots) and (tracks_to_use[track_index].fired_slot_index == -2):
							button.send_value(session._stop_track_clip_value)
						#elif index in range(len(session.tracks_to_use())):
						#	dif = self._mixer._track_offset - self._session._track_offset
						#	button.send_value(NAV_COLORS[int(index in range(dif, dif + 2))], True)
						#else:
						#	button.turn_off()
						else:
							self._update_navigation_view()
		return _on_fired_slot_index_changed
		
	

	def _session_stop_track_value(self, session):
		def _stop_track_value(value, sender):
			assert (session._stop_track_clip_buttons != None)
			assert (list(session._stop_track_clip_buttons).count(sender) == 1)
			assert (value in range(128))
			if session.is_enabled():
				if ((value is not 0) or (not sender.is_momentary())):
					tracks = session.tracks_to_use()
					track_index = (list(session._stop_track_clip_buttons).index(sender) + session.track_offset())
					if (track_index in range(len(tracks))) and (tracks[track_index] in session.song().tracks):
						tracks[track_index].stop_all_clips()
					sender.send_value(3, True)
					self.schedule_message(10, self._update_navigation_view)
		
		return _stop_track_value
	

	"""ChannelStripComponent overrides"""
	def _channelstrip_update(self, channelstrip):
		def _update():
			ChannelStripComponent.update(channelstrip)
			self._update_device(channelstrip)
		return _update
		
	

	def _channelstrip_set_track(self, channelstrip, cb):
		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)
		return _set_track
		
	

	def _channelstrip_select_value(self, channelstrip, index):  
		def _select_value(value):
			ChannelStripComponent._select_value(channelstrip, value)
			self._last_selected_strip_number = index
		return _select_value
		
	

	def _channelstrip_on_cf_assign_changed(self, channel_strip):
		def _on_cf_assign_changed():
			if (channel_strip.is_enabled() and (channel_strip._crossfade_toggle != None)):
				if (channel_strip._track != None) and (channel_strip._track in chain(self.song().tracks, self.song().return_tracks)):
					if channel_strip._track.mixer_device.crossfade_assign == 1: #modified
						channel_strip._crossfade_toggle.turn_off()
					elif channel_strip._track.mixer_device.crossfade_assign == 0:
						channel_strip._crossfade_toggle.send_value(CROSSFADE_A)
					else:
						channel_strip._crossfade_toggle.send_value(CROSSFADE_B)
		return _on_cf_assign_changed
		
	

	def _channelstrip1_cb(self):
		self._on_selected_track_changed()
	

	def _channelstrip2_cb(self):
		self._on_selected_track_changed()
	

	"""MixerComponent overrides"""
	def _mixer_tracks_to_use(self, mixer):
		def tracks_to_use():
			return tuple(self.song().visible_tracks) + tuple(self.song().return_tracks)
		return tracks_to_use
		
	

	"""SessionComponent overrides"""
	def _device_number_of_parameter_banks(self, device):
		def _number_of_parameter_banks():
			return number_of_parameter_banks(device._device) #added
		return _number_of_parameter_banks
			
	

	def _device_assign_parameters(self, device):
		def _assign_parameters():
			assert device.is_enabled()
			assert (device._device != None)
			assert (device._parameter_controls != None)
			device._bank_name = ('Bank ' + str(device._bank_index + 1)) #added
			if (device._device.class_name in device._device_banks.keys()): #modified
				assert (device._device.class_name in device._device_best_banks.keys())
				banks = device._device_banks[device._device.class_name]
				bank = None
				if (not device._is_banking_enabled()):
					 banks = device._device_best_banks[device._device.class_name]
					 device._bank_name = 'Best of Parameters' #added
				if (len(banks) > device._bank_index):
					bank = banks[device._bank_index]
					if device._is_banking_enabled(): #added
						if device._device.class_name in device._device_bank_names.keys(): #added
							device._bank_name[device._bank_index] = device._device_bank_names[device._device.class_name] #added *recheck
				assert ((bank == None) or (len(bank) >= len(device._parameter_controls)))
				for index in range(len(device._parameter_controls)):
					parameter = None
					if (bank != None):
						parameter = get_parameter_by_name(device._device, bank[index])
					if (parameter != None):
						device._parameter_controls[index].connect_to(parameter)
					else:
						device._parameter_controls[index].release_parameter()
			else:
				parameters = device._device_parameters_to_map()
				num_controls = len(device._parameter_controls)
				index = (device._bank_index * num_controls)
				for control in device._parameter_controls:
					if (index < len(parameters)):
						control.connect_to(parameters[index])
					else:
						control.release_parameter()
					index += 1
		return _assign_parameters
class SoftStep_Single_Clip(ControlSurface):
    __module__ = __name__
    __doc__ = "SoftStep Clip Launching controller script"

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._setup_mixer_control()
            self._setup_session_control()
            #self._setup_channel_strip_control()
            self.set_highlighting_session_component(self.session)

    def _setup_session_control(self):
        num_tracks = 1  #4 columns (tracks)
        num_scenes = 1  #2 rows (scenes)

        #(num_tracks, num_scenes) a session highlight ("red box") will appear with any two non-zero values
        self.session = SoftStepSessionComponent(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_CC_TYPE, CHANNEL, 74),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 73))
        self.session.set_scene_bank_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 72),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 71))
        self.session.set_track_bank_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 75),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 76))
        self.session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 114))
        self.session.set_undo_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 118))
        #self.session.set_stop_all_clips_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 75))

        #here we set up the clip launch assignments for the session

        self.session.scene(0).clip_slot(0).set_started_value(1)
        self.session.scene(0).clip_slot(0).set_stopped_value(0)
        self.session.scene(0).clip_slot(0).set_recording_value(2)
        self.session.scene(0).clip_slot(0).set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 110))

        #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
        self.session.update()

    def _setup_mixer_control(self):
        #A mixer is one-dimensional; here we define the width in tracks
        num_tracks = 1
        #set up the mixer
        self.mixer = MixerComponent(num_tracks, 2)  #(num_tracks, num_returns)
        self.mixer.set_track_offset(
            0)  #sets start point for mixer strip (offset from left)
        #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
        channelstrip = self.mixer.channel_strip(0)
        channelstrip.set_arm_button(
            ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, 21))

    """
  def _setup_channel_strip_control(self):
  	self.channel = ChannelStripComponent()
  
  def _on_selected_track_changed(self):
  	self.channel.set_track(self.song().view.selected_track)
  """

    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()) +
            "----------SoftStep ClipLaunching log closed----------")

        ControlSurface.disconnect(self)
        return None
 def set_track_offset(self, new_offset): #added override
     MixerComponent.set_track_offset(self, new_offset)
     if self._parent._slider_modes != None:
         self._parent._slider_modes.update()
     if self._parent._encoder_modes != None:
         self._parent._encoder_modes.update()          
Beispiel #25
0
class QuNexus_Basic(ControlSurface):
    __module__ = __name__
    __doc__ = "QuNexus Keyboard controller script"

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._setup_mixer_control()
            self._setup_session_control()
            self._setup_device_control()
            self._setup_transport_control()
            self.set_highlighting_session_component(self.session)

    def _setup_transport_control(self):
        self._transport = TransportComponent()
        self._transport.set_stop_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 68))
        self._transport.set_record_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 66))
        self._transport.set_play_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 70))

    def _setup_session_control(self):
        num_tracks = 1  #one column (track)
        num_scenes = 8  #eight rows, which will be mapped to eight "white" notes

        #(num_tracks, num_scenes) a session highlight ("red box") will appear with any two non-zero values
        self.session = QuNexusSessionComponent(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, 63),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61))
        self.session.set_scene_bank_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 51),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 49))
        self.session.set_track_bank_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 56),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 54))

        self.session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 62))
        self.session.set_stop_all_clips_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 58))

        for row in range(num_scenes):
            for col in range(num_tracks):
                self.session.scene(row).clip_slot(col).set_started_value(127)
                self.session.scene(row).clip_slot(col).set_stopped_value(0)

        #here we set up the clip launch assignments for the session
        clip_launch_notes = [48, 50, 52, 53, 55, 57, 59,
                             60]  #set of eight white notes starting at C3/C4
        for index in range(num_scenes):
            #step though scenes and assign a note to first slot of each
            self.session.scene(index).clip_slot(0).set_started_value(127)
            self.session.scene(index).clip_slot(0).set_stopped_value(3)
            self.session.scene(index).clip_slot(0).set_launch_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              clip_launch_notes[index]))
        #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

    def _setup_mixer_control(self):
        #A mixer is one-dimensional; here we define the width in tracks
        num_tracks = 1
        #set up the mixer
        self.mixer = MixerComponent(
            num_tracks, 2, with_eqs=True, with_filters=True
        )  #(num_tracks, num_returns, with_eqs, with_filters)
        self.mixer.set_track_offset(
            0)  #sets start point for mixer strip (offset from left)
        #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
        self.song().view.selected_track = self.mixer.channel_strip(0)._track

    def _setup_device_control(self):
        sliders = []
        pressures = [92, 94, 98, 102, 106, 108]
        for index in range(6):
            sliders.append(
                SliderElement(MIDI_CC_TYPE, CHANNEL, pressures[index]))

        self._sliders = tuple(sliders)
        device = DeviceComponent()
        self.set_device_component(device)
        device.set_parameter_controls(self._sliders)

    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()) +
            "----------QuNexus Basic log closed----------")

        ControlSurface.disconnect(self)
        return None
Beispiel #26
0
class midi_twister_110(ControlSurface):
    def __init__(self, c_instance):
        super(midi_twister_110, self).__init__(c_instance)
        with self.component_guard():
            global active_mode
            active_mode = "_mode1"
            self._set_active_mode()
            self.show_message("Modified by XXPW")

    def _mode1(self):
        self.show_message("_mode1 is active")
        # mixer
        global mixer
        num_tracks = 32
        num_returns = 7
        self.mixer = MixerComponent(num_tracks, num_returns)
        self.mixer.set_track_offset(0)
        self.song().view.selected_track = self.mixer.channel_strip(0)._track
        # sends
        send0_controls = (
            SliderElement(MIDI_CC_TYPE, 0, 32),
            SliderElement(MIDI_CC_TYPE, 0, 36),
            SliderElement(MIDI_CC_TYPE, 0, 40),
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(0).set_send_controls(tuple(send0_controls))
        self.mixer.channel_strip(0).set_volume_control(
            SliderElement(MIDI_CC_TYPE, 0, 44))
        send1_controls = (
            SliderElement(MIDI_CC_TYPE, 0, 33),
            SliderElement(MIDI_CC_TYPE, 0, 37),
            SliderElement(MIDI_CC_TYPE, 0, 41),
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(1).set_send_controls(tuple(send1_controls))
        self.mixer.channel_strip(1).set_volume_control(
            SliderElement(MIDI_CC_TYPE, 0, 45))

        send2_controls = (
            SliderElement(MIDI_CC_TYPE, 0, 34),
            SliderElement(MIDI_CC_TYPE, 0, 38),
            SliderElement(MIDI_CC_TYPE, 0, 42),
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(2).set_send_controls(tuple(send2_controls))
        self.mixer.channel_strip(2).set_volume_control(
            SliderElement(MIDI_CC_TYPE, 0, 46))
        send3_controls = (
            SliderElement(MIDI_CC_TYPE, 0, 35),
            SliderElement(MIDI_CC_TYPE, 0, 39),
            SliderElement(MIDI_CC_TYPE, 0, 43),
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(3).set_send_controls(tuple(send3_controls))
        self.mixer.channel_strip(3).set_volume_control(
            SliderElement(MIDI_CC_TYPE, 0, 47))
        # session
        global _session
        num_tracks = 4
        num_scenes = 3
        session_buttons = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
        self._pads = [
            ButtonElement(1, MIDI_CC_TYPE, 1, session_buttons[index])
            for index in range(num_tracks * num_scenes)
        ]
        self._grid = ButtonMatrixElement(rows=[
            self._pads[(index * num_tracks):(index * num_tracks) + num_tracks]
            for index in range(num_scenes)
        ])
        self._session = SessionComponent(num_tracks, num_scenes)
        self._session.set_clip_launch_buttons(self._grid)
        self.set_highlighting_session_component(self._session)
        # session track stop
        stop_track_buttons = [12, 13, 14, 15]
        self._track_stop_buttons = [
            ButtonElement(1, MIDI_CC_TYPE, 1, stop_track_buttons[index])
            for index in range(num_tracks)
        ]
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        # session navigation
        self.session_left = ButtonElement(1, MIDI_CC_TYPE, 3, 8)
        self._session.set_page_left_button(self.session_left)
        self.session_left.add_value_listener(self._reload_active_devices,
                                             identify_sender=False)
        self.session_right = ButtonElement(1, MIDI_CC_TYPE, 3, 11)
        self._session.set_page_right_button(self.session_right)
        self.session_right.add_value_listener(self._reload_active_devices,
                                              identify_sender=False)
        self.session_up = ButtonElement(1, MIDI_CC_TYPE, 3, 10)
        self._session.set_page_up_button(self.session_up)
        self.session_up.add_value_listener(self._reload_active_devices,
                                           identify_sender=False)
        self.session_down = ButtonElement(1, MIDI_CC_TYPE, 3, 13)
        self._session.set_page_down_button(self.session_down)
        self.session_down.add_value_listener(self._reload_active_devices,
                                             identify_sender=False)
        self._session._link()
        self._session.set_mixer(self.mixer)
        #self._session.set_mixer(self.mixer)
        self._mode1_devices()
        self.add_device_listeners()
        # button: next device
        self.next_device = ButtonElement(0, MIDI_CC_TYPE, 1, 25)
        self.next_device.add_value_listener(self._next_device_value,
                                            identify_sender=False)
        # button: prev device
        self.previous_device = ButtonElement(1, MIDI_CC_TYPE, 1, 24)
        self.previous_device.add_value_listener(self._prev_device_value,
                                                identify_sender=False)
        # transport
        global transport
        self.transport = TransportComponent()
        self.transport.name = 'Transport'
        loop_button = ButtonElement(1, MIDI_CC_TYPE, 1, 50)
        loop_button.name = 'loop_button'
        self.transport.set_loop_button(loop_button)
        stop_button = ButtonElement(1, MIDI_CC_TYPE, 1, 49)
        stop_button.name = 'stop_button'
        self.transport.set_stop_button(stop_button)
        play_button = ButtonElement(1, MIDI_CC_TYPE, 1, 48)
        play_button.name = 'play_button'
        self.transport.set_play_button(play_button)
        # button: track navigation right
        self.track_navigation_right = ButtonElement(1, MIDI_CC_TYPE, 3, 17)
        self.track_navigation_right.add_value_listener(
            self._track_navigation_right_track_nav, identify_sender=False)
        # button: track navigation left
        self.track_navigation_left = ButtonElement(1, MIDI_CC_TYPE, 3, 14)
        self.track_navigation_left.add_value_listener(
            self._track_navigation_left_track_nav, identify_sender=False)

    def _remove_mode1(self):
        # mixer
        global mixer
        self._remove_mode1_devices()
        self.remove_device_listeners()
        send0_controls = (
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(0).set_send_controls(tuple(send0_controls))
        send1_controls = (
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(1).set_send_controls(tuple(send1_controls))
        send2_controls = (
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(2).set_send_controls(tuple(send2_controls))
        send3_controls = (
            None,
            None,
            None,
            None,
            None,
            None,
            None,
            None,
        )
        self.mixer.channel_strip(3).set_send_controls(tuple(send3_controls))
        # session
        global _session
        self._session.set_clip_launch_buttons(None)
        self.set_highlighting_session_component(None)
        self._session.set_mixer(None)
        self._session.set_stop_all_clips_button(None)
        # session track stop
        self._track_stop_buttons = None
        self._session.set_stop_track_clip_buttons(None)
        # session scene launch
        self._scene_launch_buttons = None
        self._session.set_scene_launch_buttons(None)
        # session navigation
        self.session_left.remove_value_listener(self._reload_active_devices)
        self._session.set_page_left_button(None)
        self.session_right.remove_value_listener(self._reload_active_devices)
        self._session.set_page_right_button(None)
        self.session_up.remove_value_listener(self._reload_active_devices)
        self._session.set_page_up_button(None)
        self.session_down.remove_value_listener(self._reload_active_devices)
        self._session.set_page_down_button(None)
        self._session = None
        self.next_device.remove_value_listener(self._next_device_value)
        self.next_device = None
        self.previous_device.remove_value_listener(self._prev_device_value)
        self.previous_device = None
        # transport
        global transport
        self.transport.set_loop_button(None)
        self.transport.set_stop_button(None)
        self.transport.set_play_button(None)
        self.transport = None
        self.track_navigation_right.remove_value_listener(
            self._track_navigation_right_track_nav)
        self.track_navigation_right = None
        self.track_navigation_left.remove_value_listener(
            self._track_navigation_left_track_nav)
        self.track_navigation_left = None

    def _mode1_devices(self):
        global mixer
        global _session
        # device
        self.mixer.selected_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, 0, 28))
        self.mixer.selected_strip().set_pan_control(
            SliderElement(MIDI_CC_TYPE, 0, 29))
        self.mixer.selected_strip().set_mute_button(
            ButtonElement(1, MIDI_CC_TYPE, 1, 28))
        self.mixer.selected_strip().set_solo_button(
            ButtonElement(1, MIDI_CC_TYPE, 1, 29))

        if (len(self.mixer.selected_strip()._track.devices) > 0):
            global device_tracktype_selected__chain_number_selected
            self.device_tracktype_selected__chain_number_selected = DeviceComponent(
            )
            device_controls = (
                SliderElement(MIDI_CC_TYPE, 0, 16),
                SliderElement(MIDI_CC_TYPE, 0, 17),
                SliderElement(MIDI_CC_TYPE, 0, 18),
                SliderElement(MIDI_CC_TYPE, 0, 19),
                SliderElement(MIDI_CC_TYPE, 0, 20),
                SliderElement(MIDI_CC_TYPE, 0, 21),
                SliderElement(MIDI_CC_TYPE, 0, 22),
                SliderElement(MIDI_CC_TYPE, 0, 23),
            )
            self.device_tracktype_selected__chain_number_selected.set_parameter_controls(
                tuple(device_controls))
            self.set_device_component(
                self.device_tracktype_selected__chain_number_selected)
            self.device_tracktype_selected__chain_number_selected.set_on_off_button(
                ButtonElement(1, MIDI_CC_TYPE, 1, 26))
            self.device_tracktype_selected__chain_number_selected.set_bank_nav_buttons(
                ButtonElement(0, MIDI_CC_TYPE, 1, 31),
                ButtonElement(1, MIDI_CC_TYPE, 1, 33))

    def _remove_mode1_devices(self):
        global mixer
        global _session
        # device
        if (hasattr(self, 'device_tracktype_selected__chain_number_selected')):
            global device_tracktype_selected__chain_number_selected
            device_controls = (
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
            )
            self.device_tracktype_selected__chain_number_selected.set_parameter_controls(
                tuple(device_controls))
            self.device_tracktype_selected__chain_number_selected.set_on_off_button(
                None)
            self.device_tracktype_selected__chain_number_selected.set_bank_nav_buttons(
                None, None)
            self.set_device_component(
                self.device_tracktype_selected__chain_number_selected)

    def add_device_listeners(self):
        global mixer
        num_of_tracks = len(self.song().tracks)
        value = "add device listener"
        for index in range(num_of_tracks):
            self.song().tracks[index].add_devices_listener(
                self._reload_active_devices)

    def remove_device_listeners(self):
        global mixer
        num_of_tracks = len(self.song().tracks)
        value = "remove device listener"
        for index in range(num_of_tracks):
            self.song().tracks[index].remove_devices_listener(
                self._reload_active_devices)

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._display_reset_delay = 0
        value = "selected track changed"
        self._reload_active_devices(value)

    def _reload_active_devices(self, value=None):
        self._remove_active_devices()
        self._set_active_devices()

    def _set_active_devices(self):
        global active_mode
        # activate mode
        if (active_mode == "_mode1") and (hasattr(self, '_mode1_devices')):
            self._mode1_devices()

    def _remove_active_devices(self):
        global active_mode
        # remove activate mode
        if (active_mode == "_mode1") and (hasattr(self, '_mode1_devices')):
            self._remove_mode1_devices()

    def _next_device_value(self, value):
        if value > 0:
            self._device = self.song().view.selected_track.view.selected_device
            if self._device is not None:
                self.song().view.select_device(
                    self.song().view.selected_track.devices[
                        self.selected_device_idx() + 1])

    def _prev_device_value(self, value):
        if value > 0:
            self._device = self.song().view.selected_track.view.selected_device
            if self._device is not None:
                self.song().view.select_device(
                    self.song().view.selected_track.devices[
                        self.selected_device_idx() - 1])

    def selected_device_idx(self):
        self._device = self.song().view.selected_track.view.selected_device
        return self.tuple_index(self.song().view.selected_track.devices,
                                self._device)

    def _track_navigation_right_track_nav(self, value):
        if value > 0:
            self.song().view.selected_track = self.song().tracks[
                self.selected_track_idx() + 1]

    def _track_navigation_left_track_nav(self, value):
        if value > 0:
            self.song().view.selected_track = self.song().tracks[
                self.selected_track_idx() - 1]

    def selected_track_idx(self):
        return self.tuple_index(self.song().tracks,
                                self.song().view.selected_track)

    def _set_active_mode(self):
        global active_mode
        # activate mode
        if active_mode == "_mode1":
            self._mode1()

    def _remove_active_mode(self):
        global active_mode
        # remove activate mode
        if active_mode == "_mode1":
            self._remove_mode1()

    def _activate_mode1(self, value):
        global active_mode
        if value > 0:
            self._remove_active_mode()
            active_mode = "_mode1"
            self._set_active_mode()

    def _activate_shift_mode1(self, value):
        global active_mode
        if value > 0:
            self._remove_active_mode()
            self._mode1()
        else:
            self._remove_mode1()
            self._set_active_mode()

    def tuple_index(self, tuple, obj):
        for i in xrange(0, len(tuple)):
            if (tuple[i] == obj):
                return i
        return (False)

    def disconnect(self):
        super(midi_twister_110, self).disconnect()
Beispiel #27
0
class LinkedCode(ControlSurface):
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._reset()
        # turn off rebuild MIDI map until after setup
        self.set_suppress_rebuild_requests(True)
        self._create_buttons()
        self._create_encoders()
        self._create_device_components()
        self._setup_mixer_control()
        self._setup_transport_control()
        self._setup_session_control()
        self._setup_mode_selector_control()
        self.set_suppress_rebuild_requests(False)

    def _reset(self):
        self._send_midi(FactoryReset)
        self._send_midi(ButtonMap)
        # self._send_midi(EncosionMap1);
        self._send_midi(ButtonChannelMap)
        self._send_midi(EncoderChannelMap)

    def _create_mode_buttons(self):
        self.mode_buttons = []
        for i in range(MODES):
            self.mode_buttons.append(
                ButtonElement(True, MIDI_NOTE_TYPE, CHAN,
                              SIDE_BUTTONS_NOTES[MODES - 1 - i]))

    def _create_buttons(self):
        self._buttons = []
        for row in (ROW1_BUTTON_NOTES, ROW2_BUTTON_NOTES, ROW3_BUTTON_NOTES,
                    ROW4_BUTTON_NOTES, BOTTOM_BUTTONS_NOTES):
            for n in row:
                self._buttons.append(
                    ButtonElement(True, MIDI_NOTE_TYPE, CHAN, n))

    def _create_encoders(self):
        # hack, placeholder control so we can get to arbitrary parameters
        # in a device
        self._dummy_encoder = EncoderElement(MIDI_CC_TYPE, CHAN + 1, 0x7f,
                                             Live.MidiMap.MapMode.absolute)
        self._encoders = []
        self._sliders = []
        for row in (ROW1_ENCODERS_CCS, ROW2_ENCODERS_CCS, ROW3_ENCODERS_CCS,
                    ROW4_ENCODERS_CCS):
            for n in row:
                self._encoders.append(
                    EncoderElement(MIDI_CC_TYPE, CHAN, n,
                                   Live.MidiMap.MapMode.absolute))
                self._sliders.append(SliderElement(MIDI_CC_TYPE, CHAN, n))
        # make a relative encoder.  currently not in use, since causes an error when such an encoder is assigned to anything
        #self._encoders.append(EncoderElement(MIDI_CC_TYPE, CHAN, ROW1_ENCODERS_CCS[7], Live.MidiMap.MapMode.relative_two_compliment))

    def _create_device_components(self):
        self._create_return_devices()
        self._create_selected_device()
        self._create_device_view_controls()

    def _create_return_devices(self):
        self._device_returns = []
        for track in self.song().return_tracks:
            device = DeviceComponent()
            try:
                device.set_device(track.devices[0])
            except:
                self.log_message("no devices on return track")
            self._device_returns.append(device)
            if len(self._device_returns) == 2:
                break

    def _create_selected_device(self):
        self._device_selected = DeviceComponent()
        self.set_device_component(self._device_selected)

    def _create_device_view_controls(self):
        self._detail_view_control = DetailViewCntrlComponent()

    def _setup_mode_selector_control(self):
        self._create_mode_buttons()
        self._last_mode = -1
        self._unmap_mode_callbacks = (self._unmap_mode_0, self._unmap_mode_1,
                                      self._unmap_mode_2, self._unmap_mode_3)
        self._map_mode_callbacks = (self._map_mode_0, self._map_mode_1,
                                    self._map_mode_2, self._map_mode_3)
        self.mode_selector = ModeSelectorComponent2(MODES)
        self.mode_selector.add_mode_index_listener(self._mode_changed)
        # call this last because setting the mode buttons sets the default mode
        self.mode_selector.set_mode_buttons(tuple(self.mode_buttons))

    def _mode_changed(self):
        if self.mode_selector.mode_index == 3:
            self._unmap_session_buttons()
        if self._last_mode != -1:
            self._unmap_mode_callbacks[self._last_mode]()
        self._map_mode_callbacks[self.mode_selector.mode_index]()
        if self._last_mode == -1 or self._last_mode == 3:
            self._map_session_buttons()
        self._last_mode = self.mode_selector.mode_index

    def _map_session_buttons(self):
        for i in range(MIXER_TRACKS):
            self.mixer.channel_strip(i).set_invert_mute_feedback(True)
            self.mixer.channel_strip(i).set_mute_button(self._buttons[4 * 8 +
                                                                      i])
            self.mixer.channel_strip(i).set_select_button(self._buttons[3 * 8 +
                                                                        i])
            self.mixer.channel_strip(i).set_arm_button(self._buttons[2 * 8 +
                                                                     i])
            self.mixer.channel_strip(i).set_solo_button(self._buttons[8 + i])
        stop_track_buttons = []
        for i in range(SESSION_TRACKS):
            stop_track_buttons.append(self._buttons[i])
        self.session.set_stop_track_clip_buttons(
            tuple(stop_track_buttons))  #array size needs to match num_tracks

    def _unmap_session_buttons(self):
        for i in range(MIXER_TRACKS):
            self.mixer.channel_strip(i).set_mute_button(None)
            self.mixer.channel_strip(i).set_select_button(None)
            self.mixer.channel_strip(i).set_arm_button(None)
            self.mixer.channel_strip(i).set_solo_button(None)
        self.session.set_stop_track_clip_buttons(
            None)  #array size needs to match num_tracks

    def _map_mode_0(self):
        self.log_message("+ mode 1")
        for i in range(MIXER_TRACKS):
            self.mixer.channel_strip(i).set_volume_control(
                self._sliders[3 * 8 + i])
            self.mixer.channel_strip(i).set_send_controls(
                (self._encoders[2 * 8 + i], self._encoders[8 + i],
                 self._encoders[i]))
            # or...
            # self.mixer.channel_strip(i).set_pan_control(self._encoders[2 * 8 + i])
            # self.mixer.channel_strip(i).set_send_controls((self._encoders[8 + i], self._encoders[i]))

    def _unmap_mode_0(self):
        self.log_message("- mode 1")
        for i in range(MIXER_TRACKS):
            self.mixer.channel_strip(i).set_volume_control(None)
            # self.mixer.channel_strip(i).set_pan_control(None)
            self.mixer.channel_strip(i).set_send_controls(None)

    def _map_mode_1(self):
        self.log_message("+ mode 2")
        for i in range(SESSION_TRACKS):
            self.session.device(i).set_parameter_controls(
                (self._encoders[3 * 8 + i], self._encoders[2 * 8 + i],
                 self._encoders[8 + i], self._encoders[i]))

    def _unmap_mode_1(self):
        self.log_message("- mode 2")
        for i in range(SESSION_TRACKS):
            self.session.device(i).set_parameter_controls(())

    def _map_mode_2(self):
        self.log_message("+ mode 3")
        for i in range(SESSION_TRACKS):
            self.session.device(i).set_parameter_controls(
                (self._dummy_encoder, self._dummy_encoder, self._dummy_encoder,
                 self._dummy_encoder, self._encoders[3 * 8 + i],
                 self._encoders[2 * 8 + i], self._encoders[8 + i],
                 self._encoders[i]))

    def _unmap_mode_2(self):
        self.log_message("- mode 3")
        for i in range(SESSION_TRACKS):
            self.session.device(i).set_parameter_controls(())

    def _map_mode_3(self):
        self.log_message("+ mode 4")
        # self._send_midi(EncosionMap2);
        for i in range(
                len(self._device_returns
                    )):  # maybe this should be 2, instead of all returns? - LD
            self._device_returns[i].set_parameter_controls(
                (self._encoders[3 * 8 + i * 2], self._encoders[2 * 8 + i * 2],
                 self._encoders[8 + i * 2], self._encoders[i * 2],
                 self._encoders[3 * 8 + i * 2 + 1],
                 self._encoders[2 * 8 + i * 2 + 1],
                 self._encoders[8 + i * 2 + 1], self._encoders[i * 2 + 1]))
        self._device_selected.set_parameter_controls(
            (self._encoders[3 * 8 + 2 * 2], self._encoders[2 * 8 + 2 * 2],
             self._encoders[8 + 2 * 2], self._encoders[2 * 2],
             self._encoders[3 * 8 + 2 * 2 + 1],
             self._encoders[2 * 8 + 2 * 2 + 1], self._encoders[8 + 2 * 2 + 1],
             self._encoders[2 * 2 + 1]))
        self._device_selected.set_on_off_button(self._buttons[2 * 8 + 5])
        self._detail_view_control.set_device_clip_toggle_button(
            self._buttons[4 * 8 + 4])
        self._detail_view_control.set_detail_toggle_button(
            self._buttons[4 * 8 + 5])
        self._detail_view_control.set_device_nav_buttons(
            self._buttons[3 * 8 + 4], self._buttons[3 * 8 + 5])
        for i in range(4):
            self.mixer.return_strip(i).set_volume_control(
                self._sliders[(3 - i) * 8 + 6])
        for i in range(RETURN_TRACKS):
            self.mixer.return_strip(i).set_invert_mute_feedback(True)
            self.mixer.return_strip(i).set_select_button(self._buttons[4 * 8 +
                                                                       i])
            self.mixer.return_strip(i).set_mute_button(self._buttons[3 * 8 +
                                                                     i])
        self.mixer.master_strip().set_select_button(self._buttons[4 * 8 + 7])
        self.mixer.master_strip().set_volume_control(self._sliders[3 * 8 + 7])
        self.mixer.set_prehear_volume_control(self._sliders[2 * 8 + 7])
        self._transport.set_record_button(self._buttons[3 * 8 + 6])
        self._transport.set_play_button(self._buttons[3 * 8 + 7])
        self._transport.set_stop_button(self._buttons[2 * 8 + 7])
        self._transport.set_nudge_buttons(self._buttons[8 + 7],
                                          self._buttons[8 + 6])
        self._transport.set_tap_tempo_button(self._buttons[4 * 8 + 6])
        self._transport.set_tempo_control(self._encoders[7],
                                          self._encoders[15])
        self.session.set_stop_all_clips_button(self._buttons[2 * 8 + 6])
        self._transport.set_metronome_button(self._buttons[0 * 8 + 6])
        self._transport.set_overdub_button(self._buttons[0 * 8 + 7])

    def _unmap_mode_3(self):
        self.log_message("- mode 4")
        # self._send_midi(EncosionMap1);
        for i in range(len(self._device_returns)):
            self._device_returns[i].set_parameter_controls(())
        self._device_selected.set_parameter_controls(())
        self._device_selected.set_on_off_button(None)
        self._detail_view_control.set_device_clip_toggle_button(None)
        self._detail_view_control.set_detail_toggle_button(None)
        self._detail_view_control.set_device_nav_buttons(None, None)
        for i in range(4):
            self.mixer.return_strip(i).set_volume_control(None)
        for i in range(RETURN_TRACKS):
            self.mixer.return_strip(i).set_select_button(None)
            self.mixer.return_strip(i).set_mute_button(None)
        self.mixer.master_strip().set_select_button(None)
        self.mixer.master_strip().set_volume_control(None)
        self._transport.set_record_button(None)
        self._transport.set_play_button(None)
        self._transport.set_stop_button(None)
        self._transport.set_nudge_buttons(None, None)
        self._transport.set_tap_tempo_button(None)
        self._transport.set_tempo_control(None, None)
        self.session.set_stop_all_clips_button(None)
        self.mixer.set_prehear_volume_control(None)
        self._transport.set_metronome_button(None)
        self._transport.set_overdub_button(None)

    def _setup_mixer_control(self):
        # MixerComponent(num_tracks, num_returns, ...)
        self.mixer = MixerComponent(MIXER_TRACKS,
                                    RETURN_TRACKS,
                                    with_eqs=True,
                                    with_filters=False)
        self.mixer.set_track_offset(0)

    def _setup_transport_control(self):
        self._transport = TransportComponent()

    def _setup_session_control(self):
        self.session = SessionComponent2(SESSION_TRACKS, SESSION_SCENES, self)
        self.session.name = "Session_Control"
        self.session.set_mixer(self.mixer)
        self.session._link()

    def disconnect(self):
        if self.session and self.session._is_linked():
            self.session._unlink()
        ControlSurface.disconnect(self)
Beispiel #28
0
class AumTroll_G(AumTroll):


	def __init__(self, *a, **k):
		super(AumTroll_G, self).__init__(*a, **k)
		with self.component_guard():
			self._setup_session_recording_component()
			self._setup_APC_detail_component()
		self.log_message('Aumtroll G 4')
	


	def _setup_session_recording_component(self):
		self._recorder = SessionRecordingComponent(ClipCreator(), ViewControlComponent())
	

	def _setup_APC_detail_component(self):
		self._alt_device_navigator = DetailViewCntrlComponent()
	
	"""the mixer component corresponds and moves with our selection in Live, and allows us to assign physical controls"""
	"""to Live's mixer functions without having to make all the links ourselves"""
	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (8) 								#A mixer is one-dimensional; 
		self._mixer = MixerComponent(8, 2, True, False)		#These values represent the (Number_of_tracks, Number_of_returns, EQ_component, Filter_component)
		self._mixer.name = 'Mixer'							#We name everything that we might want to access in m4l
		self._mixer.set_track_offset(0) 					#Sets start point for mixer strip (offset from left)
		for index in range(8):								
			#self._mixer.channel_strip(index).set_volume_control(self._fader[index])		#Since we gave our mixer 4 tracks above, we'll now assign our fader controls to it						
			self._mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)	#We also name the individual channel_strip so we can access it
			self._mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)					#We also name the individual EQ_component so we can access it
			self._mixer.channel_strip(index)._invert_mute_feedback = True				#This makes it so that when a track is muted, the corresponding button is turned off
		self.song().view.selected_track = self._mixer.channel_strip(0)._track 			#set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
		self._send_reset = ResetSendsComponent(self)		#This creates a custom MonoComponent that allows us to reset all the sends on a track to zero with a single button
		self._send_reset.name = 'Sends_Reset'				#We name it so that we can access it from m4l
	

	"""the session component represents a grid of buttons that can be used to fire, stop, and navigate clips in the session view"""
	def _setup_session_control(self):
		is_momentary = True
		num_tracks = 8															#we are working with a 4x4 grid,	
		num_scenes = 4 															#so the height and width are both set to 4
		self._session = SessionComponent(num_tracks, num_scenes)				#we create our SessionComponent with the variables we set above it
		self._session.name = "Session"											#we name it so we can access it in m4l
		self._session.set_offsets(0, 0)											#we set the initial offset to the far left, top of the session grid
		self._session._track_banking_increment = 4
		self._session.set_stop_clip_value(STOP_CLIP[self._rgb])			#we assign the colors that will be displayed when the stop_clip button is pressed. This value comes from CNTRLR_Map.py, which is imported in the header of our script
		self._scene = [None for index in range(4)]								#we create an array to hold the Scene subcomponents so that we can get to them if we need them.
		for row in range(num_scenes):											#now we'll fill the array with different objects that were created when we called the SessionComponent() module
			self._scene[row] = self._session.scene(row)							#each session row is a SceneComponent
			self._scene[row].name = 'Scene_' + str(row)							#name it so we can access it in m4l
			for column in range(num_tracks):									#now we'll create holders and names for the contents of each scene
				clip_slot = self._scene[row].clip_slot(column)					#we use our assignment of the scene above to gain access to the individual clipslots.  Here, we are just assigning 'clip_slot' each time as a local variable so we can manipulated it's properties
				clip_slot.name = str(column) + '_Clip_Slot' + str(row)			#name it so that we can acces it in m4l
				clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY[self._rgb])	#set its triggered to play color
				clip_slot.set_triggered_to_record_value(CLIP_TRG_REC[self._rgb])#set its triggered to record color
				clip_slot.set_stopped_value(CLIP_STOP[self._rgb])				#set its stop color
				clip_slot.set_started_value(CLIP_STARTED[self._rgb])			#set its started color
				clip_slot.set_recording_value(CLIP_RECORDING[self._rgb])		#set its recording value
		self._session.set_mixer(self._mixer)									#now we link the MixerComponent we created in _setup_mixer_control() to our session component so that they will follow each other when either is navigated
		self.set_highlighting_session_component(self._session)
		self._session_zoom = SessionZoomingComponent(self._session)	 			#this creates the ZoomingComponent that allows navigation when the shift button is pressed
		self._session_zoom.name = 'Session_Overview'							#name it so we can access it in m4l
		self._session_zoom.set_stopped_value(ZOOM_STOPPED[self._rgb])			#set the zooms stopped color
		self._session_zoom.set_playing_value(ZOOM_PLAYING[self._rgb])			#set the zooms playing color
		self._session_zoom.set_selected_value(ZOOM_SELECTED[self._rgb])			#set the zooms selected color
		self._session_zoom.set_button_matrix(self._matrix)						#assign the ButtonMatrixElement that we created in _setup_controls() to the zooming component so that we can control it
		self._session_zoom.set_zoom_button(self._button[31])					#assign a shift button so that we can switch states between the SessionComponent and the SessionZoomingComponent
	

	"""this section is used so that we can reassign the color properties of each state.  Legacy, from the OhmModes script, to support either RGB or Monochrome"""
	def _assign_session_colors(self):
		num_tracks = 8
		num_scenes = 4 
		self._session.set_stop_clip_value(STOP_ALL[self._rgb])
		for row in range(num_scenes): 
			for column in range(num_tracks):
				self._scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRG_PLAY[self._rgb])
				self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRG_REC[self._rgb])
				self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOP[self._rgb])
				self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED[self._rgb])
				self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING[self._rgb])		
		self._session_zoom.set_stopped_value(ZOOM_STOPPED[self._rgb])
		self._session_zoom.set_playing_value(ZOOM_PLAYING[self._rgb])
		self._session_zoom.set_selected_value(ZOOM_SELECTED[self._rgb])
		self.refresh_state()
	

	def deassign_live_controls(self, *a, **k):
		for index in range(4):
			self._encoder[index].send_value(0, True)
			self._encoder[index].clear_send_cache()							
			self._mixer.channel_strip(index+4).set_volume_control(None)		#Since we gave our mixer 4 tracks above, we'll now assign our fader controls to it																#for the left side of the mixer
			self._mixer.channel_strip(index+4).set_solo_button(None)		#remove the solo button assignments
			self._mixer.channel_strip(index+4).set_arm_button(None)		#remove the arm button assignments
			self._mixer.channel_strip(index+4).set_mute_button(None)		#remove the mute button assignments
			self._mixer.channel_strip(index+4).set_select_button(None)	#remove the select button assignments
		#self._alt_device_navigator.set_arrange_session_toggle_button(None)
		self._alt_device_navigator.set_device_clip_toggle_button(None)
		self._alt_device_navigator.set_detail_toggle_button(None)
		self._alt_device_navigator.set_enabled(False)
		#self._alt_device_navigator.set_shift_button(None)
		self._transport.set_nudge_buttons(None, None)
		self._recorder.set_record_button(None)
		self._recorder.set_re_enable_automation_button(None)
		
		super(AumTroll_G, self).deassign_live_controls(*a, **k)
	


	def assign_live_controls(self):
		"""the following lines update all of the controls' last_sent properties, so that they forward the next value they receive regardless of whether or not it is the same as the last it recieved"""
		"""we also reset the encoder rings and buttons, since the device component will not update them if it is not locked to a device in Live"""
		for index in range(16):
			self._grid[index].force_next_send()
		for index in range(32):
			#self._button[index].set_on_off_values(0, 127)
			self._button[index].send_value(0, True)
			self._button[index].force_next_send()
		for index in range(8):
			self._encoder_button[index+4].send_value(0, True)
			self._encoder_button[index+4].force_next_send()
		for index in range(12):
			self._encoder[index].send_value(0, True)
			self._encoder[index].force_next_send()

		"""here we assign the left side of our mixer's buttons on the lower 32 keys"""
		if self._monohm is None:
			with self.component_guard():
				for index in range(4):															#we set up a recursive loop to assign all four of our track channel strips' controls
					self._button[index+16].set_on_value(MUTE[self._rgb])						#set the mute color from the Map.py
					self._mixer.channel_strip(index).set_mute_button(self._button[index+16])	#assign the mute buttons to our mixer channel strips
					self._button[index+28].set_on_value(MUTE[self._rgb])						#set the mute color from the Map.py
					self._mixer.channel_strip(index+4).set_mute_button(self._button[index+28])	#assign the mute buttons to our mixer channel strips

					self._button[index].set_on_off_values(SELECT[self._rgb], SELECT_OFF[self._rgb])
					self._mixer.channel_strip(index).set_select_button(self._button[index])	#assign the select buttons to our mixer channel strips
					self._button[index+12].set_on_off_values(SELECT[self._rgb], SELECT_OFF[self._rgb])	#set the select color from the Map.py
					self._mixer.channel_strip(index+4).set_select_button(self._button[index+12])	#assign the select buttons to our mixer channel strips

				#self._session.set_stop_track_clip_buttons(tuple(self._button[index+4] for index in range(8)))	#these last two lines assign the send_reset buttons and the stop_clip buttons for each track
				for index in range(8):
					#self._button[index + 4].set_on_off_values(SOLO[self._rgb], SOLO[self._rgb])	#this assigns the custom colors defined in the Map.py file to the stop_clip buttons.  They have seperate on/off values, but we assign them both the same value so we can always identify them
					self._mixer.channel_strip(index).set_solo_button(self._button[index+4])
					#self._button[index + 4].send_value(STOP_CLIP[self._rgb], True)				#finally, we send the on/off colors out to turn the LEDs on for the stop clip buttons
				for index in range(4):															#set up a for loop to generate an index for assigning the session nav buttons' colors
					self._button[index + 20].set_on_off_values(SESSION_NAV[self._rgb], SESSION_NAV_OFF[self._rgb])	#assign the colors from Map.py to the session nav buttons
				self._session.set_track_bank_buttons(self._button[21], self._button[20])		#set the track bank buttons for the Session navigation controls
				self._session.set_scene_bank_buttons(self._button[23], self._button[22])		#set the scnee bank buttons for the Session navigation controls

				"""this section assigns the grid to the clip launch functionality of the SessionComponent"""
				for column in range(4):															#we need to set up a double recursion so that we can generate the indexes needed to assign the grid buttons
					for row in range(4):														#the first recursion passes the column index, the second the row index
						self._scene[row].clip_slot(column).set_launch_button(self._grid[(row*4)+column])	#we use the indexes to grab the first the scene and then the clip we assigned above, and then we use them again to define the button held in the grid array that we want to assign to the clip slot from the session component

				for index in range(4):															#set up a for loop to generate an index for assigning the session nav buttons' colors
					self._button[index + 24].set_on_off_values(SHIFTS[self._rgb], SHIFTS_OFF[self._rgb])	#assign the colors from Map.py to the session nav buttons

				self._session.update()															#tell the Session component to update so that the grid will display the currently selected session region
				self._session.set_enabled(True)													#enable the Session Component
				self._session_zoom.set_enabled(True)											#enable the Session Zoom
				
				#self._alt_device_navigator.set_arrange_session_toggle_button(self._encoder_button[4])
				self._alt_device_navigator.set_device_clip_toggle_button(self._encoder_button[5])
				self._alt_device_navigator.set_detail_toggle_button(self._encoder_button[6])
				#self._device_navigator.set_shift_button(self._encoder_button[7])
				self._session_zoom.set_zoom_button(self._encoder_button[7])							#assign the lower right key button to the shift function of the Zoom component

				self._session.set_scene_bank_buttons(self._button[25], self._button[24])
				self._recorder.set_record_button(self._button[27])
				self._recorder.set_re_enable_automation_button(self._button[26])
		else:
			for index in range(8):
				self._mixer2.channel_strip(index).set_volume_control(self._fader[index])
			self._mixer2.set_track_offset(TROLL_OFFSET)
			self._device_selector.set_mode_buttons(self._grid)
			if not self._shifted:
				self._assign_monomodular_controls()
			else:
				self._assign_shifted_controls()
			self._device1.set_parameter_controls(tuple([self._knobs[index] for index in range(8)]))
			self._device2.set_parameter_controls(tuple([self._knobs[index+12] for index in range(8)]))
			self._device1.set_enabled(True)
			self._device2.set_enabled(True)
			self._find_devices()
			self._device1.update()
			self._device2.update()

		"""this section assigns the encoders and encoder buttons"""
		self._device.set_parameter_controls(tuple([self._encoder[index+4] for index in range(8)]))			#assign the encoders from the device component controls - we are doing this here b
		#self._encoder_button[7].set_on_value(DEVICE_LOCK[self._rgb])					#set the on color for the Device lock encoder button
		#self._device.set_lock_button(self._encoder_button[7])							#assign encoder button 7 to the device lock control
		#self._encoder_button[4].set_on_value(DEVICE_ON[self._rgb])						#set the on color for the Device on/off encoder button 
		#self._device.set_on_off_button(self._encoder_button[4])							#assing encoder button 4 to the device on/off control
		for index in range(2):															#setup a recursion to generate indexes so that we can reference the correct controls to assing to the device_navigator functions
			self._encoder_button[index + 8].set_on_value(DEVICE_NAV[self._rgb])			#assign the on color for the device navigator
			self._encoder_button[index + 10].set_on_value(DEVICE_BANK[self._rgb])		#assign the on color for the device bank controls
		self._device_navigator.set_nav_buttons(self._encoder_button[10], self._encoder_button[11]) 	#set the device navigators controls to encoder buttons 10 and 11
		self._device.set_bank_nav_buttons(self._encoder_button[8], self._encoder_button[9]) 	#set the device components bank nav controls to encoder buttons 8 and 9

		"""now we turn on and update some of the components we've just made assignments to"""
		self._device.set_enabled(True)													#enable the Device Component
		self._device_navigator.set_enabled(True)										#enable the Device Navigator
		self._alt_device_navigator.set_enabled(True)
		self._device.update()															#tell the Device component to update its assingments so that it will detect the currently selected device parameters and display them on the encoder rings
Beispiel #29
0
class DV1(ControlSurface):
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        is_momentary = True
        self._timer = 0  #used for flashing states, and is incremented by each call from self._update_display()
        self._touched = 0
        self.flash_status = 1  # Used in FlashingButtonElement (kludge for our purposes)
        self._device_selection_follows_track_selection = True

        with self.component_guard():
            self._setup_transport_control()

            if USE_MIXER_CONTROLS == True:
                self.mixer_control()
            if USE_SESSION_VIEW == True:
                self.session_control()
            # self.setup_device_control()

    def _setup_transport_control(self):
        is_momentary = True  # We'll only be using momentary buttons here
        self.transport = TransportComponent(
        )  #Instantiate a Transport Component
        """set up the buttons"""
        self.transport.set_play_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 60)
        )  #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module
        self.transport.set_stop_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61))
        self.transport.set_record_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 62))

    def mixer_control(self):
        is_momentary = True
        self.num_tracks = N_TRACKS
        if (USE_SENDS == True):
            self.mixer = MixerComponent(N_TRACKS, N_SENDS_PER_TRACK,
                                        USE_MIXER_EQ, USE_MIXER_FILTERS)
        else:
            self.mixer = MixerComponent(N_TRACKS, 0, USE_MIXER_EQ,
                                        USE_MIXER_FILTERS)
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        for index in range(N_TRACKS):
            self.mixer.channel_strip(
                index).name = 'Mixer_ChannelStrip_' + str(index)
            self.mixer.channel_strip(index)._invert_mute_feedback = True

        if (USE_SELECT_BUTTONS == True):
            self.selectbuttons = [None for index in range(N_TRACKS)]
            for index in range(len(SELECT_BUTTONS)):
                self.selectbuttons[index] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                    SELECT_BUTTONS[index], 'Select_Button', self)
                self.mixer.channel_strip(index).set_select_button(
                    self.selectbuttons[index])
                self.selectbuttons[index].set_on_value(SELECT_BUTTON_ON_COLOR)
                self.selectbuttons[index].set_off_value(
                    SELECT_BUTTON_OFF_COLOR)

        if (USE_SOLO_BUTTONS == True):
            self.solobuttons = [None for index in range(N_TRACKS)]
            for index in range(len(SOLO_BUTTONS)):
                self.solobuttons[index] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL, SOLO_BUTTONS[index],
                    'Solo_Button', self)
                self.mixer.channel_strip(index).set_solo_button(
                    self.solobuttons[index])
                self.solobuttons[index].set_on_value(SOLO_BUTTON_ON_COLOR)
                self.solobuttons[index].set_off_value(SOLO_BUTTON_OFF_COLOR)

        if (USE_ARM_BUTTONS == True):
            self.armbuttons = [None for index in range(N_TRACKS)]
            for index in range(len(ARM_BUTTONS)):
                self.armbuttons[index] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL, ARM_BUTTONS[index],
                    'Arm_Button', self)
                self.mixer.channel_strip(index).set_arm_button(
                    self.armbuttons[index])
                self.armbuttons[index].set_on_value(ARM_BUTTON_ON_COLOR)
                self.armbuttons[index].set_off_value(ARM_BUTTON_OFF_COLOR)

        if (USE_MUTE_BUTTONS == True):
            self.mutebuttons = [None for index in range(N_TRACKS)]
            for index in range(len(MUTE_BUTTONS)):
                self.mutebuttons[index] = FlashingButtonElement(
                    is_momentary, MIDI_NOTE_TYPE, CHANNEL, MUTE_BUTTONS[index],
                    'Mute_Button', self)
                self.mixer.channel_strip(index).set_mute_button(
                    self.mutebuttons[index])
                self.mutebuttons[index].set_on_value(MUTE_BUTTON_ON_COLOR)
                self.mutebuttons[index].set_off_value(MUTE_BUTTON_OFF_COLOR)

        if (USE_SENDS == True):
            self.sendencoders = [None for index in range(len(SEND_ENCODERS))]
            for index in range(len(SEND_ENCODERS)):
                # self.sendencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_ENCODERS[index], Live.MidiMap.MapMode.absolute)
                self.sendencoders[index] = CMDEncoderElement(
                    MIDI_CC_TYPE, CHANNEL, SEND_ENCODERS[index],
                    Live.MidiMap.MapMode.relative_smooth_binary_offset, 20)
            for index in range(len(SEND_ENCODERS) / N_SENDS_PER_TRACK):
                self.mixer.channel_strip(index).set_send_controls(
                    tuple(self.sendencoders[(index * N_SENDS_PER_TRACK):(
                        (index * N_SENDS_PER_TRACK) + N_SENDS_PER_TRACK)])
                )  # Pas -1, car tuple() fonctionne etrangement en Python ;)

        if (USE_VOLUME_CONTROLS == True):
            self.volencoders = [None for index in range(len(VOLUME_ENCODERS))]
            for index in range(len(VOLUME_ENCODERS)):
                #self.volencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, VOLUME_ENCODERS[index], Live.MidiMap.MapMode.absolute)
                self.volencoders[index] = CMDEncoderElement(
                    MIDI_CC_TYPE, CHANNEL, VOLUME_ENCODERS[index],
                    Live.MidiMap.MapMode.relative_smooth_binary_offset, 20)
                self.mixer.channel_strip(index).set_volume_control(
                    self.volencoders[index])

    def session_control(self):
        is_momentary = True
        self._timer = 0
        self.flash_status = 1
        self.grid = [None for index in range(N_TRACKS * N_SCENES)]
        for index in range(N_TRACKS * N_SCENES):
            self.grid[index] = FlashingButtonElement(is_momentary,
                                                     MIDI_NOTE_TYPE, CHANNEL,
                                                     TRACK_CLIP_BUTTONS[index],
                                                     'Grid' + str(index), self)
            self.grid[index].set_off_value(0)
            self.grid[index].turn_off()

        self.matrix = ButtonMatrixElement()
        for row in range(N_SCENES):
            button_row = []
            for column in range(N_TRACKS):
                button_row.append(self.grid[row + (column * N_SCENES)])
            self.matrix.add_row(tuple(button_row))
        self.session = SessionComponent(N_TRACKS, N_SCENES)
        self.session.name = "Session"
        self.session.set_offsets(0, 0)

        self.scene = [None for index in range(N_SCENES)]
        for row in range(N_SCENES):
            self.scene[row] = self.session.scene(row)
            self.scene[row].name = 'Scene_' + str(row)
            for column in range(N_TRACKS):
                clip_slot = self.scene[row].clip_slot(column)
                clip_slot.name = str(column) + '_Clip_Slot' + str(row)
                self.scene[row].clip_slot(column).set_triggered_to_play_value(
                    CLIP_TRG_PLAY_COLOR)
                self.scene[row].clip_slot(column).set_stopped_value(
                    CLIP_STOP_COLOR)
                self.scene[row].clip_slot(column).set_started_value(
                    CLIP_STARTED_COLOR)
        self.set_highlighting_session_component(self.session)
        #self.session_zoom = DeprecatedSessionZoomingComponent(self.session)                 #this creates the ZoomingComponent that allows navigation when the shift button is pressed
        #self.session_zoom.name = 'Session_Overview'                            #name it so we can access it in m4l
        #self.session_zoom.set_stopped_value(ZOOM_STOPPED)            #set the zooms stopped color
        #self.session_zoom.set_playing_value(ZOOM_PLAYING)            #set the zooms playing color
        #self.session_zoom.set_selected_value(ZOOM_SELECTED)            #set the zooms selected color
        #self.session_zoom.set_button_matrix(self.matrix)                        #assign the ButtonMatrixElement that we created in _setup_controls() to the zooming component so that we can control it
        #self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 84)
        #self.session_zoom.set_zoom_button(self._shift_button)                   #assign a shift button so that we can switch states between the SessionComponent and the SessionZoomingComponent

        #self.looper = LooperComponent(self)
        #self.log_message(str(len(STOP_BUTTONS)))
        #if(USE_STOP_BUTTONS == True):
        #self.stopbuttons = [None for index in range(N_TRACKS)]
        #for index in range(len(STOP_BUTTONS)):
        #self.stopbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,STOP_BUTTONS[index], 'Stop_Button', self)
        #self.session.set_stop_track_clip_buttons(self.stopbuttons)
        #self.stopbuttons[index].set_on_value(STOP_BUTTON_ON_COLOR)
        #self.stopbuttons[index].set_off_value(STOP_BUTTON_OFF_COLOR)
        #self.scrollencoder = ScrollEncoderElement(MIDI_CC_TYPE, CHANNEL, 32, Live.MidiMap.MapMode.absolute, self.session, self.transport, self.mixer, self.looper)
        #self.scrollencoder.set_nav_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80))
        #self.scrollencoder.set_transport_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 81))
        #self.scrollencoder.set_scene_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 82))
        #self.scrollencoder.set_library_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 83))
        #self.scrollencoder.set_button1(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 66))
        #self.scrollencoder.set_button2(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 67))
        #self.scrollencoder.set_button3(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 64))
        #self.scrollencoder.set_button4(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 65))
        #self.scrollencoder.set_encoder_button(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 32))

        self.button_left = SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                               CHANNEL, NAVBOX_LEFT_BUTTON)
        self.button_right = SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                CHANNEL, NAVBOX_RIGHT_BUTTON)
        self.button_up = SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                             CHANNEL, NAVBOX_UP_BUTTON)
        self.button_down = SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                               CHANNEL, NAVBOX_DOWN_BUTTON)

        self.session.set_track_bank_buttons(self.button_right,
                                            self.button_left)
        self.session.set_scene_bank_buttons(self.button_down, self.button_up)

        for column in range(N_TRACKS):
            for row in range(N_SCENES):
                self.scene[row].clip_slot(column).set_launch_button(
                    self.grid[row + (column * N_SCENES)])

        for index in range(N_TRACKS * N_SCENES):
            self.grid[index].clear_send_cache()

        if USE_MIXER_CONTROLS == True:
            self.session.set_mixer(self.mixer)

        self.refresh_state()
        self.session.set_enabled(True)
        self.session.update()

    #def setup_device_control(self):
    #is_momentary = True
    #device_bank_buttons = []
    #device_param_controls = []
    #bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button')
    #for index in range(4):
    #device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 16 + index))
    #device_bank_buttons[-1].name = bank_button_labels[index]
    #for index in range(8):
    ##ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, 21 + index)
    #ringed_encoder = CMDEncoderElement(MIDI_CC_TYPE, CHANNEL, 16 + index, Live.MidiMap.MapMode.relative_binary_offset, 20)
    ##ringed_encoder.set_ring_mode_button(ring_mode_button)
    #ringed_encoder.name = 'Device_Control_' + str(index)
    ##ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
    #device_param_controls.append(ringed_encoder)

    #device = ShiftableDeviceComponent()
    #device.name = 'Device_Component'
    #device.set_bank_buttons(tuple(device_bank_buttons))
    ##device.set_shift_button(self._shift_button)
    #device.set_parameter_controls(tuple(device_param_controls))
    #device.set_on_off_button(device_bank_buttons[1])
    #self.set_device_component(device)
    #detail_view_toggler = DetailViewControllerComponent(self)
    #detail_view_toggler.name = 'Detail_View_Control'
    ##detail_view_toggler.set_shift_button(self._shift_button)
    #detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
    #detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])

    def update_display(self):
        ControlSurface.update_display(self)
        self._timer = (self._timer + 1) % 256

    def disconnect(self):
        self._hosts = []
        ControlSurface.disconnect(self)
        return None
class DC1(ControlSurface):
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        is_momentary = True
        self._timer = 0                             #used for flashing states, and is incremented by each call from self._update_display()
        self._touched = 0    
        self.flash_status = 1 # Used in FlashingButtonElement (kludge for our purposes)       
        self._device_selection_follows_track_selection = True
        
        with self.component_guard():
            self._setup_transport_control()

            if USE_MIXER_CONTROLS == True:
                self.mixer_control()
            if USE_SESSION_VIEW == True:
                self.session_control()        
            self.setup_device_control()
    
    
    def _setup_transport_control(self):
        is_momentary = True # We'll only be using momentary buttons here
        self.transport = TransportComponent() #Instantiate a Transport Component
        """set up the buttons"""
        self.transport.set_play_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 60)) #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module
        self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61))
        self.transport.set_record_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 62))


    def mixer_control(self):
        is_momentary = True
        self.num_tracks = N_TRACKS
        if(USE_SENDS == True):
            self.mixer = MixerComponent(N_TRACKS, N_SENDS_PER_TRACK, USE_MIXER_EQ, USE_MIXER_FILTERS)
        else:
            self.mixer = MixerComponent(N_TRACKS,0, USE_MIXER_EQ, USE_MIXER_FILTERS)
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
        for index in range(N_TRACKS):
            self.mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
            self.mixer.channel_strip(index)._invert_mute_feedback = True             


        if(USE_SELECT_BUTTONS == True):
            self.selectbuttons = [None for index in range(N_TRACKS)]
            for index in range(len(SELECT_BUTTONS)):
                self.selectbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,SELECT_BUTTONS[index], 'Select_Button', self)
                self.mixer.channel_strip(index).set_select_button(self.selectbuttons[index])
                self.selectbuttons[index].set_on_value(SELECT_BUTTON_ON_COLOR)
                self.selectbuttons[index].set_off_value(SELECT_BUTTON_OFF_COLOR)

        if(USE_SOLO_BUTTONS == True):
            self.solobuttons = [None for index in range(N_TRACKS)]
            for index in range(len(SOLO_BUTTONS)):
                self.solobuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,SOLO_BUTTONS[index], 'Solo_Button', self)
                self.mixer.channel_strip(index).set_solo_button(self.solobuttons[index])
                self.solobuttons[index].set_on_value(SOLO_BUTTON_ON_COLOR)
                self.solobuttons[index].set_off_value(SOLO_BUTTON_OFF_COLOR)



        if(USE_ARM_BUTTONS == True):
            self.armbuttons = [None for index in range(N_TRACKS)]
            for index in range(len(ARM_BUTTONS)):
                self.armbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,ARM_BUTTONS[index], 'Arm_Button', self)
                self.mixer.channel_strip(index).set_arm_button(self.armbuttons[index])
                self.armbuttons[index].set_on_value(ARM_BUTTON_ON_COLOR)
                self.armbuttons[index].set_off_value(ARM_BUTTON_OFF_COLOR)
		
        if(USE_MUTE_BUTTONS == True):
            self.mutebuttons = [None for index in range(N_TRACKS)]
            for index in range(len(MUTE_BUTTONS)):
                self.mutebuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,MUTE_BUTTONS[index], 'Mute_Button', self)
                self.mixer.channel_strip(index).set_mute_button(self.mutebuttons[index])
                self.mutebuttons[index].set_on_value(MUTE_BUTTON_ON_COLOR)
                self.mutebuttons[index].set_off_value(MUTE_BUTTON_OFF_COLOR)
                
        if(USE_SENDS == True):
            self.sendencoders = [None for index in range(len(SEND_ENCODERS))]
            for index in range(len(SEND_ENCODERS)):
                self.sendencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_ENCODERS[index], Live.MidiMap.MapMode.absolute)
            for index in range(len(SEND_ENCODERS)/N_SENDS_PER_TRACK):
                self.mixer.channel_strip(index).set_send_controls(tuple(self.sendencoders[(index*N_SENDS_PER_TRACK):((index*N_SENDS_PER_TRACK)+N_SENDS_PER_TRACK-1)]))

                
        if(USE_VOLUME_CONTROLS == True):
            self.volencoders = [None for index in range(len(VOLUME_ENCODERS))]
            for index in range (len(VOLUME_ENCODERS)):
                self.volencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, VOLUME_ENCODERS[index], Live.MidiMap.MapMode.absolute)
                self.mixer.channel_strip(index).set_volume_control(self.volencoders[index])
      
    def session_control(self):
        is_momentary = True
        self._timer = 0
        self.flash_status = 1
        self.grid = [None for index in range(N_TRACKS*N_SCENES)]
        for index in range(N_TRACKS*N_SCENES):
            self.grid[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,TRACK_CLIP_BUTTONS[index], 'Grid' + str(index), self)
            self.grid[index].set_off_value(0)
            self.grid[index].turn_off()
            
        self.matrix = ButtonMatrixElement()
        for row in range(N_SCENES):
            button_row = []
            for column in range(N_TRACKS):
                button_row.append(self.grid[row+(column*N_SCENES)])
            self.matrix.add_row(tuple(button_row))
        self.session = SessionComponent(N_TRACKS,N_SCENES)
        self.session.name = "Session"
        self.session.set_offsets(0,0)

        self.scene = [None for index in range(N_SCENES)]
        for row in range(N_SCENES):
            self.scene[row] = self.session.scene(row)
            self.scene[row].name = 'Scene_'+str(row)
            for column in range(N_TRACKS):
                clip_slot = self.scene[row].clip_slot(column)
                clip_slot.name = str(column)+'_Clip_Slot'+str(row)
                self.scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRG_PLAY_COLOR)
                self.scene[row].clip_slot(column).set_stopped_value(CLIP_STOP_COLOR)
                self.scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR)
        self.set_highlighting_session_component(self.session)        
        self.session_zoom = DeprecatedSessionZoomingComponent(self.session)                 #this creates the ZoomingComponent that allows navigation when the shift button is pressed
        self.session_zoom.name = 'Session_Overview'                            #name it so we can access it in m4l
        self.session_zoom.set_stopped_value(ZOOM_STOPPED)            #set the zooms stopped color
        self.session_zoom.set_playing_value(ZOOM_PLAYING)            #set the zooms playing color
        self.session_zoom.set_selected_value(ZOOM_SELECTED)            #set the zooms selected color
        self.session_zoom.set_button_matrix(self.matrix)                        #assign the ButtonMatrixElement that we created in _setup_controls() to the zooming component so that we can control it
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 63)
        self.session_zoom.set_zoom_button(self._shift_button)                   #assign a shift button so that we can switch states between the SessionComponent and the SessionZoomingComponent

        self.looper = LooperComponent(self)
        self.log_message(str(len(STOP_BUTTONS)))
        if(USE_STOP_BUTTONS == True):
            self.stopbuttons = [None for index in range(N_TRACKS)]
            for index in range(len(STOP_BUTTONS)):
                self.stopbuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,STOP_BUTTONS[index], 'Stop_Button', self)
                self.session.set_stop_track_clip_buttons(self.stopbuttons)
                self.stopbuttons[index].set_on_value(STOP_BUTTON_ON_COLOR)
                self.stopbuttons[index].set_off_value(STOP_BUTTON_OFF_COLOR)
        self.scrollencoder = ScrollEncoderElement(MIDI_CC_TYPE, CHANNEL, 32, Live.MidiMap.MapMode.absolute, self.session, self.transport, self.mixer, self.looper)
        self.scrollencoder.set_nav_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 0))
        self.scrollencoder.set_transport_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 7))
        self.scrollencoder.set_scene_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 3))
        self.scrollencoder.set_library_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 4))
        self.scrollencoder.set_button1(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 1))
        self.scrollencoder.set_button2(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 2))
        self.scrollencoder.set_button3(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 5))
        self.scrollencoder.set_button4(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 6))
        self.scrollencoder.set_encoder_button(SimpleButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 32))
		

        for column in range(N_TRACKS):
            for row in range(N_SCENES):
                self.scene[row].clip_slot(column).set_launch_button(self.grid[row+(column*N_SCENES)])    
    
        for index in range(N_TRACKS*N_SCENES):
            self.grid[index].clear_send_cache()      
                
        
        if USE_MIXER_CONTROLS == True:
            self.session.set_mixer(self.mixer)    

        self.refresh_state()
        self.session.set_enabled(True)
        self.session.update()  
              
    def setup_device_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button')
        for index in range(4):
            device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 16 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
        for index in range(8):
            #ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, 21 + index)
            ringed_encoder = CMDEncoderElement(MIDI_CC_TYPE, CHANNEL, 16 + index, Live.MidiMap.MapMode.relative_binary_offset, 20)
            #ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = 'Device_Control_' + str(index)
            #ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)

        device = ShiftableDeviceComponent()
        device.name = 'Device_Component'
        device.set_bank_buttons(tuple(device_bank_buttons))
        device.set_shift_button(self._shift_button)
        device.set_parameter_controls(tuple(device_param_controls))
        device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(device)
        detail_view_toggler = DetailViewControllerComponent(self)
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])
        
    def update_display(self):
        ControlSurface.update_display(self)
        self._timer = (self._timer + 1) % 256
  
    def disconnect(self):
        self._hosts = []
        ControlSurface.disconnect(self)
        return None        
Beispiel #31
0
 def set_track_offset(self, new_offset):  #added override
     MixerComponent.set_track_offset(self, new_offset)
     if self._parent._slider_modes != None:
         self._parent._slider_modes.update()
     if self._parent._encoder_modes != None:
         self._parent._encoder_modes.update()
class QuNexus_Basic(ControlSurface):
  __module__ = __name__
  __doc__ = "QuNexus Keyboard controller script"
  
  def __init__(self, c_instance):
    ControlSurface.__init__(self, c_instance)
    #Turn off rebuild MIDI map until after we're done setting up
    self.set_suppress_rebuild_requests(True)
    
    #set up some variables I want to use in multiple functions
    self.mixer = None
    self.session = None
    
    #Setup the mixer and session object
    self._setup_session_control()
    self._setup_mixer_control()
    self._setup_device_control()
    self._setup_transport_control()
    self.set_suppress_rebuild_requests(False)

  def _setup_transport_control(self):
    self._transport = TransportComponent()
    self._transport.set_stop_button(ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,68))
    self._transport.set_record_button(ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,66))
    self._transport.set_play_button(ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,70))
    
    
  #note that we have split the mixer functions across two scripts, in order to have two session highlight boxes (one red, one yellow), so there are a few things which we are not doing here...
  def _setup_session_control(self):
    num_tracks = 1 #one column (track)
    num_scenes = 8 #eight rows, which will be mapped to eight "white" notes
    
    #(num_tracks, num_scenes) a session highlight ("red box") will appear with any two non-zero values
    self.session = QuNexusSessionComponent(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,63), ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,61))
    self.session.set_scene_bank_buttons(ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,51), ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,49))
    self.session.set_track_bank_buttons(ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,56), ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,54))
    
    self.session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 62))
    self.session.set_stop_all_clips_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 58))

    for row in range(8):
      for col in range(1):
        self.session.scene(row).clip_slot(col).set_started_value(127)
        self.session.scene(row).clip_slot(col).set_stopped_value(0)
    
    #here we set up the clip launch assignments for the session  
    clip_launch_notes = [48,50,52,53,55,57,59,60] #set of eight white notes starting at C3/C4
    for index in range(num_scenes):
      #step though scenes and assign a note to first slot of each
      self.session.scene(index).clip_slot(0).set_started_value(127)
      self.session.scene(index).clip_slot(0).set_stopped_value(3)
      #self.session.scene(index).clip_slot(0).set_recording_value(64)
      self.session.scene(index).clip_slot(0).set_launch_button(ButtonElement(is_momentary,MIDI_NOTE_TYPE,CHANNEL,clip_launch_notes[index]))
    #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


  def _setup_mixer_control(self):
    is_momentary = True
    #A mixer is one-dimensional; here we define the width in tracks - seven columns, which we will map to the seven "white" notes
    num_tracks = 1
    #set up the mixer
    self.mixer = MixerComponent(num_tracks, 2, with_eqs=True, with_filters=True)  #(num_tracks, num_returns, with_eqs, with_filters)
    self.mixer.set_track_offset(0)  #sets start point for mixer strip (offset from left)
    #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
    self.song().view.selected_track = self.mixer.channel_strip(0)._track
    #set up the mixer buttons
    #self.mixer.set_select_buttons() #left, right track select
        
  def _setup_device_control(self):
    sliders = []
    pressures = [92,94,98,102,106,108]
    for index in range(6):
      sliders.append(SliderElement(MIDI_CC_TYPE, CHANNEL, pressures[index]))
      
    self._sliders = tuple(sliders)
    device = DeviceComponent()
    device.name = 'Device_Component'
    self.set_device_component(device)
    device.set_parameter_controls(self._sliders)

  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()) + "----------QuNexus Basic log closed----------")
    
    ControlSurface.disconnect(self)
    return None
Beispiel #33
0
class CNTRL_R_LITE(ControlSurface):
	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		is_momentary = True
		self._timer = 0 # Used in FlashingButtonElement (kludge for our purposes)
		self.flash_status = 1 # Used in FlashingButtonElement (kludge for our purposes)		
		
		if USE_MIXER_CONTROLS == True:
			self.mixer_control()
		
		if USE_SESSION_VIEW == True:
			self.session_control()		
  
	def mixer_control(self):
		is_momentary = True
		self.num_tracks = N_TRACKS
		if(USE_SENDS == True):
			self.mixer = MixerComponent(N_TRACKS, N_SENDS_PER_TRACK, USE_MIXER_EQ, USE_MIXER_FILTERS)
		else:
			self.mixer = MixerComponent(N_TRACKS,0, USE_MIXER_EQ, USE_MIXER_FILTERS)
		self.mixer.name = 'Mixer'
		self.mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(N_TRACKS):
			self.mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			self.mixer.channel_strip(index)._invert_mute_feedback = True 
		self.song().view.selected_track = self.mixer.channel_strip(0)._track
	
		self.log_message(str(len(SOLO_BUTTONS)))
		self.log_message(str(len(MUTE_BUTTONS)))
	
		if(USE_SOLO_BUTTONS == True):
			self.solobuttons = [None for index in range(N_TRACKS)]
			for index in range(len(SOLO_BUTTONS)):
				self.solobuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,SOLO_BUTTONS[index], 'Solo_Button', self)
				self.mixer.channel_strip(index).set_solo_button(self.solobuttons[index])
				self.solobuttons[index].set_on_value(SOLO_BUTTON_ON_COLOR)
				self.solobuttons[index].set_off_value(SOLO_BUTTON_OFF_COLOR)

		if(USE_MUTE_BUTTONS == True):
			self.mutebuttons = [None for index in range(N_TRACKS)]
			for index in range(len(MUTE_BUTTONS)):
				self.mutebuttons[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,MUTE_BUTTONS[index], 'Mute_Button', self)
				self.mixer.channel_strip(index).set_mute_button(self.mutebuttons[index])
				self.mutebuttons[index].set_on_value(MUTE_BUTTON_ON_COLOR)
				self.mutebuttons[index].set_off_value(MUTE_BUTTON_OFF_COLOR)
				
		if(USE_SENDS == True):
			self.sendencoders = [None for index in range(len(SEND_ENCODERS))]
			for index in range(len(SEND_ENCODERS)):
				self.sendencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, SEND_ENCODERS[index], Live.MidiMap.MapMode.absolute)
			for index in range(len(SEND_ENCODERS)/N_SENDS_PER_TRACK):
				self.mixer.channel_strip(index).set_send_controls(tuple(self.sendencoders[(index*N_SENDS_PER_TRACK):((index*N_SENDS_PER_TRACK)+N_SENDS_PER_TRACK-1)]))
				
		if(USE_VOLUME_CONTROLS == True):
			self.volencoders = [None for index in range(len(VOLUME_ENCODERS))]
			for index in range (len(VOLUME_ENCODERS)):
				self.volencoders[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, VOLUME_ENCODERS[index], Live.MidiMap.MapMode.absolute)
				self.mixer.channel_strip(index).set_volume_control(self.volencoders[index])
	  
	def session_control(self):
		is_momentary = True
		self._timer = 0
		self.flash_status = 1
		self.grid = [None for index in range(N_TRACKS*N_SCENES)]
		for index in range(N_TRACKS*N_SCENES):
			self.grid[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,TRACK_CLIP_BUTTONS[index], 'Grid' + str(index), self)
		self.matrix = ButtonMatrixElement()
		for row in range(N_SCENES):
			button_row = []
			for column in range(N_TRACKS):
				button_row.append(self.grid[row+(column*4)])
			self.matrix.add_row(tuple(button_row))
		self.session = SessionComponent(N_TRACKS,N_SCENES)
		self.session.name = "Session"
		self.session.set_offsets(0,0)
		self.scene = [None for index in range(N_SCENES)]
		for row in range(N_SCENES):
			self.scene[row] = self.session.scene(row)
			self.scene[row].name = 'Scene_'+str(row)
			for column in range(N_TRACKS):
				clip_slot = self.scene[row].clip_slot(column)
				clip_slot.name = str(column)+'_Clip_Slot'+str(row)
				self.scene[row].clip_slot(column).set_triggered_to_play_value(CLIP_TRG_PLAY_COLOR)
				self.scene[row].clip_slot(column).set_stopped_value(CLIP_STOP_COLOR)
				self.scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR)
	
    # Clip trigger on grid assignments
		for column in range(N_TRACKS):
			for row in range(N_SCENES):
				self.scene[row].clip_slot(column).set_launch_button(self.grid[row+(column*4)])	
	
		for index in range(N_TRACKS*N_SCENES):
			self.grid[index].clear_send_cache()	  
				
		if USE_SESSION_NAV == True:
			self.navleft = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_LEFT_BUTTON, 'Nav_Left_Button', self)
			self.navleft.clear_send_cache()
			self.navleft.set_on_off_values(NAVBOX_LEFT_BUTTON_C, NAVBOX_LEFT_BUTTON_C)
			
			self.navright = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_RIGHT_BUTTON, 'Nav_Right_Button', self)
			self.navright.clear_send_cache()
			self.navright.set_on_off_values(NAVBOX_RIGHT_BUTTON_C, NAVBOX_RIGHT_BUTTON_C)
			
			self.navup = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_UP_BUTTON, 'Nav_Up_Button', self)
			self.navup.clear_send_cache()
			self.navup.set_on_off_values(NAVBOX_UP_BUTTON_C, NAVBOX_UP_BUTTON_C)
				 
			self.navdown = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,NAVBOX_DOWN_BUTTON, 'Nav_Down_Button', self)
			self.navdown.clear_send_cache()
			self.navdown.set_on_off_values(NAVBOX_DOWN_BUTTON_C, NAVBOX_DOWN_BUTTON_C) 
			
			self.session.set_track_bank_buttons(self.navright, self.navleft)
			self.session.set_scene_bank_buttons(self.navdown, self.navup)
		
		if USE_MIXER_CONTROLS == True:
			self.session.set_mixer(self.mixer)	

		self.refresh_state()
		self.session.set_enabled(True)
		self.session.update()		
			
	def update_display(self):
		ControlSurface.update_display(self)
		self._timer = (self._timer + 1) % 256
		self.flash()
		
	def flash(self):
		if(USE_SESSION_VIEW == True):
			for index in range(N_TRACKS*N_SCENES):
				if(self.grid[index]._flash_state > 0):
					self.grid[index].flash(self._timer)	
		if(USE_SESSION_NAV == True):
			if(self.navleft._flash_state>0):
					self.navleft.flash(self._timer)
			if(self.navright._flash_state>0):
					self.navright.flash(self._timer)
			if(self.navup._flash_state>0):
					self.navup.flash(self._timer)
			if(self.navdown._flash_state>0):
					self.navdown.flash(self._timer)	
		if(USE_MIXER_CONTROLS == True):
			for index in range(N_TRACKS):
				if(USE_SOLO_BUTTONS == True):
					if(self.solobuttons[index]._flash_state > 0):
						self.solobuttons[index].flash(self._timer)				
				if(USE_MUTE_BUTTONS == True):
					if(self.mutebuttons[index]._flash_state > 0):
						self.mutebuttons[index].flash(self._timer)
				

	def disconnect(self):
		self._hosts = []
		self.log_message("--------------= CNTRLR log closed =--------------")
		ControlSurface.disconnect(self)
		return None		
Beispiel #34
0
class Tweaker(ControlSurface):
	__module__ = __name__
	__doc__ = " MonOhmod companion controller script "


	def __init__(self, c_instance):
		"""everything except the '_on_selected_track_changed' override and 'disconnect' runs from here"""
		ControlSurface.__init__(self, c_instance)
		with self.component_guard():
			self._update_linked_device_selection = None
			self._tweaker_version = '0.2'
			self.log_message("--------------= Tweaker Mixer " + str(self._tweaker_version) + " log opened =--------------") 
			self._update_linked_device_selection = None
			self._setup_mixer_control()
			self._setup_session_control()
	

	"""script initialization methods"""
	def _setup_controls(self):
		is_momentary = True
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column + (row * 8), 'Grid_' + str(column) + '_' + str(row), self) for row in range(4)]
		self._button = [FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_BUTTONS[index], 'Button_' + str(index), self) for index in range(len(TWEAKER_BUTTONS))]
		self._nav = [FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_NAVS[index], 'Nav_' + str(index), self) for index in range(len(TWEAKER_NAVS))]
		self._encoder_buttons = [FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, TWEAKER_ENCODER_BUTTONS[index], 'Encoder_Button_' + str(index), self) for index in range(len(TWEAKER_ENCODER_BUTTONS))]
		self._dial = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_DIALS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_DIALS))]
		self._fader = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_FADERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_FADERS))]
		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._encoder = [EncoderElement(MIDI_CC_TYPE, CHANNEL, TWEAKER_ENCODERS[index], Live.MidiMap.MapMode.absolute) for index in range(len(TWEAKER_ENCODERS))]
		self._pad = [FlashingButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, TWEAKER_PADS[index], 'Pad_' + str(index), self) for index in range(len(TWEAKER_PADS))]
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		for row in range(4):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 	
	

	def _setup_transport_control(self):
		self._transport = TransportComponent() 
		self._transport.name = 'Transport'
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (2) #A mixer is one-dimensional; 
		self._mixer = MixerComponent(2, 0, False, True)
		self._mixer.name = 'Mixer'
		self._mixer.tracks_to_use = self._mixer_tracks_to_use(self._mixer)
		self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
	

	def _setup_session_control(self):
		is_momentary = True
		num_tracks = 2
		num_scenes = 3 
		self._session = SessionComponent(num_tracks, num_scenes)
		self._session.name = "Session"
		self._session.set_offsets(0, 0)
		self._session.set_mixer(self._mixer)
		self.set_highlighting_session_component(self._session)
	

	"""general functionality"""
	
	def allow_updates(self, allow_updates):
		for component in self.components:
			component.set_allow_update(int(allow_updates!=0))
	

	def disconnect(self):
		"""clean things up on disconnect"""
		if self._session._is_linked():
			self._session._unlink()
		self.log_message("--------------= Tweaker Mixer " + str(self._tweaker_version) + " log closed =--------------") #Create entry in log file
		ControlSurface.disconnect(self)
		return None
	

	def connect_script_instances(self, instanciated_scripts):
		link = False
		for s in instanciated_scripts:
			if '_tweaker_version' in dir(s):
				if s._tweaker_version == self._tweaker_version:
					link = True
			if not s is self:
				s._linked_session = self._session
					#break	
		if link is True:
			if not self._session._is_linked():
				#self._session.set_offsets(0, 0)
				self._session._link()
	

	def _mixer_tracks_to_use(self, mixer):
		def tracks_to_use():
			return tuple(self.song().visible_tracks) + tuple(self.song().return_tracks)
		return tracks_to_use

#	a
Beispiel #35
0
class LinkedCode(ControlSurface):
	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		self._reset()
		# turn off rebuild MIDI map until after setup
		self.set_suppress_rebuild_requests(True)
		self._create_buttons()
		self._create_encoders()
		self._create_device_components()
		self._setup_mixer_control()
		self._setup_transport_control()
		self._setup_session_control()
		self._setup_mode_selector_control()
		self.set_suppress_rebuild_requests(False)

	def _reset(self):
		self._send_midi(FactoryReset)
		self._send_midi(ButtonMap)
		# self._send_midi(EncosionMap1);
		self._send_midi(ButtonChannelMap)
		self._send_midi(EncoderChannelMap)
		
	def _create_mode_buttons(self):
		self.mode_buttons = []
		for i in range(MODES):
			self.mode_buttons.append(ButtonElement(True, MIDI_NOTE_TYPE, CHAN, SIDE_BUTTONS_NOTES[MODES-1-i]))

	def _create_buttons(self):
		self._buttons = []
		for row in (ROW1_BUTTON_NOTES, ROW2_BUTTON_NOTES, ROW3_BUTTON_NOTES, ROW4_BUTTON_NOTES, BOTTOM_BUTTONS_NOTES):
			for n in row:
				self._buttons.append(ButtonElement(True, MIDI_NOTE_TYPE, CHAN, n))

	def _create_encoders(self):
		# hack, placeholder control so we can get to arbitrary parameters
		# in a device
		self._dummy_encoder = EncoderElement(MIDI_CC_TYPE, CHAN + 1, 0x7f, Live.MidiMap.MapMode.absolute)
		self._encoders = []
		self._sliders = []
		for row in (ROW1_ENCODERS_CCS, ROW2_ENCODERS_CCS, ROW3_ENCODERS_CCS, ROW4_ENCODERS_CCS):
			for n in row:
				self._encoders.append(EncoderElement(MIDI_CC_TYPE, CHAN, n, Live.MidiMap.MapMode.absolute))
				self._sliders.append(SliderElement(MIDI_CC_TYPE, CHAN, n))
		# make a relative encoder.  currently not in use, since causes an error when such an encoder is assigned to anything
		#self._encoders.append(EncoderElement(MIDI_CC_TYPE, CHAN, ROW1_ENCODERS_CCS[7], Live.MidiMap.MapMode.relative_two_compliment))
		
	def _create_device_components(self):
		self._create_return_devices()
		self._create_selected_device()
		self._create_device_view_controls()

	def _create_return_devices(self):
		self._device_returns = []
		for track in self.song().return_tracks:
			device = DeviceComponent()
			try:
				device.set_device(track.devices[0])
			except:
				self.log_message("no devices on return track")
			self._device_returns.append(device)
			if len(self._device_returns) == 2:
				break

	def _create_selected_device(self):
		self._device_selected = DeviceComponent()
		self.set_device_component(self._device_selected)

	def _create_device_view_controls(self):
		self._detail_view_control = DetailViewCntrlComponent()

	def _setup_mode_selector_control(self):
		self._create_mode_buttons()
		self._last_mode = -1
		self._unmap_mode_callbacks = (self._unmap_mode_0, self._unmap_mode_1, self._unmap_mode_2, self._unmap_mode_3)
		self._map_mode_callbacks = (self._map_mode_0, self._map_mode_1, self._map_mode_2, self._map_mode_3)
		self.mode_selector = ModeSelectorComponent2(MODES)
		self.mode_selector.add_mode_index_listener(self._mode_changed)
		# call this last because setting the mode buttons sets the default mode
		self.mode_selector.set_mode_buttons(tuple(self.mode_buttons))

	def _mode_changed(self):
		if self.mode_selector.mode_index == 3:
			self._unmap_session_buttons()
		if self._last_mode != -1:
			self._unmap_mode_callbacks[self._last_mode]()
		self._map_mode_callbacks[self.mode_selector.mode_index]()
		if self._last_mode == -1 or self._last_mode == 3:
			self._map_session_buttons()
		self._last_mode = self.mode_selector.mode_index

	def _map_session_buttons(self):
		for i in range(MIXER_TRACKS):
			self.mixer.channel_strip(i).set_invert_mute_feedback(True)
			self.mixer.channel_strip(i).set_mute_button(self._buttons[4 * 8 + i])
			self.mixer.channel_strip(i).set_select_button(self._buttons[3 * 8 + i])
			self.mixer.channel_strip(i).set_arm_button(self._buttons[2 * 8 + i])
			self.mixer.channel_strip(i).set_solo_button(self._buttons[8 + i])
		stop_track_buttons = []
		for i in range(SESSION_TRACKS):
			stop_track_buttons.append(self._buttons[i])
		self.session.set_stop_track_clip_buttons(tuple(stop_track_buttons)) #array size needs to match num_tracks  

	def _unmap_session_buttons(self):
		for i in range(MIXER_TRACKS):
			self.mixer.channel_strip(i).set_mute_button(None)
			self.mixer.channel_strip(i).set_select_button(None)
			self.mixer.channel_strip(i).set_arm_button(None)
			self.mixer.channel_strip(i).set_solo_button(None)
		self.session.set_stop_track_clip_buttons(None) #array size needs to match num_tracks  

	def _map_mode_0(self):
		self.log_message("+ mode 1")
		for i in range(MIXER_TRACKS):
			self.mixer.channel_strip(i).set_volume_control(self._sliders[3 * 8 + i])
			self.mixer.channel_strip(i).set_send_controls((self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i]))
			# or...
			# self.mixer.channel_strip(i).set_pan_control(self._encoders[2 * 8 + i])
			# self.mixer.channel_strip(i).set_send_controls((self._encoders[8 + i], self._encoders[i]))
			
	def _unmap_mode_0(self):
		self.log_message("- mode 1")
		for i in range(MIXER_TRACKS):
			self.mixer.channel_strip(i).set_volume_control(None)
			# self.mixer.channel_strip(i).set_pan_control(None)
			self.mixer.channel_strip(i).set_send_controls(None)

	def _map_mode_1(self):
		self.log_message("+ mode 2")
		for i in range(SESSION_TRACKS):
			self.session.device(i).set_parameter_controls((self._encoders[3 * 8 + i], self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i]))

	def _unmap_mode_1(self):
		self.log_message("- mode 2")
		for i in range(SESSION_TRACKS):
			self.session.device(i).set_parameter_controls(())

	def _map_mode_2(self):
		self.log_message("+ mode 3")
		for i in range(SESSION_TRACKS):
			self.session.device(i).set_parameter_controls((self._dummy_encoder, self._dummy_encoder, self._dummy_encoder, self._dummy_encoder, self._encoders[3 * 8 + i], self._encoders[2 * 8 + i], self._encoders[8 + i], self._encoders[i]))

	def _unmap_mode_2(self):
		self.log_message("- mode 3")
		for i in range(SESSION_TRACKS):
			self.session.device(i).set_parameter_controls(())

	def _map_mode_3(self):
		self.log_message("+ mode 4")
		# self._send_midi(EncosionMap2);
		for i in range(len(self._device_returns)):	# maybe this should be 2, instead of all returns? - LD
			self._device_returns[i].set_parameter_controls((self._encoders[3 * 8 + i * 2], self._encoders[2 * 8 + i * 2], self._encoders[8 + i * 2], self._encoders[i * 2], self._encoders[3 * 8 + i * 2 + 1], self._encoders[2 * 8 + i * 2 + 1], self._encoders[8 + i * 2 + 1], self._encoders[i * 2 + 1]))
		self._device_selected.set_parameter_controls((self._encoders[3 * 8 + 2 * 2], self._encoders[2 * 8 + 2 * 2], self._encoders[8 + 2 * 2], self._encoders[2 * 2], self._encoders[3 * 8 + 2 * 2 + 1], self._encoders[2 * 8 + 2 * 2 + 1], self._encoders[8 + 2 * 2 + 1], self._encoders[2 * 2 + 1]))
		self._device_selected.set_on_off_button(self._buttons[2 * 8 + 5])
		self._detail_view_control.set_device_clip_toggle_button(self._buttons[4 * 8 + 4])
		self._detail_view_control.set_detail_toggle_button(self._buttons[4 * 8 + 5])
		self._detail_view_control.set_device_nav_buttons(self._buttons[3 * 8 + 4], self._buttons[3 * 8 + 5])
		for i in range(4):
			self.mixer.return_strip(i).set_volume_control(self._sliders[(3 - i) * 8 + 6])
		for i in range(RETURN_TRACKS):
			self.mixer.return_strip(i).set_invert_mute_feedback(True)
			self.mixer.return_strip(i).set_select_button(self._buttons[4 * 8 + i])
			self.mixer.return_strip(i).set_mute_button(self._buttons[3 * 8 + i])
		self.mixer.master_strip().set_select_button(self._buttons[4 * 8 + 7])
		self.mixer.master_strip().set_volume_control(self._sliders[3 * 8 + 7])
		self.mixer.set_prehear_volume_control(self._sliders[2 * 8 + 7])
		self._transport.set_record_button(self._buttons[3 * 8 + 6])
		self._transport.set_play_button(self._buttons[3 * 8 + 7])
		self._transport.set_stop_button(self._buttons[2 * 8 + 7])
		self._transport.set_nudge_buttons(self._buttons[8 + 7], self._buttons[8 + 6])
		self._transport.set_tap_tempo_button(self._buttons[4 * 8 + 6])
		self._transport.set_tempo_control(self._encoders[7], self._encoders[15])
		self.session.set_stop_all_clips_button(self._buttons[2 * 8 + 6])
		self._transport.set_metronome_button(self._buttons[0 * 8 + 6])
		self._transport.set_overdub_button(self._buttons[0 * 8 + 7])
		
	def _unmap_mode_3(self):
		self.log_message("- mode 4")
		# self._send_midi(EncosionMap1);
		for i in range(len(self._device_returns)):
			self._device_returns[i].set_parameter_controls(())
		self._device_selected.set_parameter_controls(())
		self._device_selected.set_on_off_button(None)
		self._detail_view_control.set_device_clip_toggle_button(None)
		self._detail_view_control.set_detail_toggle_button(None)
		self._detail_view_control.set_device_nav_buttons(None, None)
		for i in range(4):
			self.mixer.return_strip(i).set_volume_control(None)
		for i in range(RETURN_TRACKS):
			self.mixer.return_strip(i).set_select_button(None)
			self.mixer.return_strip(i).set_mute_button(None)
		self.mixer.master_strip().set_select_button(None)
		self.mixer.master_strip().set_volume_control(None)
		self._transport.set_record_button(None)
		self._transport.set_play_button(None)
		self._transport.set_stop_button(None)
		self._transport.set_nudge_buttons(None, None)
		self._transport.set_tap_tempo_button(None)
		self._transport.set_tempo_control(None, None)
		self.session.set_stop_all_clips_button(None)
		self.mixer.set_prehear_volume_control(None)
		self._transport.set_metronome_button(None)
		self._transport.set_overdub_button(None)


	def _setup_mixer_control(self):
		# MixerComponent(num_tracks, num_returns, ...)
		self.mixer = MixerComponent(MIXER_TRACKS, RETURN_TRACKS, with_eqs = True, with_filters = False)
		self.mixer.set_track_offset(0)

	def _setup_transport_control(self):
		self._transport = TransportComponent()

	def _setup_session_control(self):
		self.session = SessionComponent2(SESSION_TRACKS, SESSION_SCENES, self)
		self.session.name = "Session_Control"
		self.session.set_mixer(self.mixer)
		self.session._link()
		
	def disconnect(self):
		if self.session and self.session._is_linked():
			self.session._unlink()
		ControlSurface.disconnect(self)
Beispiel #36
0
class ControlMI(ControlSurface):
    __module__ = __name__
    __doc__ = " ControlMI 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("--------------= ControlMI log opened =--------------")
        with self.component_guard():
            # OBJECTS
            self.session = None
            self.mixer = None
            self.view = None
            self.device = None
            self.transport = None
            # INITIALIZE MIXER, SESSIONS
            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_device_control()  # Setup the device object
            self._setup_transport_control()  # Setup transport object
            self._set_initial_mode()
            self.set_device_component(
                self.device)  # Bind device to control surface-
            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 ##############################")
        self.session = SessionComponent(num_tracks, num_scenes)
        self.session.set_offsets(0, 0)
        self.session.set_track_bank_buttons(
            ButtonElement(False, MIDI_CC_TYPE, data_channel, session_right),
            ButtonElement(False, MIDI_CC_TYPE, data_channel, session_left))

    def _setup_mixer_control(self):
        self.mixer = MixerComponent(num_tracks, 0, False, False)
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(0)

    def _setup_device_control(self):
        self.device = DeviceComponent()
        self.device.name = 'Device_Component'

    def _setup_transport_control(self):
        self.transport = TransportComponent(self)

    def _clear_controls(self):
        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)
            strip.set_select_button(None)
        # TRANSPORT
        self.transport.set_stop_button(None)
        self.transport.set_play_button(None)
        self.transport.set_record_button(None)

        self.log_message("Controls Cleared")

    def _set_initial_mode(self):
        is_momentary = True
        ### MIXER

        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.name = 'Mixer_ChannelStrip_' + str(index)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, data_channel,
                              mixer_volume_cc[index]))
            strip._invert_mute_feedback = True

        self.mixer.master_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, data_channel, mixer_master_cc))
        self.transport.set_stop_button(
            ButtonElement(False, MIDI_CC_TYPE, data_channel,
                          transport_stop_cc))
        self.transport.set_play_button(
            ButtonElement(False, MIDI_CC_TYPE, data_channel,
                          transport_play_cc))
        self.transport.set_record_button(
            ButtonElement(False, MIDI_CC_TYPE, data_channel,
                          transport_record_cc))

        self.log("color: " + str(self.session.tracks_to_use()[0].color))
        self.log("color: " + str(self.session.tracks_to_use()[1].color))
        self.log("color: " + str(self.session.tracks_to_use()[2].color))
        self.log("color: " + str(self.session.tracks_to_use()[3].color))
        self._send_midi([0x09, 0x09, 0x09, 0x09])

    def disconnect(self):
        """clean things up on disconnect"""
        self.log("--------------= ControlMI log closed =--------------")
        self._clear_controls()
        self.session = None
        self.mixer = None
        self.view = None
        self.device = None
        self.transport = None

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

    def log(self, message):
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + message)
Beispiel #37
0
    def _setup_mixer_control(self):
        is_momentary = True  # We use non-latching buttons (keys) throughout, so we'll set this as a constant
        num_tracks = 4  # Here we define the mixer width in tracks (a mixer has only one dimension)
        global mixer  # We want to instantiate the global mixer as a MixerComponent object (it was a global "None" type up until now...)
        mixer = MixerComponent(
            num_tracks, 2, with_eqs=True, with_filters=False
        )  #(num_tracks, num_returns, with_eqs, with_filters)
        mixer.set_track_offset(
            0)  #Sets start point for mixer strip (offset from left)
        """set up the mixer buttons"""
        self.song().view.selected_track = mixer.channel_strip(0)._track
        #mute_notes = [1,5,9,13]
        #solo_notes = [2,6,10,14]
        #arm_notes = [3,7,11,15]
        track_select_notes = [
            38, 39, 40, 41
        ]  #more note numbers need to be added if num_scenes is increased
        send_ccs = [2, 6, 10, 14, 1, 5, 9, 13]
        pan_ccs = [3, 7, 11, 15]
        slider_ccs = [4, 8, 12, 16]
        for index in range(num_tracks):
            mixer.channel_strip(index).set_select_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHAN,
                              track_select_notes[index]))
            mixer.channel_strip(index).set_volume_control(
                SliderElement(MIDI_CC_TYPE, CHAN, slider_ccs[index]))
            mixer.channel_strip(index).set_pan_control(
                EncoderElement(MIDI_CC_TYPE, CHAN, pan_ccs[index],
                               Live.MidiMap.MapMode.absolute))
            #put send A and send B controllers into an array, which is then "tupled" for set_send_controls:
            send_controlers = [
                EncoderElement(MIDI_CC_TYPE, CHAN, send_ccs[index],
                               Live.MidiMap.MapMode.absolute),
                EncoderElement(MIDI_CC_TYPE, CHAN,
                               send_ccs[index + num_tracks],
                               Live.MidiMap.MapMode.absolute)
            ]
            mixer.channel_strip(index).set_send_controls(
                tuple(send_controlers))

        crossfader = SliderElement(MIDI_CC_TYPE, CHAN, 28)
        master_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 32)
        returna_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 19)
        returna_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 20)
        returnb_pan_control = SliderElement(MIDI_CC_TYPE, CHAN, 23)
        returnb_volume_control = SliderElement(MIDI_CC_TYPE, CHAN, 24)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                             CHAN, 31)
        prehear_control = EncoderElement(MIDI_CC_TYPE, CHAN, 30,
                                         Live.MidiMap.MapMode.absolute)
        crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        returna_pan_control.name = 'ReturnA_Pan_Control'
        returna_volume_control.name = 'ReturnA_Volume_Control'
        returnb_pan_control.name = 'ReturnB_Pan_Control'
        returnb_volume_control.name = 'ReturnB_Volume_Control'
        master_select_button.name = 'Master_Select_Button'
        prehear_control.name = 'Prehear_Volume_Control'
        mixer.set_crossfader_control(crossfader)
        mixer.master_strip().set_volume_control(master_volume_control)
        mixer.master_strip().set_select_button(master_select_button)
        mixer.set_prehear_volume_control(prehear_control)
        mixer.return_strip(0).set_pan_control(returna_pan_control)
        mixer.return_strip(0).set_volume_control(returna_volume_control)
        mixer.return_strip(1).set_pan_control(returnb_pan_control)
        mixer.return_strip(1).set_volume_control(returnb_volume_control)