Exemple #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)
    def _setup_mixer_control(self):
        is_momentary = True
        mixer = MixerComponent(NUM_TRACKS, 2, with_eqs=True, with_filters=True)
        for track in range(NUM_TRACKS):
            strip = mixer.channel_strip(track)
            strip.set_volume_control(SliderElement(MIDI_CC_TYPE, track, 23))
            strip.set_pan_control(
                EncoderElement(MIDI_CC_TYPE, track, 10,
                               Live.MidiMap.MapMode.absolute))
            strip.set_send_controls(
                (EncoderElement(MIDI_CC_TYPE, track, 19,
                                Live.MidiMap.MapMode.absolute),
                 EncoderElement(MIDI_CC_TYPE, track, 20,
                                Live.MidiMap.MapMode.absolute)))
            strip.set_solo_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 64))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 63))
            strip.set_crossfade_toggle(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 65))
            eq = mixer.track_eq(track)
            eq.set_gain_controls(
                tuple([
                    EncoderElement(MIDI_CC_TYPE, track, 18 - index,
                                   Live.MidiMap.MapMode.absolute)
                    for index in range(3)
                ]))
            eq.set_cut_buttons(
                tuple([
                    ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                  62 - index) for index in range(3)
                ]))
            filter = mixer.track_filter(track)
            filter.set_filter_controls(
                EncoderElement(MIDI_CC_TYPE, track, 22,
                               Live.MidiMap.MapMode.absolute),
                EncoderElement(MIDI_CC_TYPE, track, 21,
                               Live.MidiMap.MapMode.absolute))

        for ret_track in range(2):
            strip = mixer.return_strip(ret_track)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, 12, 22 + ret_track))
            strip.set_pan_control(
                EncoderElement(MIDI_CC_TYPE, 12, 20 + ret_track,
                               Live.MidiMap.MapMode.absolute))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12,
                              78 + ret_track))

        mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 12, 8))
        mixer.set_prehear_volume_control(
            EncoderElement(MIDI_CC_TYPE, 12, 24,
                           Live.MidiMap.MapMode.absolute))
        mixer.master_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, 12, 7))
        mixer.master_strip().set_pan_control(
            EncoderElement(MIDI_CC_TYPE, 12, 10,
                           Live.MidiMap.MapMode.absolute))
        return mixer
 def _setup_mixer_control(self):
     is_momentary = True
     #mixer = MixerComponent(8)
     mixer = MixerComponent(1)
     #for track in range(8):
     #    strip = mixer.channel_strip(track)
     #    strip.set_volume_control(SliderElement(MIDI_CC_TYPE, track, 7))
     #    strip.set_arm_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
     #    strip.set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49))
     #    strip.set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50))
     #    #strip.set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51))
     #    strip.set_shift_button(self._shift_button)
     #    strip.set_invert_mute_feedback(True)
     """ WAC addition...................................."""
     mixer.selected_strip().set_mute_button(SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[9]))
     mixer.selected_strip().set_solo_button(SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[13]))
     mixer.set_select_buttons(SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[15]),
                              SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[14]))
     send_faders = []
     NUM_CONTROLLABLE_SENDS = 4
     for index in range(NUM_CONTROLLABLE_SENDS):
         send_faders.append(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[index + 2]))
     mixer.selected_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[0]))
     mixer.selected_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[1]))
     mixer.selected_strip().set_send_controls(tuple(send_faders))
     """------------------------------------------------"""
     #mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 0, 15))
     #mixer.set_prehear_volume_control(EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment))
     mixer.set_prehear_volume_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[6], Live.MidiMap.MapMode.absolute))
     #mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 0, 14))
     mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[7]))
     #mixer.master_strip().set_select_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80))
     return mixer
Exemple #4
0
 def _setup_mixer_control(self):
     is_momentary = True
     mixer = MixerComponent(1)
     mixer.selected_strip().set_mute_button(
         SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                            KMK_PAD[9]))
     mixer.selected_strip().set_solo_button(
         SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                            KMK_PAD[13]))
     mixer.set_select_buttons(
         SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                            KMK_PAD[15]),
         SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                            KMK_PAD[14]))
     send_faders = []
     NUM_CONTROLLABLE_SENDS = 4
     for index in range(NUM_CONTROLLABLE_SENDS):
         send_faders.append(
             SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[index + 2]))
     mixer.selected_strip().set_volume_control(
         SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[0]))
     mixer.selected_strip().set_pan_control(
         SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[1]))
     mixer.selected_strip().set_send_controls(tuple(send_faders))
     mixer.set_prehear_volume_control(
         EncoderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[6],
                        Live.MidiMap.MapMode.absolute))
     mixer.master_strip().set_volume_control(
         SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[7]))
     return mixer
Exemple #5
0
    def _setup_mixer_control(self):
        is_momentary = True
        mixer = MixerComponent(NUM_TRACKS, 2, with_eqs=True, with_filters=True)
        for track in range(NUM_TRACKS):
            strip = mixer.channel_strip(track)
            strip.set_volume_control(SliderElement(MIDI_CC_TYPE, track, 23))
            strip.set_pan_control(EncoderElement(MIDI_CC_TYPE, track, 10, Live.MidiMap.MapMode.absolute))
            strip.set_send_controls((EncoderElement(MIDI_CC_TYPE, track, 19, Live.MidiMap.MapMode.absolute),
             EncoderElement(MIDI_CC_TYPE, track, 20, Live.MidiMap.MapMode.absolute)))
            strip.set_solo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 64))
            strip.set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 63))
            strip.set_crossfade_toggle(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 65))
            eq = mixer.track_eq(track)
            eq.set_gain_controls(tuple([ EncoderElement(MIDI_CC_TYPE, track, (18 - index), Live.MidiMap.MapMode.absolute) for index in range(3) ]))
            eq.set_cut_buttons(tuple([ ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, (62 - index)) for index in range(3) ]))
            filter = mixer.track_filter(track)
            filter.set_filter_controls(EncoderElement(MIDI_CC_TYPE, track, 22, Live.MidiMap.MapMode.absolute), EncoderElement(MIDI_CC_TYPE, track, 21, Live.MidiMap.MapMode.absolute))

        for ret_track in range(2):
            strip = mixer.return_strip(ret_track)
            strip.set_volume_control(SliderElement(MIDI_CC_TYPE, 12, (22 + ret_track)))
            strip.set_pan_control(EncoderElement(MIDI_CC_TYPE, 12, (20 + ret_track), Live.MidiMap.MapMode.absolute))
            strip.set_mute_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, (78 + ret_track)))

        mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 12, 8))
        mixer.set_prehear_volume_control(EncoderElement(MIDI_CC_TYPE, 12, 24, Live.MidiMap.MapMode.absolute))
        mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 12, 7))
        mixer.master_strip().set_pan_control(EncoderElement(MIDI_CC_TYPE, 12, 10, Live.MidiMap.MapMode.absolute))
        return mixer
Exemple #6
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)
 def _setup_mixer_control(self):
     is_momentary = True
     mixer = MixerComponent(1)
     mixer.selected_strip().set_mute_button(SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[9]))
     mixer.selected_strip().set_solo_button(SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[13]))
     mixer.set_select_buttons(SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[15]),
                              SysexButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, KMK_PAD[14]))
     send_faders = []
     NUM_CONTROLLABLE_SENDS = 4
     for index in range(NUM_CONTROLLABLE_SENDS):
         send_faders.append(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[index + 2]))
     mixer.selected_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[0]))
     mixer.selected_strip().set_pan_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[1]))
     mixer.selected_strip().set_send_controls(tuple(send_faders))
     mixer.set_prehear_volume_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[6], Live.MidiMap.MapMode.absolute))
     mixer.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, KMK_FADER[7]))
     return mixer
Exemple #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 = 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)
Exemple #9
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))
class VoidMaschine(ControlSurface):
  """
  Originally Created on Nov 7, 2010  :: Matt Howell
  Thanks to Hanz Petrov, Native Instruments, Ableton, Liine
  """
  

      
  def __init__(self, c_instance):
    """
    Constructor
    """
    ControlSurface.__init__(self, c_instance)
    self.name = 'VoidMaschine'
    self.log_message(self.name + " opened =-- @ "+ time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()))
    self.set_suppress_rebuild_requests(True)
    self._suppress_session_highlight = False
    self._suppress_send_midi = True
    self._suggested_input_port = MASCHINE_DEVICE_PORT_NAME
    self._suggested_output_port = MASCHINE_DEVICE_PORT_NAME
    self._shift_button = None
    self.transport = TransportComponent()
    self.transport.name = 'Transport'
    self.session = None
    self.session_zoom = None
    self.mixer = None
    self.back_to_arranger_button = None
    self.is_momentary = True
    self.bpmBeatTime = 0
    self.lastBeat = 0
    
    self._setup_transport_control()
    self._session = VoidSessionComponent(c_instance)
    self._session.name = 'Session_Control'
    
    self._setup_mixer_control()
    
    #self._session_zoom = SessionZoomingComponent(self._session)
    #self._session_zoom.name = 'Session_Overview'
    #self._session_zoom.set_button_matrix(self._session._matrix)
    
    self._set_back_to_arranger_button(ButtonElement(True, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_BACK_TO_ARRANGER))
    self.set_suppress_rebuild_requests(False)
    self._display = PhysicalDisplayElement(56, 8)
    self._void_message()
    self._register_timer_callback(self.update_controller)
    self._register_timer_callback(self.updateTempo)
    self._register_timer_callback(self.onTempoChange)
    
  def _void_message(self):
    self.sendScreenSysex(self.translateString((SYSEX_SCREEN_BUFFER_15 + 'VoidMaschine' + SYSEX_SCREEN_BUFFER_15)), 1)
    self.sendScreenSysex(self.translateString(('Voidrunner.com' + SYSEX_SCREEN_BUFFER_15 + '    maschine/ableton')), 2)

  def _setup_mixer_control(self):
    self.mixer = MixerComponent(0, 0, with_eqs=False, with_filters=False)
    master_volume_control = EncoderElement(MIDI_CC_TYPE, MIXER_CHANNEL, MASTER_VOLUME, Live.MidiMap.MapMode.absolute)
    booth_volume_control = EncoderElement(MIDI_CC_TYPE, MIXER_CHANNEL, MASTER_BOOTH, Live.MidiMap.MapMode.absolute)
    self.mixer.set_prehear_volume_control(booth_volume_control)
    self.mixer.master_strip().set_volume_control(master_volume_control)

  def _setup_transport_control(self):
    play_button = ButtonElement(self.is_momentary, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_PLAY)
    stop_button = ButtonElement(self.is_momentary, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_STOP)
    record_button = ButtonElement(self.is_momentary, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_RECORD)
    seek_ffwd_button = ButtonElement(self.is_momentary, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_SEEK_FFWD)
    seek_rwd_button = ButtonElement(self.is_momentary, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_SEEK_RWD)
    tap_tempo_button = ButtonElement(self.is_momentary, MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_TAP_TEMPO)
    tempo_control = EncoderElement(MIDI_CC_TYPE, TRANSPORT_CHANNEL, TRANSPORT_COARSE_TEMPO, Live.MidiMap.MapMode.absolute)
    play_button.name = 'Play_Button'
    stop_button.name = 'Stop_Button'
    record_button.name = 'Record_Button'
    seek_ffwd_button.name = 'Seek_FFWD_Button'
    seek_rwd_button.name = 'Seek_RWD_Button'
    tap_tempo_button.name = 'Tap_Tempo_Button'
    self.transport.set_play_button(play_button)
    self.transport.set_stop_button(stop_button)
    self.transport.set_record_button(record_button)
    self.transport.set_tap_tempo_button(tap_tempo_button)
    self.transport.set_tempo_control(tempo_control)
    self.transport.set_seek_buttons(seek_ffwd_button, seek_rwd_button)

  def _set_back_to_arranger_button(self, button):
    button.add_value_listener(self.back_to_arranger)
    self.back_to_arranger_button = button

  def disconnect(self):
    self.send_midi((240, 0, 66, 89, 69, 247)) #goodbye message in sysex stream
  
  def send_midi(self, midi_event_bytes):
    """
    Use this function to send MIDI events through Live to the _real_ MIDI devices
    that this script is assigned to.
    """
    assert isinstance(midi_event_bytes, tuple)
    self._send_midi(midi_event_bytes)
    return True

  def translateString(self, text):
    """
    Convert a string into a sysex safe string
    """
    result = ()
    length = len(text)
    for i in range(0, length):
      charCode = ord(text[i])
      if (charCode < 32):
        charCode = 32
      elif (charCode > 127):
        charCode = 127
      result = (result + (charCode,))
    
    return result
  
  def sendScreenSysex(self, data, line=1):
    """
    Data must be a tuple of bytes, remember only 7-bit data is allowed for sysex
    """
    if not data:
      pass
    if(line==1):
        self._send_midi(((SYSEX_SCREEN_BEGIN_LINE_1 + data) + SYSEX_SCREEN_END))
    else:
        if(line==2):
            self._send_midi(((SYSEX_SCREEN_BEGIN_LINE_2 + data) + SYSEX_SCREEN_END))
  
  def send_value(self, msg_type, channel, id, value, force_send = False):
    assert (value != None)
    assert isinstance(value, int)
    assert (value in range(128))
    
    data_byte1 = id
    data_byte2 = value
    status_byte = channel
    if (msg_type == MIDI_NOTE_TYPE):
      status_byte += MIDI_NOTE_ON_STATUS
    elif (msg_type == MIDI_CC_TYPE):
      status_byte += MIDI_CC_STATUS
    else:
        assert False
    self._send_midi((status_byte, data_byte1, data_byte2))
  
  def back_to_arranger(self, *args, **kwargs):
    self.song().back_to_arranger = False
  
  def update_controller(self):
    """
    controller event loop
    this may also update every 100 miliseconds.
    decoupling the data updates from live and the controller communication
    may help keep latency to a minimum.
    """
    
  def onTempoChange(self):      
    self.bpmBeatTime = self.song().get_current_beats_song_time()
  
  def updateTempo(self):                          
    if self.song().is_playing:
      if (self.bpmBeatTime.beats > self.lastBeat):
        self.updateBPMLightOff()
      else:
        self.updateBPMLightOn()
  
  def updateBPMLightOn(self):  
    self.transport._play_button.turn_on()
    #self.send_value(MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_TEMPO, MASCHINE_DISPLAY_BPM)

  def updateBPMLightOff(self): 
    self.transport._play_button.turn_off()
    #self.send_value(MIDI_NOTE_TYPE, TRANSPORT_CHANNEL, TRANSPORT_TEMPO, 0)
    
Exemple #11
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
Exemple #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 = 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)