Пример #1
0
 def _init_transport_component(self, transport_controls, global_channel):
     is_momentary = True
     if transport_controls:
         transport = TransportComponent()
         transport.name = 'Transport'
         if 'STOP' in transport_controls.keys() and transport_controls['STOP'] in range(128):
             stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['STOP'])
             stop_button.name = 'Stop_Button'
             transport.set_stop_button(stop_button)
         if 'PLAY' in transport_controls.keys() and transport_controls['PLAY'] in range(128):
             play_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['PLAY'])
             play_button.name = 'Play_Button'
             transport.set_play_button(play_button)
         if 'REC' in transport_controls.keys() and transport_controls['REC'] in range(128):
             rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['REC'])
             rec_button.name = 'Record_Button'
             transport.set_record_button(rec_button)
         if 'LOOP' in transport_controls.keys() and transport_controls['LOOP'] in range(128):
             loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['LOOP'])
             loop_button.name = 'Loop_Button'
             transport.set_loop_button(loop_button)
         ffwd_button = None
         rwd_button = None
         momentary_seek = 'NORELEASE' not in transport_controls.keys()
         if 'FFWD' in transport_controls.keys() and transport_controls['FFWD'] in range(128):
             ffwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['FFWD'])
             ffwd_button.name = 'FFwd_Button'
         if 'RWD' in transport_controls.keys() and transport_controls['RWD'] in range(128):
             rwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['RWD'])
             rwd_button.name = 'Rwd_Button'
         transport.set_seek_buttons(ffwd_button, rwd_button)
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            is_momentary = True
            self._suggested_input_port = 'Oxygen'
            self._suggested_output_port = 'Oxygen'
            self._has_slider_section = True
            self._device_selection_follows_track_selection = True
            self._shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 57)
            self._shift_button.add_value_listener(self._shift_value)
            self._mixer = SpecialMixerComponent(NUM_TRACKS)
            self._mute_solo_buttons = []
            self._track_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 111)
            self._track_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 110)
            self._master_slider = SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 41)
            for index in range(NUM_TRACKS):
                self._mute_solo_buttons.append(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 49 + index))
                self._mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 33 + index))

            self._shift_value(0)
            self._mixer.master_strip().set_volume_control(self._master_slider)
            self._mixer.selected_strip().set_volume_control(None)
            device = DeviceComponent()
            device.set_parameter_controls(tuple([ EncoderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 17 + index, Live.MidiMap.MapMode.absolute) for index in range(8) ]))
            self.set_device_component(device)
            ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 115)
            rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 114)
            loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 113)
            transport = TransportComponent()
            transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 116))
            transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 117))
            transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 118))
            session = SessionComponent(0, 0)
            transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button)
        return
Пример #3
0
	def _setup_transport_control(self):
		is_momentary = True # We'll only be using momentary buttons here
		transport = TransportComponent() #Instantiate a Transport Component
		"""set up the buttons"""
		transport.set_play_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 69)) #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module
		transport.set_stop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 70))
		#transport.set_record_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 66))
		#transport.set_overdub_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 68))
		#transport.set_nudge_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 73)) #(up_button, down_button)
		#transport.set_tap_tempo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80))
		#transport.set_metronome_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80)) #For some reason, in Ver 7.x.x this method's name has no trailing "e" , and must be called as "set_metronom_button()"...
		#transport.set_loop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 82))
		#transport.set_punch_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 85), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 87)) #(in_button, out_button)
		#transport.set_seek_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 90), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 92)) # (ffwd_button, rwd_button)
		#"""set up the sliders"""
		#transport.set_tempo_control(SliderElement(MIDI_CC_TYPE, CHANNEL, 26), SliderElement(MIDI_CC_TYPE, CHANNEL, 25)) #(control, fine_control)
		#transport.set_song_position_control(SliderElement(MIDI_CC_TYPE, CHANNEL, 24))
		
		device_param_controls = []
		effects_knob_cc = [17,16,9,8,19,18,11,10]
		device = DeviceComponent()
		for index in range(8):
			device_param_controls.append(EncoderElement(MIDI_CC_TYPE, 0, effects_knob_cc[index], Live.MidiMap.MapMode.absolute))
		device.set_parameter_controls(tuple(device_param_controls))
		self.set_device_component(device)
Пример #4
0
	def _setup_transport_control(self):
		is_momentary = True # We'll only be using momentary buttons here
		transport = TransportComponent() #Instantiate a Transport Component
		"""set up the buttons"""
		transport.set_play_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 69)) #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module
		transport.set_stop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 70))
		#transport.set_record_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 66))
		#transport.set_overdub_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 68))
		#transport.set_nudge_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 73)) #(up_button, down_button)
		#transport.set_tap_tempo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80))
		#transport.set_metronome_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80)) #For some reason, in Ver 7.x.x this method's name has no trailing "e" , and must be called as "set_metronom_button()"...
		#transport.set_loop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 82))
		#transport.set_punch_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 85), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 87)) #(in_button, out_button)
		#transport.set_seek_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 90), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 92)) # (ffwd_button, rwd_button)
		#"""set up the sliders"""
		#transport.set_tempo_control(SliderElement(MIDI_CC_TYPE, CHANNEL, 26), SliderElement(MIDI_CC_TYPE, CHANNEL, 25)) #(control, fine_control)
		#transport.set_song_position_control(SliderElement(MIDI_CC_TYPE, CHANNEL, 24))
		
		device_param_controls = []
		effects_knob_cc = [17,16,9,8,19,18,11,10]
		device = DeviceComponent()
		for index in range(8):
			device_param_controls.append(EncoderElement(MIDI_CC_TYPE, 0, effects_knob_cc[index], Live.MidiMap.MapMode.absolute))
		device.set_parameter_controls(tuple(device_param_controls))
		self.set_device_component(device)
Пример #5
0
 def __init__(self, c_instance):
     ControlSurface.__init__(self, c_instance)
     with self.component_guard():
         self._suggested_input_port = u'HyperControl'
         self._suggested_output_port = u'HyperControl'
         self.set_pad_translations(PAD_TRANSLATIONS)
         stop_button = make_button(116)
         play_button = make_button(117)
         record_button = make_button(118)
         select_button = make_button(98)
         nav_left_button = make_button(99)
         nav_right_button = make_button(100)
         nav_up_button = make_button(101)
         nav_down_button = make_button(102)
         mixer_modes_toggle = make_button(58)
         mixer_or_device_toggle = make_button(59)
         hypercontrol_mode_toggle = make_button(60)
         encoders = tuple([ make_encoder(33 + index) for index in range(8) ])
         transport = TransportComponent()
         transport.set_stop_button(stop_button)
         transport.set_play_button(play_button)
         transport.set_record_button(record_button)
         session = SessionComponent(8, 0)
         device = BestBankDeviceComponent(device_selection_follows_track_selection=True)
         self.set_device_component(device)
         device_nav = DeviceNavComponent()
         mixer = SpecialMixerComponent(NUM_TRACKS)
         session.set_mixer(mixer)
         mixer_encoder_modes = EncoderMixerModeSelector(mixer)
         mixer_encoder_modes.set_mode_toggle(mixer_modes_toggle)
         mixer_or_device = MixerOrDeviceModeSelector(encoders, select_button, nav_up_button, nav_down_button, nav_left_button, nav_right_button, mixer, session, device, mixer_encoder_modes, device_nav)
         mixer_or_device.set_mode_buttons((mixer_modes_toggle, mixer_or_device_toggle, hypercontrol_mode_toggle))
Пример #6
0
 def __init__(self, c_instance):
     ControlSurface.__init__(self, c_instance)
     transport = TransportComponent()
     transport.set_play_button(ButtonElement(True, 0, ABLETON["GENERAL_CHANNEL"], ABLETON["START_NOTE"]))
     transport.set_stop_button(ButtonElement(True, 0, ABLETON["GENERAL_CHANNEL"], ABLETON["STOP_NOTE"]))
     self.log_message("MiniCommand surface")
     self.get_track_name(0)
 def __init__(self, c_instance):
     ControlSurface.__init__(self, c_instance)
     with self.component_guard():
         self._suggested_input_port = 'HyperControl'
         self._suggested_output_port = 'HyperControl'
         self._device_selection_follows_track_selection = True
         self.set_pad_translations(PAD_TRANSLATIONS)
         stop_button = make_button(116)
         play_button = make_button(117)
         record_button = make_button(118)
         select_button = make_button(98)
         nav_left_button = make_button(99)
         nav_right_button = make_button(100)
         nav_up_button = make_button(101)
         nav_down_button = make_button(102)
         mixer_modes_toggle = make_button(58)
         mixer_or_device_toggle = make_button(59)
         hypercontrol_mode_toggle = make_button(60)
         encoders = tuple([ make_encoder(33 + index) for index in range(8) ])
         transport = TransportComponent()
         transport.set_stop_button(stop_button)
         transport.set_play_button(play_button)
         transport.set_record_button(record_button)
         session = SessionComponent(8, 0)
         device = BestBankDeviceComponent()
         self.set_device_component(device)
         device_nav = DeviceNavComponent()
         mixer = SpecialMixerComponent(NUM_TRACKS)
         session.set_mixer(mixer)
         mixer_encoder_modes = EncoderMixerModeSelector(mixer)
         mixer_encoder_modes.set_mode_toggle(mixer_modes_toggle)
         mixer_or_device = MixerOrDeviceModeSelector(encoders, select_button, nav_up_button, nav_down_button, nav_left_button, nav_right_button, mixer, session, device, mixer_encoder_modes, device_nav)
         mixer_or_device.set_mode_buttons((mixer_modes_toggle, mixer_or_device_toggle, hypercontrol_mode_toggle))
 def _init_transport_component(self, transport_controls, global_channel):
     is_momentary = True
     if transport_controls:
         transport = TransportComponent()
         transport.name = "Transport"
         if "STOP" in transport_controls.keys() and transport_controls["STOP"] in range(128):
             stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls["STOP"])
             stop_button.name = "Stop_Button"
             transport.set_stop_button(stop_button)
         if "PLAY" in transport_controls.keys() and transport_controls["PLAY"] in range(128):
             play_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls["PLAY"])
             play_button.name = "Play_Button"
             transport.set_play_button(play_button)
         if "REC" in transport_controls.keys() and transport_controls["REC"] in range(128):
             rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls["REC"])
             rec_button.name = "Record_Button"
             transport.set_record_button(rec_button)
         if "LOOP" in transport_controls.keys() and transport_controls["LOOP"] in range(128):
             loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls["LOOP"])
             loop_button.name = "Loop_Button"
             transport.set_loop_button(loop_button)
         ffwd_button = None
         rwd_button = None
         momentary_seek = "NORELEASE" not in transport_controls.keys()
         if "FFWD" in transport_controls.keys() and transport_controls["FFWD"] in range(128):
             ffwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls["FFWD"])
             ffwd_button.name = "FFwd_Button"
         if "RWD" in transport_controls.keys() and transport_controls["RWD"] in range(128):
             rwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls["RWD"])
             rwd_button.name = "Rwd_Button"
         transport.set_seek_buttons(ffwd_button, rwd_button)
Пример #9
0
    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]))
Пример #10
0
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            is_momentary = True
            self._suggested_input_port = 'Oxygen'
            self._suggested_output_port = 'Oxygen'
            self._has_slider_section = True
            self._device_selection_follows_track_selection = True
            self._shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 57)
            self._shift_button.add_value_listener(self._shift_value)
            self._mixer = SpecialMixerComponent(NUM_TRACKS)
            self._mute_solo_buttons = []
            self._track_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 111)
            self._track_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 110)
            self._master_slider = SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 41)
            for index in range(NUM_TRACKS):
                self._mute_solo_buttons.append(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 49 + index))
                self._mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 33 + index))

            self._shift_value(0)
            self._mixer.master_strip().set_volume_control(self._master_slider)
            self._mixer.selected_strip().set_volume_control(None)
            device = DeviceComponent()
            device.set_parameter_controls(tuple([ EncoderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 17 + index, Live.MidiMap.MapMode.absolute) for index in range(8) ]))
            self.set_device_component(device)
            ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 115)
            rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 114)
            loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 113)
            transport = TransportComponent()
            transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 116))
            transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 117))
            transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 118))
            session = SessionComponent(0, 0)
            transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button)
Пример #11
0
 def _setup_transport(self):
     is_momentary = True
     transport = TransportComponent()
     studiotransport = MaschineTransport()
     playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108)
     stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110)
     recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109)
     overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107)
     metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104)
     eventRecButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 98)
     playButton.name = 'Play'
     stopButton.name = 'Stop'
     recordButton.name = 'Record'
     overdubButton.name = 'Overdub'
     metrononmeButton.name = 'Metronome'
     transport.set_play_button(playButton)
     transport.set_stop_button(stopButton)
     transport.set_record_button(recordButton)
     transport.set_overdub_button(overdubButton)
     transport.set_metronome_button(metrononmeButton)
     studiotransport.set_session_auto_button(eventRecButton)
     studiotransport.set_arrangement_overdub_button(
         StateButton(is_momentary, MIDI_CC_TYPE, 0, 106))
     studiotransport.set_back_arrange_button(
         StateButton(is_momentary, MIDI_CC_TYPE, 0, 105))
     transport.set_nudge_buttons(
         StateButton(is_momentary, MIDI_CC_TYPE, 1, 51),
         StateButton(is_momentary, MIDI_CC_TYPE, 1, 50))
     punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52)
     punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53)
     punchinbutton.name = 'Punch In'
     punchoutbutton.name = 'Punch Out'
     transport.set_punch_buttons(punchinbutton, punchoutbutton)
     transport.set_loop_button(
         StateButton(is_momentary, MIDI_CC_TYPE, 1, 54))
     self.song_follow_button = ButtonElement(True, MIDI_CC_TYPE, 2, 98)
     self._do_song_follow.subject = self.song_follow_button
     self._song_follow_changed.subject = self.song().view
     self._song_follow_changed()
     self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59)
     self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58)
     transport.set_seek_buttons(self.transp_ff_button,
                                self.transp_rw_button)
     self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 105)
     self.xfadeKnob.connect_to(
         self.song().master_track.mixer_device.crossfader)
     self.master_knob = SliderElement(MIDI_CC_TYPE, 0, 99)
     self.master_knob.connect_to(
         self.song().master_track.mixer_device.volume)
     self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88)
     self._do_tap_tempo.subject = self.tap_button
     self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1,
                                              55)
     self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56)
     self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57)
     self._do_toggle_cue.subject = self.cue_add_delete_button
     self._do_toggle_prev_cue.subject = self.cue_prev_button
     self._do_toggle_next_cue.subject = self.cue_next_button
Пример #12
0
 def _setup_transport_control(self):
     transport_button = [
         ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                                   TRANSPORT_BUTTONS[index])
         for index in range(4)
     ]
     #transport_button.set_on_off_values(LED_ON, LED_OFF)
     transport = TransportComponent()
     transport.set_play_button(transport_button[0])
     transport.set_stop_button(transport_button[1])
Пример #13
0
 def __init__(self, c_instance):
     ControlSurface.__init__(self, c_instance)
     transport = TransportComponent()
     transport.set_play_button(
         ButtonElement(True, 0, ABLETON["GENERAL_CHANNEL"],
                       ABLETON["START_NOTE"]))
     transport.set_stop_button(
         ButtonElement(True, 0, ABLETON["GENERAL_CHANNEL"],
                       ABLETON["STOP_NOTE"]))
     self.log_message("MiniCommand surface")
     self.get_track_name(0)
Пример #14
0
 def _setup_transport(self):
     is_momentary = True
     transport = TransportComponent()
     self.__play_button = StateButton(is_momentary,
                                      MIDI_CC_TYPE,
                                      BASE_CONTROL_CHANNEL,
                                      CC_PLAY_BUTTON,
                                      name='Play_Button')
     self.__restart_button = StateButton(True, MIDI_CC_TYPE,
                                         BASE_CONTROL_CHANNEL,
                                         CC_RESTART_BUTTON)
     stop_button = StateButton(not is_momentary,
                               MIDI_CC_TYPE,
                               BASE_CONTROL_CHANNEL,
                               CC_STOP_BUTTON,
                               name='Stop_Button')
     self._rec_button = StateButton(is_momentary,
                                    MIDI_CC_TYPE,
                                    BASE_CONTROL_CHANNEL,
                                    CC_RECORD_BUTTON,
                                    name='Record_Button')
     metrononme_button = StateButton(is_momentary,
                                     MIDI_CC_TYPE,
                                     BASE_CONTROL_CHANNEL,
                                     CC_METRONOME_BUTTON,
                                     name='Metronome_Button')
     self._song_follow_button = StateButton(is_momentary,
                                            MIDI_CC_TYPE,
                                            BASE_CONTROL_CHANNEL,
                                            CC_FOLLOW_BUTTON,
                                            name='Follow_Button')
     self._do_rec_button.subject = self._rec_button
     if self._has_stop_button:
         transport.set_play_button(self.__play_button)
         transport.set_stop_button(stop_button)
     else:
         self._hand_play_pressed.subject = self.__play_button
         self._listen_playing.subject = self.song()
     self._stopall_button = StateButton(True, MIDI_CC_TYPE, 0,
                                        CC_ALL_BUTTON)
     self._do_stop_all.subject = self._stopall_button
     self._auto_button = StateButton(True,
                                     MIDI_CC_TYPE,
                                     0,
                                     CC_AUTO_BUTTON,
                                     name='Auto_Button')
     self._handle_automation_record.subject = self._auto_button
     self._listen_automation_record.subject = self.song()
     self._handle_restart_button.subject = self.__restart_button
     self._handle_follows_button.subject = self._song_follow_button
     self._follow_song_changed.subject = self.song().view
     transport.set_metronome_button(metrononme_button)
     self._listen_overdub.subject = self.song()
Пример #15
0
    def _setup_components(self):
        
        # Session

        self._session = SessionComponent(8, len(self._scene_launch_buttons))
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(self._scene_launch_button)
        self._session.set_stop_all_clips_button(self._scene_stop_button)

        for index in range(8):
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_launch_button(self._clip_launch_buttons[index])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(tuple(self._clip_stop_buttons))

        # Undo

        self._do_undo.subject = self._clip_undo_button;

        # Transport

        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(self._stop_button)
        transport.set_play_button(self._play_button)
        transport.set_record_button(self._rec_button)
        transport.set_loop_button(self._loop_button)

        self._transport_view_modes = TransportViewModeSelector(transport, self._session, self._ffwd_button, self._rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

        session_recording = SessionRecordingComponent(ClipCreator(), ViewControlComponent(), name='Session_Recording', is_enabled=False, layer=Layer(record_button=self._overdub_button))

        # Device

        # device = DeviceComponent()
        # device.name = 'Device_Component'
        # self.set_device_component(device)
        # device.set_parameter_controls(self._encoders)

        # Navigation

        self._session_navigation = SessionNavigationComponent(name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

        # Playing
        # self._session.set_scene_launch_buttons(tuple(self._scene_launch_buttons))
        for index in range(len(self._scene_launch_buttons)):
            scene = self._session.scene(index)
            scene.set_launch_button(self._scene_launch_buttons[index])
Пример #16
0
 def _setup_mixer_control(self):
     """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))
 def _setup_transport(self):
     is_momentary = True
     transport = TransportComponent()
     studiotransport = MaschineTransport()
     playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108)
     stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110)
     recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109)
     overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107)
     metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104)
     eventRecButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 98)
     playButton.name = 'Play'
     stopButton.name = 'Stop'
     recordButton.name = 'Record'
     overdubButton.name = 'Overdub'
     metrononmeButton.name = 'Metronome'
     transport.set_play_button(playButton)
     transport.set_stop_button(stopButton)
     transport.set_record_button(recordButton)
     transport.set_overdub_button(overdubButton)
     transport.set_metronome_button(metrononmeButton)
     studiotransport.set_session_auto_button(eventRecButton)
     studiotransport.set_arrangement_overdub_button(StateButton(is_momentary, MIDI_CC_TYPE, 0, 106))
     studiotransport.set_back_arrange_button(StateButton(is_momentary, MIDI_CC_TYPE, 0, 105))
     transport.set_nudge_buttons(StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50))
     punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52)
     punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53)
     punchinbutton.name = 'Punch In'
     punchoutbutton.name = 'Punch Out'
     transport.set_punch_buttons(punchinbutton, punchoutbutton)
     transport.set_loop_button(StateButton(is_momentary, MIDI_CC_TYPE, 1, 54))
     self.song_follow_button = ButtonElement(True, MIDI_CC_TYPE, 2, 98)
     self._do_song_follow.subject = self.song_follow_button
     self._song_follow_changed.subject = self.song().view
     self._song_follow_changed()
     self.prehear_knob = SliderElement(MIDI_CC_TYPE, 0, 41)
     self.prehear_knob.connect_to(self.song().master_track.mixer_device.cue_volume)
     self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59)
     self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58)
     transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button)
     self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 105)
     self.xfadeKnob.connect_to(self.song().master_track.mixer_device.crossfader)
     self.master_knob = SliderElement(MIDI_CC_TYPE, 0, 99)
     self.master_knob.connect_to(self.song().master_track.mixer_device.volume)
     self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88)
     self._do_tap_tempo.subject = self.tap_button
     self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55)
     self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56)
     self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57)
     self._do_toggle_cue.subject = self.cue_add_delete_button
     self._do_toggle_prev_cue.subject = self.cue_prev_button
     self._do_toggle_next_cue.subject = self.cue_next_button
Пример #18
0
 def _setup_transport(self):
     rwd_button = make_button(112, "Rwd_Button")
     ffwd_button = make_button(113, "FFwd_Button")
     stop_button = make_button(114, "Stop_Button")
     play_button = make_button(115, "Play_Button")
     loop_button = make_button(116, "Loop_Button")
     rec_button = make_button(117, "Record_Button")
     transport = TransportComponent()
     transport.name = "Transport"
     transport.set_stop_button(stop_button)
     transport.set_play_button(play_button)
     transport.set_record_button(rec_button)
     transport.set_loop_button(loop_button)
     self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button)
     self._transport_view_modes.name = "Transport_View_Modes"
Пример #19
0
 def _setup_transport(self):
     rwd_button = make_button(112, 'Rwd_Button')
     ffwd_button = make_button(113, 'FFwd_Button')
     stop_button = make_button(114, 'Stop_Button')
     play_button = make_button(115, 'Play_Button')
     loop_button = make_button(116, 'Loop_Button')
     rec_button = make_button(117, 'Record_Button')
     transport = TransportComponent()
     transport.name = 'Transport'
     transport.set_stop_button(stop_button)
     transport.set_play_button(play_button)
     transport.set_record_button(rec_button)
     transport.set_loop_button(loop_button)
     self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button)
     self._transport_view_modes.name = 'Transport_View_Modes'
 def _setup_transport_control(self):
     is_momentary = True # We'll only be using momentary buttons here
     transport = TransportComponent() #Instantiate a Transport Component
     """set up the buttons"""
     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
     transport.set_stop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61))
     transport.set_record_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 62))
     #transport.set_overdub_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 68))
     #transport.set_nudge_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 75), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 73)) #(up_button, down_button)
 #    transport.set_tap_tempo_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 63))
     #transport.set_metronome_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80)) #For some reason, in Ver 7.x.x this method's name has no trailing "e" , and must be called as "set_metronom_button()"...
     #transport.set_loop_button(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 82))
     #transport.set_punch_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 85), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 87)) #(in_button, out_button)
     #transport.set_seek_buttons(ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 90), ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 92)) # (ffwd_button, rwd_button)
     """set up the sliders"""
Пример #21
0
 def _setup_transport(self):
     rwd_button = make_button(112, 'Rwd_Button')
     ffwd_button = make_button(113, 'FFwd_Button')
     stop_button = make_button(114, 'Stop_Button')
     play_button = make_button(115, 'Play_Button')
     loop_button = make_button(116, 'Loop_Button')
     rec_button = make_button(117, 'Record_Button')
     transport = TransportComponent()
     transport.name = 'Transport'
     transport.set_stop_button(stop_button)
     transport.set_play_button(play_button)
     transport.set_record_button(rec_button)
     transport.set_loop_button(loop_button)
     self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button)
     self._transport_view_modes.name = 'Transport_View_Modes'
Пример #22
0
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._suppress_send_midi = True
            self._suppress_session_highlight = True
            self._control_is_with_automap = False
            is_momentary = True
            self._suggested_input_port = 'Akai MPD26'
            self._suggested_output_port = 'Akai MPD26'

            """SESSION ViEW"""
            session = SessionComponent(4,4)
            session.name = 'Session_Control'
            matrix = ButtonMatrixElement()
            matrix.name = 'Button_Matrix'
            up_button = ButtonElement(False, MIDI_CC_TYPE, 0, 115)
            down_button = ButtonElement(False, MIDI_CC_TYPE, 0, 116)
            up_button.name = 'Bank_Select_Up_Button'
            down_button.name = 'Bank_Select_Down_Button'
            session.set_scene_bank_buttons(down_button, up_button)
            for row in range(4):
                button_row = []
                button_notes = [48, 44, 40, 36]
                scene = session.scene(row)
                scene.name = 'Scene_' + str(row)
                for column in range(4):
                    button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, button_notes[row] +  column )
                    button.name = str(column) + '_Clip_' + str(row) + '_Button'
                    button_row.append(button)
                    clip_slot = scene.clip_slot(column)
                    clip_slot.name = str(column) + '_Clip_Slot_' + str(row)
                    clip_slot.set_launch_button(button)
                matrix.add_row(tuple(button_row))

            self._suppress_session_highlight = False
            self._suppress_send_midi = False
            self.set_highlighting_session_component(session)
            #self._set_session_highlight(0,session._scene_offset,4,4,False)
            
            """TRANSPORT CONTROLS"""
            stop_button = ButtonElement(False, MIDI_CC_TYPE, 0, 117)
            play_button = ButtonElement(False, MIDI_CC_TYPE, 0, 118)
            transport = TransportComponent()
            transport.set_stop_button(stop_button)
            transport.set_play_button(play_button)
Пример #23
0
 def _init_transport_component(self, transport_controls, global_channel, macro_map_mode):
     is_momentary = True
     if transport_controls:
         transport = TransportComponent()
         transport.name = 'Transport'
         #THIS IS NEW STUFF
         #if 'TEMPO' in transport_control.keys() and transport_controls['TEMPO'] in range(128):
         tempo_slider = EncoderElement(MIDI_CC_TYPE, global_channel, 1, macro_map_mode)
         tempo_slider.name = 'Tempo_Slider'
         transport.set_tempo_control(tempo_slider)
         #END NEW STUFF
         if 'STOP' in transport_controls.keys() and transport_controls['STOP'] in range(128):
             stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['STOP'])
             stop_button.name = 'Stop_Button'
             transport.set_stop_button(stop_button)
         
         if 'PLAY' in transport_controls.keys() and transport_controls['PLAY'] in range(128):
             play_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['PLAY'])
             play_button.name = 'Play_Button'
             transport.set_play_button(play_button)
         
         if 'REC' in transport_controls.keys() and transport_controls['REC'] in range(128):
             rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['REC'])
             rec_button.name = 'Record_Button'
             transport.set_record_button(rec_button)
         
         if 'LOOP' in transport_controls.keys() and transport_controls['LOOP'] in range(128):
             loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['LOOP'])
             loop_button.name = 'Loop_Button'
             transport.set_loop_button(loop_button)
         
         ffwd_button = None
         rwd_button = None
         momentary_seek = 'NORELEASE' not in transport_controls.keys()
         if 'FFWD' in transport_controls.keys() and transport_controls['FFWD'] in range(128):
             ffwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['FFWD'])
             ffwd_button.name = 'FFwd_Button'
         
         if 'RWD' in transport_controls.keys() and transport_controls['RWD'] in range(128):
             rwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['RWD'])
             rwd_button.name = 'Rwd_Button'
         
         transport.set_seek_buttons(ffwd_button, rwd_button)
Пример #24
0
 def _init_transport_component(self, transport_controls, global_channel, macro_map_mode):
     is_momentary = True
     if transport_controls:
         transport = TransportComponent()
         transport.name = 'Transport'
         #THIS IS NEW STUFF
         #if 'TEMPO' in transport_control.keys() and transport_controls['TEMPO'] in range(128):
         tempo_slider = EncoderElement(MIDI_CC_TYPE, global_channel, 1, macro_map_mode)
         tempo_slider.name = 'Tempo_Slider'
         transport.set_tempo_control(tempo_slider)
         #END NEW STUFF
         if 'STOP' in transport_controls.keys() and transport_controls['STOP'] in range(128):
             stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['STOP'])
             stop_button.name = 'Stop_Button'
             transport.set_stop_button(stop_button)
         
         if 'PLAY' in transport_controls.keys() and transport_controls['PLAY'] in range(128):
             play_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['PLAY'])
             play_button.name = 'Play_Button'
             transport.set_play_button(play_button)
         
         if 'REC' in transport_controls.keys() and transport_controls['REC'] in range(128):
             rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['REC'])
             rec_button.name = 'Record_Button'
             transport.set_record_button(rec_button)
         
         if 'LOOP' in transport_controls.keys() and transport_controls['LOOP'] in range(128):
             loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, transport_controls['LOOP'])
             loop_button.name = 'Loop_Button'
             transport.set_loop_button(loop_button)
         
         ffwd_button = None
         rwd_button = None
         momentary_seek = 'NORELEASE' not in transport_controls.keys()
         if 'FFWD' in transport_controls.keys() and transport_controls['FFWD'] in range(128):
             ffwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['FFWD'])
             ffwd_button.name = 'FFwd_Button'
         
         if 'RWD' in transport_controls.keys() and transport_controls['RWD'] in range(128):
             rwd_button = ButtonElement(momentary_seek, MIDI_CC_TYPE, global_channel, transport_controls['RWD'])
             rwd_button.name = 'Rwd_Button'
         
         transport.set_seek_buttons(ffwd_button, rwd_button)
Пример #25
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))
Пример #26
0
    def _setup_transport_control(self):
        is_momentary = True

        """ Instantiate a Transport Component """
        transport = TransportComponent()

        """ Buttons declaration """
        button_play = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_transport_play_button)
        button_stop = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_transport_stop_button)
        button_record = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_transport_record_button)
        button_loop = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_transport_loop_button)
        button_seek_ffwd = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_transport_seek_ffwd)
        button_seek_rwd = ButtonElement(is_momentary, MIDI_CC_TYPE, midi_channel, midi_transport_seek_rwd)

        """ Buttons association """
        transport.set_play_button(button_play)
        transport.set_stop_button(button_stop)
        transport.set_record_button(button_record)
        transport.set_loop_button(button_loop)
        transport.set_seek_buttons(button_seek_ffwd, button_seek_rwd)
Пример #27
0
    def _init_transport_component(self):
        is_momentary = True
        momentary_seek = False
        global_channel = 0
        transport = TransportComponent()
        transport.name = 'Transport'
        
        # rec 
        rec_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, REC_CC)
        rec_button.name = 'Record_Button'
        transport.set_record_button(rec_button)

        # play
        play_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, PLAY_CC)
        play_button.name = 'Play_Button'
        transport.set_play_button(play_button)

        # stop
        stop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, global_channel, STOP_CC)
        stop_button.name = 'Stop_Button'
        transport.set_stop_button(stop_button)
Пример #28
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))
Пример #29
0
 def _setup_transport_control(self):
     is_momentary = True  # We'll only be using momentary buttons here
     transport = TransportComponent()  #Instantiate a Transport Component
     return
     """set up the buttons"""
     transport.set_play_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61)
     )  #ButtonElement(is_momentary, msg_type, channel, identifier) Note that the MIDI_NOTE_TYPE constant is defined in the InputControlElement module
     transport.set_stop_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 63))
     transport.set_record_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 66))
     transport.set_overdub_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 68))
     transport.set_nudge_buttons(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 75),
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       73))  #(up_button, down_button)
     transport.set_tap_tempo_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 78))
     transport.set_metronome_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80)
     )  #For some reason, in Ver 7.x.x this method's name has no trailing "e" , and must be called as "set_metronom_button()"...
     transport.set_loop_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 82))
     transport.set_punch_buttons(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 85),
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       87))  #(in_button, out_button)
     transport.set_seek_buttons(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 90),
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                       92))  # (ffwd_button, rwd_button)
     """set up the sliders"""
     transport.set_tempo_control(
         SliderElement(MIDI_CC_TYPE, CHANNEL, 26),
         SliderElement(MIDI_CC_TYPE, CHANNEL, 25))  #(control, fine_control)
     transport.set_song_position_control(
         SliderElement(MIDI_CC_TYPE, CHANNEL, 24))
 def _setup_transport(self):
     is_momentary = True
     transport = TransportComponent()
     playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108)
     stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110)
     recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109)
     overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107)
     metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104)
     playButton.name = 'Play'
     stopButton.name = 'Stop'
     recordButton.name = 'Record'
     overdubButton.name = 'Overdub'
     metrononmeButton.name = 'Metronome'
     transport.set_play_button(playButton)
     transport.set_stop_button(stopButton)
     transport.set_record_button(recordButton)
     transport.set_overdub_button(overdubButton)
     transport.set_metronome_button(metrononmeButton)
     transport.set_nudge_buttons(StateButton(is_momentary, MIDI_CC_TYPE, 1, 51), StateButton(is_momentary, MIDI_CC_TYPE, 1, 50))
     punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52)
     punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53)
     punchinbutton.name = 'Punch In'
     punchoutbutton.name = 'Punch Out'
     transport.set_punch_buttons(punchinbutton, punchoutbutton)
     transport.set_loop_button(StateButton(is_momentary, MIDI_CC_TYPE, 1, 54))
     self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59)
     self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58)
     transport.set_seek_buttons(self.transp_ff_button, self.transp_rw_button)
     self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 100)
     self.xfadeKnob.connect_to(self.song().master_track.mixer_device.crossfader)
     self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88)
     self.tap_button.add_value_listener(self._do_tap_tempo)
     self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 55)
     self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56)
     self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57)
     self.cue_add_delete_button.add_value_listener(self._do_toggle_cue)
     self.cue_prev_button.add_value_listener(self._do_toggle_prev_cue)
     self.cue_next_button.add_value_listener(self._do_toggle_next_cue)
Пример #31
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
Пример #32
0
class OhmModes(ControlSurface):
	__module__ = __name__
	__doc__ = " OhmModes 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)
		self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= OhmModes log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
		self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up
		self._version_check = 'b993'
		self._host_name = 'Ohm'
		self._hosts = []
		self.hosts = []
		self._client = [None for index in range(6)]
		self._active_client = None
		self._bright = True
		self.flash_status = 1
		self._touched = 0
		self._backlight = 127
		self._backlight_type = 'static'
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._rgb = 1
		self._keys_octave = 5
		self._keys_scale = 0
		self._tempo_buttons = None
		self._setup_monobridge()
		self._setup_controls()
		self._setup_transport_control() # Run the transport setup part of the script
		self._setup_mixer_control() # Setup the mixer object
		self._setup_session_control()  # Setup the session object 
		self._setup_device_control() # Setup the device object
		self._setup_crossfader()
		self._setup_ohmmod()
		self._setup_switchboard()
		self._setup_modes() 
		self._assign_page_constants()
		self._last_device = None
		self._timer = 0
		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('OhmModes Control Surface Loaded')
		self._send_midi(tuple(switchxfader))
		self.schedule_message(10, self.query_ohm, None)
	

	def query_ohm(self):
		#self.log_message('querying Ohm')
		self._send_midi(tuple(check_model))

	

	def update_display(self):
		""" Live -> Script
		Aka on_timer. Called every 100 ms and should be used to update display relevant
		parts of the controller
		"""
		for message in self._scheduled_messages:
			message['Delay'] -= 1
			if (message['Delay'] == 0):
				if (message['Parameter'] != None):
					message['Message'](message['Parameter'])
				else:
					message['Message']()
					del self._scheduled_messages[self._scheduled_messages.index(message)]

		for callback in self._timer_callbacks:
			callback()

		self._timer = (self._timer + 1) % 256
		self.flash()
		self.strobe()
	

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

	def get_device_bank(self):
		return self._device._bank_index
	

	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(16)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(8):
			self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
			#self._fader[index].name = 'Fader_' + str(index), self
		for index in range(8):
			self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(16):
			self._dial[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index, self)
			#self._dial[index].name = 'Dial_' + str(index)
		self._knobs = []
		for index in range(12):
			self._knobs.append(self._dial[index])
		for index in range(6):
			self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)	
		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = "Crossfader"
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [None for index in range(8)]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))
	

	def _setup_ohmmod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self.hosts = [self._host]
		self._hosts = [self._host]
		for index in range(6):
			self._client[index] = MonoClient(self, index)
			self._client[index].name = 'Client_' + str(index)
			#self._client[index]._mod_dial = self._encoder[index]
		self._host._active_client = self._client[0]
		self._host._active_client._is_active = True
		self._host.connect_to_clients(self)
	

	def _setup_switchboard(self):
		self._switchboard = SwitchboardElement(self, self._client)
		self._switchboard.name = 'Switchboard'
	

	def _setup_modes(self):
		self._shift_mode = ShiftModeComponent(self) 
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid)
		self._scale_mode = ScaleModeComponent(self)
		self._scale_mode.name = "Scale_Mode"
		self._octave_mode = OctaveModeComponent(self)
		self._octave_mode.name = "Octave_Mode"
		self._modNum = ModNumModeComponent(self, self.modNum_update) 
		self._modNum.name = 'Mod_Number'
		self._modNum.set_mode = self._modNum_set_mode(self._modNum)
		self._modNum.set_mode_buttons([self._menu[index] for index in range(6)])
	

	def _modNum_set_mode(self, modNum):
		def set_mode(mode):
			if modNum._is_enabled == True:
				assert isinstance(mode, int)
				assert (mode in range(modNum.number_of_modes()))
				if (modNum._mode_index != mode):
					modNum._mode_index = mode
					modNum.update()
		return set_mode
	
	

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

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (7) #A mixer is one-dimensional; 
		global mixer
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])
		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True
		self.song().view.selected_track = mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
	

	def _setup_session_control(self):
		is_momentary = True
		num_tracks = 7
		num_scenes = 5 
		global session
		session = SessionComponent(num_tracks, num_scenes)
		session.name = "Session"
		self._session = session	
		session.set_offsets(0, 0)	 
		self._scene = [None for index in range(6)]
		for row in range(num_scenes):
			self._scene[row] = 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)		
		session.set_mixer(self._mixer)
		self._session_zoom = SessionZoomingComponent(session)	 
		self._session_zoom.name = 'Session_Overview'
	

	def _assign_session_colors(self):
		num_tracks = 7
		num_scenes = 5 
		self._session.set_stop_track_clip_value(STOP_CLIP_COLOR[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_TRIGD_TO_PLAY_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb])		
		self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb])
		self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb])
		self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb])
	

	def _setup_device_control(self):
		self._device = DeviceComponent()
		self._device.name = 'Device_Component'
		self.set_device_component(self._device)
		self._device_navigator = DetailViewControllerComponent()
		self._device_navigator.name = 'Device_Navigator'
		self._device_selection_follows_track_selection = FOLLOW
	

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

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

	def disconnect(self):
		"""clean things up on disconnect"""
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= OhmModes log closed =--------------") #Create entry in log file
		ControlSurface.disconnect(self)
		return None
	

	def _get_num_tracks(self):
		return self.num_tracks
	

	def flash(self):
		#if(self.flash_status > 0):
		for row in range(8):
			if(self._button[row]._flash_state > 0):
				self._button[row].flash(self._timer)
			for column in range(8):
				button = self._grid[column][row]
				if(button._flash_state > 0):
					button.flash(self._timer)
	

	def strobe(self):
		if(self._backlight_type != 'static'):
			if(self._backlight_type is 'pulse'):
				self._backlight = int(math.fabs(((self._timer * 16) % 64) -32) +32)
			if(self._backlight_type is 'up'):
				self._backlight = int(((self._timer * 8) % 64) + 16)
			if(self._backlight_type is 'down'):
				self._backlight = int(math.fabs(int(((self._timer * 8) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 27, int(self._backlight)]))
		if(self._ohm_type != 'static'):
			if(self._ohm_type is 'pulse'):
				self._ohm = int(math.fabs(((self._timer * 16) % 64) -32) +32)
			if(self._ohm_type is 'up'):
				self._ohm = int(((self._timer * 8) % 64) + 16)
			if(self._ohm_type is 'down'):
				self._ohm = int(math.fabs(int(((self._timer * 8) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))	
	

	def deassign_matrix(self):
		self._host._set_knobs(None)
		self._host._set_button_matrix(None)
		self._modNum.set_enabled(False)
		self.assign_alternate_mappings(0)
		self._scale_mode.set_mode_buttons(None)
		self._scale_mode.set_enabled(False)
		self._octave_mode.set_mode_buttons(None)
		self._octave_mode.set_enabled(False)
		#self._session_zoom.set_button_matrix(None)
		self._session_zoom.set_enabled(False)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		for column in range(4):
			#self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
			self._mixer.track_eq(column)._gain_controls = None
			self._mixer.track_eq(column).set_enabled(False)	
		for column in range(7):
			self._mixer.channel_strip(column).set_crossfade_toggle(None)
			self._mixer.channel_strip(column).set_mute_button(None)
			self._mixer.channel_strip(column).set_solo_button(None)
			self._mixer.channel_strip(column).set_arm_button(None)
			self._mixer.channel_strip(column).set_send_controls(None)
			self._mixer.channel_strip(column).set_pan_control(None)
			self._mixer.track_eq(column).set_enabled(False)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(None)
		for column in range(8):
			self._button[column]._on_value = SELECT_COLOR[self._rgb]
			for row in range(8):
				self._grid[column][row].set_channel(0)
				self._grid[column][row].release_parameter()
				self._grid[column][row].use_default_message()
				self._grid[column][row].set_enabled(True)
				self._grid[column][row].send_value(0, True)
				self._grid[column][row]._on_value = 127
				self._grid[column][row]._off_value = 0
		for index in range(6):
			self._menu[index]._on_value = 127
			self._menu[index]._off_value = 0
		for index in range(16):
			self._dial[index].use_default_message()
			self._dial[index].release_parameter()
			#self._dial[index].set_enabled(True)
		if(self._device._parameter_controls != None):
			for control in self._device._parameter_controls:
				control.release_parameter()
			self._device._parameter_controls = None
		self._device.set_enabled(False)
		self._device_navigator.set_enabled(False)
		self._mixer.update()
		self._matrix.reset()
		self._transport.set_play_button(None)
		self._transport.set_stop_button(None)	
		self.request_rebuild_midi_map()
	

	def _assign_page_constants(self):
		#self._session_zoom.set_zoom_button(self._button[7]) #commented out pn 070111
		self._session_zoom.set_zoom_button(self._grid[7][7]) #added pn 070111
		self._session_zoom.set_button_matrix(self._matrix)
		#self._session_zoom.set_enabled(True)
		for column in range(7):
			self._mixer.channel_strip(column).set_select_button(self._button[column])
			self._mixer.channel_strip(column).set_volume_control(self._fader[column])
		self._mixer.master_strip().set_volume_control(self._fader[7])
		self._mixer.master_strip().set_select_button(self._button[7]) #added pn 070111
		self._mixer.set_prehear_volume_control(self._dial[15])
		self._transport.set_play_button(self._menu[0])
		self._menu[0].send_value(PLAY_COLOR[self._rgb], True)	
		self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		self._transport.set_stop_button(self._menu[1])
		self._menu[1]._off_value = STOP_COLOR[self._rgb]
		self._menu[1]._on_value = STOP_COLOR[self._rgb]
		self._menu[1].send_value(STOP_COLOR[self._rgb], True)	
		#self._livid._on_value = TAP_COLOR[self._rgb]
		#self._transport.set_tap_tempo_button(self._livid)
		#self._livid.send_value(TAP_COLOR, True)
		self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])
	

	def assign_page_0(self):
		self._backlight_type = 'static'
		#self._session_zoom.set_button_matrix(self._matrix)
		self._transport.set_play_button(self._menu[0])
		self._transport.set_stop_button(self._menu[1])
		self._session_zoom.set_enabled(True)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = SOLO_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_solo_button(self._grid[column][6])
			self._grid[column][7]._on_value = ARM_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][7])
			self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for column in range(4):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]]))
		for index in range(5):
			self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[index].set_launch_button(self._grid[7][index])
		for index in range(4):
			self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
	

	def assign_page_1(self):
		self._backlight_type = 'pulse'
		self._transport.set_play_button(self._menu[0])
		self._transport.set_stop_button(self._menu[1])
		self._session_zoom.set_enabled(False)
		for column in range(4):
			for row in range(4):
				self._grid[column][row].set_channel(PAGE1_DRUM_CHANNEL)
				self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row])
				self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True)
				self._grid[column][row].set_enabled(False)
				self._grid[column + 4][row].set_channel(PAGE1_BASS_CHANNEL)
				self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row])
				self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True)
				self._grid[column + 4][row].set_enabled(False)
		scale_mode_buttons = []
		for column in range(8):
			for row in range(3):
				self._grid[column][row + 4].set_enabled(False)
				self._grid[column][row + 4].set_channel(PAGE1_KEYS_CHANNEL)
				self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12))
				self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True)
			for row in range(1):
				scale_mode_buttons.append(self._grid[column][7])
		self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons))
		self._scale_mode.set_enabled(True)
		self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]]))
		self._octave_mode.set_enabled(True)
		for column in range(7):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]]))
			self._mixer.channel_strip(column).set_arm_button(self._button[column])
		self._device.set_enabled(True)
		device_param_controls = []
		for index in range(8):
			device_param_controls.append(self._dial[index])
		self._device.set_parameter_controls(tuple(device_param_controls))
		for index in range(4):
			self._menu[2 + index]._on_value = (DEVICE_NAV_COLOR[self._rgb])
		self._device_navigator.set_enabled(True)
	

	def assign_page_2(self):
		self._backlight_type = 'up'
		self._transport.set_play_button(self._menu[0])
		self._transport.set_stop_button(self._menu[1])
		#self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_enabled(True)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6])
			self._grid[column][7].set_channel(2)
			self._grid[column][7].set_identifier(column)
			self._grid[column][7].reset()
			self._grid[column][7].set_enabled(False)
			self._grid[column][7].send_value(4, True)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for row in range(5):
			self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[row].set_launch_button(self._grid[7][row])
		for column in range(4):
			self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
			self._mixer.track_eq(column).set_enabled(True)	
		for column in range(3):
			self._mixer.channel_strip(column+4).set_pan_control(self._dial[column + 12])
		for index in range(4):
			self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
		self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]])
	

	def assign_mod(self):
		#for index in range(6):
			#self._modNum._modes_buttons[index].send_value(self._client[index]._mod_color)
		#if self._shift_mode._mode_index is 0:
		#	self._host._set_dial_matrix(None, None)
			#self._host._set_knobs(None)
			#self._host._set_button_matrix(None)
			#self._host._set_key_buttons(None)
			#self._host.set_enabled(False)
			#self.set_local_ring_control(1)
			#self.assign_live_controls()
			#for index in range(4):
			#	self._shift_mode._modes_buttons[index].turn_off()
		#else:
		#if self._shift_mode._mode_index is 3:
		self.deassign_matrix()
		#self.set_local_ring_control(self._host._active_client._local_ring_control)
		self._host.set_enabled(True)
		self._modNum.set_enabled(True)
		#self._host._set_dial_matrix(self._dial_matrix, self._dial_button_matrix)
		self._host._set_knobs(tuple(self._knobs))
		self._host._set_button_matrix(self._monomod)
		#self._host._set_key_buttons(tuple(self._button))
		#self._host._select_client(self._shift_mode._mode_index-1)
		#self._host._select_client(0)
		#for index in range(4):
		#	if self._shift_mode._mode_index == (index + 1):
		#		self._shift_mode._modes_buttons[index].send_value(1)
		if not self._host._active_client.is_connected():
			#self.assign_alternate_mappings(self._shift_mode._mode_index)
			self.assign_alternate_mappings(self._modNum._mode_index + 1)
			#else:
			#	self._shift_mode._modes_buttons[index].send_value(self._client[index]._mod_color)
			#self._shift_mode._modes_buttons[index].send_value(((index+1)==self._shift_mode._mode_index)*127)
	

	def modNum_update(self):
		if self._modNum._is_enabled == True:
			self.assign_alternate_mappings(0)
			self._host._select_client(int(self._modNum._mode_index))
			if not self._host._active_client.is_connected():
				self.assign_alternate_mappings(self._modNum._mode_index + 1)
			for button in self._modNum._modes_buttons:
				button.send_value(int(self._modNum._mode_index == self._modNum._modes_buttons.index(button))*self._host._active_client._mod_color)
	

	def assign_alternate_mappings(self, chan):
		for column in range(8):
			for row in range(8):
				#self._grid[column][row].set_identifier(OHM_MAP_ID[column][row])
				self._grid[column][row].set_channel(chan)
				#self._grid[column][row].send_value(OHM_MAP_VALUE[column][row])
				self._grid[column][row].set_enabled(chan is 0)
		#for index in range(8):
		#	self._encoder_button[index + 4].set_channel(chan)
		#	self._encoder_button[index + 4].set_enabled(chan is 0)
		for knob in self._knobs:
			knob.set_channel(chan)
			knob.set_enabled(chan is 0)
		#for button in self._button:
		#	button.set_channel(chan)
		#	button.set_enabled(chan is 0)
		self.request_rebuild_midi_map()
	

	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			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.set_device(device_to_select)
			self.set_appointed_device(device_to_select)
			#self._device_selector.set_enabled(True)
			self.request_rebuild_midi_map()
		return None
	

	def handle_sysex(self, midi_bytes):
		#self.log_message(str('>>sysexIN') + str(midi_bytes))
		if len(midi_bytes) > 10:
			#self.log_message(str('>>sysex>10') + str(midi_bytes[:11]))
			if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]):
				self.log_message(str('>>>color detected'))
				self._rgb = 1
			elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]):
				self.log_message(str('>>>mono detected'))
				self._rgb = 0
		self._assign_session_colors()
	

	def receive_midi(self, midi_bytes):
		""" Live -> Script
		MIDI messages are only received through this function, when explicitly 
		forwarded in 'build_midi_map'.
		"""
		assert (midi_bytes != None)
		assert isinstance(midi_bytes, tuple)
		##self.log_message('got message' + str(midi_bytes))
		self.set_suppress_rebuild_requests(True)
		if (len(midi_bytes) is 3):
			msg_type = (midi_bytes[0] & 240)
			forwarding_key = [midi_bytes[0]]
			if (msg_type is not MIDI_PB_TYPE):
				forwarding_key.append(midi_bytes[1])
			if (tuple(forwarding_key) in self._forwarding_registry.keys()):
				recipient = self._forwarding_registry[tuple(forwarding_key)]
				if (recipient != None):
					recipient.receive_value(midi_bytes[2])
			else:
				self.log_message(('Got unknown message: ' + str(midi_bytes)))
		else:
			self.handle_sysex(midi_bytes)
		self.set_suppress_rebuild_requests(False)		 
	

	def _set_tempo_buttons(self, buttons):
		if self._tempo_buttons != None:
			self._tempo_buttons[0].remove_value_listener(self._tempo_value)
			self._tempo_buttons[1].remove_value_listener(self._tempo_value)
		self._tempo_buttons = buttons
		if buttons != None:
			for button in buttons:
				assert isinstance(button, FlashingButtonElement)
			self._tempo_buttons[0].set_on_off_values(4, 0)
			self._tempo_buttons[0].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[1].set_on_off_values(4, 0)
			self._tempo_buttons[1].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[0].turn_on()
			self._tempo_buttons[1].turn_on()
	

	def _tempo_value(self, value, sender):
		if (value > 0) and (self._tempo_buttons.index(sender) == 0):
			self.song().tempo = round(min((self.song().tempo + 1), 999))
		elif (value > 0) and (self._tempo_buttons.index(sender) == 1):
			self.song().tempo = round(max((self.song().tempo - 1), 20))
	

	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		#self.log_message(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, 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._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
Пример #33
0
class OhmModes(ControlSurface):
	__module__ = __name__
	__doc__ = ' OhmModes controller script '

	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		with self.component_guard():
			self._version_check = 'b994'
			self._host_name = 'Ohm'
			self._color_type = 'OhmRGB'
			self._hosts = []
			self.hosts = []
			self._client = [ None for index in range(6) ]
			self._active_client = None
			self.log_message('<<<<<<<<<<<<<<<<<<<<<<<<< OhmModes ' + str(self._version_check) + ' log opened >>>>>>>>>>>>>>>>>>>>>>>>>')
			self._rgb = 0
			self._timer = 0
			self._touched = 0
			self.flash_status = 1
			self._backlight = 127
			self._backlight_type = 'static'
			self._ohm = 127
			self._ohm_type = 'static'
			self._pad_translations = PAD_TRANSLATION
			self._device_selection_follows_track_selection = FOLLOW
			self._keys_octave = 5
			self._keys_scale = 0
			self._tempo_buttons = None
			self._setup_monobridge()
			self._setup_controls()
			self._setup_transport_control()
			self._setup_mixer_control()
			self._setup_session_control()
			self._setup_device_control()
			self._setup_crossfader()
			self._setup_ohmmod()
			self._setup_switchboard()
			self._setup_modes()
			self._assign_page_constants()
			self._last_device = None
			self.song().view.add_selected_track_listener(self._update_selected_device)
			self.show_message('OhmModes Control Surface Loaded')
			self._send_midi(tuple(switchxfader))
			if FORCE_TYPE is True:
				self._rgb = FORCE_COLOR_TYPE
			else:
				self.schedule_message(10, self.query_ohm, None)
			self.log_message(str(self._highlighting_session_component))

	def query_ohm(self):
		self._send_midi(tuple(check_model))

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

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

	def get_device_bank(self):
		return self._device._bank_index

	def _setup_controls(self):
		is_momentary = True
		self._fader = [ None for index in range(8) ]
		self._dial = [ None for index in range(16) ]
		self._button = [ None for index in range(8) ]
		self._menu = [ None for index in range(6) ]
		for index in range(8):
			self._fader[index] = MonoEncoderElement2(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)

		for index in range(8):
			self._button[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)

		for index in range(16):
			self._dial[index] = CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), index, self)

		self._knobs = []
		for index in range(12):
			self._knobs.append(self._dial[index])

		for index in range(6):
			self._menu[index] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)

		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = 'Crossfader'
		self._livid = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [ None for index in range(8) ]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for column in range(8):
			self._grid[column] = [ None for index in range(8) ]
			for row in range(8):
				self._grid[column][row] = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, column * 8 + row, 'Grid_' + str(column) + '_' + str(row), self)

		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])

			self._matrix.add_row(tuple(button_row))

		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])

			self._monomod.add_row(tuple(button_row))

		self._mod_matrix = ButtonMatrixElement()
		self._mod_matrix.name = 'Matrix'
		self._dial_matrix = EncoderMatrixElement(self)
		self._dial_matrix.name = 'Dial_Matrix'
		self._dial_button_matrix = ButtonMatrixElement()
		self._dial_button_matrix.name = 'Dial_Button_Matrix'
		for row in range(4):
			button_row = []
			for column in range(4):
				button_row.append(self._grid[column + 4][row])

			self._mod_matrix.add_row(tuple(button_row))

		for row in range(3):
			dial_row = []
			for column in range(4):
				dial_row.append(self._dial[row * 4 + column])

			self._dial_matrix.add_row(tuple(dial_row))

		for row in range(3):
			dial_button_row = []
			for column in range(4):
				dial_button_row.append(self._grid[column][row])

			self._dial_button_matrix.add_row(tuple(dial_button_row))

		self._key = [ self._grid[KEYS[index][1]][KEYS[index][0]] for index in range(32) ]
		self._encoder = [ self._dial[index] for index in range(12) ]
		self._key_matrix = ButtonMatrixElement()
		button_row = []
		for column in range(16):
			button_row.append(self._key[16 + column])

		self._key_matrix.add_row(tuple(button_row))

	def _setup_ohmmod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self.hosts = [self._host]
		self._hosts = [self._host]
		for index in range(6):
			self._client[index] = MonoClient(self, index)
			self._client[index].name = 'Client_' + str(index)
			self._client[index]._device_component.set_parameter_controls(tuple([ self._dial[num] for num in range(12) ]))
			self._client[index]._control_defs = {'dials': self._dial_matrix,
			 'buttons': self._dial_button_matrix,
			 'grid': self._mod_matrix,
			 'keys': self._key,
			 'knobs': [ self._dial[num + 12] for num in range(4) ]}

		self._host._active_client = self._client[0]
		self._host._active_client._is_active = True
		self._host.connect_to_clients(self)

	def _setup_switchboard(self):
		self._switchboard = SwitchboardElement(self, self._client)
		self._switchboard.name = 'Switchboard'

	def _setup_modes(self):
		self._shift_mode = ShiftModeComponent(self)
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r, self._livid)
		self._scale_mode = ScaleModeComponent(self)
		self._scale_mode.name = 'Scale_Mode'
		self._octave_mode = OctaveModeComponent(self)
		self._octave_mode.name = 'Octave_Mode'
		self._modNum = ModNumModeComponent(self, self.modNum_update)
		self._modNum.name = 'Mod_Number'
		self._modNum.set_mode = self._modNum_set_mode(self._modNum)
		self._modNum.set_mode_buttons([ self._menu[index] for index in range(6) ])

	def _modNum_set_mode(self, modNum):
		def set_mode(mode):
			if modNum._is_enabled == True:
				assert isinstance(mode, int)
				assert (mode in range(modNum.number_of_modes()))
				if (modNum._mode_index != mode):
					modNum._mode_index = mode
					modNum.update()
		return set_mode
	

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

	def _setup_mixer_control(self):
		global mixer
		is_momentary = True
		self._num_tracks = 7
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])

		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True

		self.song().view.selected_track = mixer.channel_strip(0)._track

	def _setup_session_control(self):
		global session
		is_momentary = True
		num_tracks = 7
		num_scenes = 5
		session = SessionComponent(num_tracks, num_scenes)
		session.name = 'Session'
		self._session = session
		session.set_offsets(0, 0)
		self._scene = [ None for index in range(6) ]
		for row in range(num_scenes):
			self._scene[row] = 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)

		session.set_mixer(self._mixer)
		session.set_show_highlight(True)
		self._session_zoom = SessionZoomingComponent(session)
		self._session_zoom.name = 'Session_Overview'
		self.set_highlighting_session_component(self._session)

	def _assign_session_colors(self):
		self.log_message('assign session colors')
		num_tracks = 7
		num_scenes = 5
		self._session.set_stop_track_clip_value(STOP_CLIP_COLOR[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_TRIGD_TO_PLAY_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb])

		self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb])
		self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb])
		self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb])
		for row in range(8):
			for column in range(8):
				self._grid[column][row].set_force_next_value()

		self._session.on_scene_list_changed()
		self._shift_mode.update()

	def _setup_device_control(self):
		self._device = DeviceComponent()
		self._device.name = 'Device_Component'
		self.set_device_component(self._device)
		self._device_navigator = DetailViewControllerComponent()
		self._device_navigator.name = 'Device_Navigator'
		self._device_selection_follows_track_selection = FOLLOW

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

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

	def disconnect(self):
		"""clean things up on disconnect"""
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		self.log_message(time.strftime('%d.%m.%Y %H:%M:%S', time.localtime()) + '--------------= OhmModes log closed =--------------')
		ControlSurface.disconnect(self)

	def _get_num_tracks(self):
		return self.num_tracks

	def flash(self):
		for row in range(8):
			if self._button[row]._flash_state > 0:
				self._button[row].flash(self._timer)
			for column in range(8):
				button = self._grid[column][row]
				if button._flash_state > 0:
					button.flash(self._timer)

	def strobe(self):
		if self._backlight_type != 'static':
			if self._backlight_type is 'pulse':
				self._backlight = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
			if self._backlight_type is 'up':
				self._backlight = int(self._timer * 8 % 64 + 16)
			if self._backlight_type is 'down':
				self._backlight = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
		self._send_midi(tuple([176, 27, int(self._backlight)]))
		if self._ohm_type != 'static':
			if self._ohm_type is 'pulse':
				self._ohm = int(math.fabs(self._timer * 16 % 64 - 32) + 32)
			if self._ohm_type is 'up':
				self._ohm = int(self._timer * 8 % 64 + 16)
			if self._ohm_type is 'down':
				self._ohm = int(math.fabs(int(self._timer * 8 % 64 - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))

	def deassign_matrix(self):
		with self.component_guard():
			self._host._set_knobs(None)
			self._host._set_button_matrix(None)
			self._host.set_enabled(False)
			self._modNum.set_enabled(False)
			self.assign_alternate_mappings(0)
			self._scale_mode.set_mode_buttons(None)
			self._scale_mode.set_enabled(False)
			self._octave_mode.set_mode_buttons(None)
			self._octave_mode.set_enabled(False)
			self._session_zoom.set_enabled(False)
			self._session_zoom.set_nav_buttons(None, None, None, None)
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			self._transport.set_enabled(False)
			for column in range(4):
				self._mixer.track_eq(column)._gain_controls = None
				self._mixer.track_eq(column).set_enabled(False)

			for column in range(7):
				self._mixer.channel_strip(column).set_crossfade_toggle(None)
				self._mixer.channel_strip(column).set_mute_button(None)
				self._mixer.channel_strip(column).set_solo_button(None)
				self._mixer.channel_strip(column).set_arm_button(None)
				self._mixer.channel_strip(column).set_send_controls(None)
				self._mixer.channel_strip(column).set_pan_control(None)
				self._mixer.track_eq(column).set_enabled(False)
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(None)

			"""for column in range(8):
				self._button[column]._on_value = SELECT_COLOR[self._rgb]
				for row in range(8):
					self._grid[column][row].set_enabled(True)
					self._grid[column][row].release_parameter()
					self._grid[column][row].use_default_message()
					self._grid[column][row].set_on_off_values(127, 0)
					self._grid[column][row].send_value(0, True)"""
			for column in range(8):
				self._button[column]._on_value = SELECT_COLOR[self._rgb]
				for row in range(8):
					#self._grid[column][row].set_channel(0)
					self._grid[column][row].release_parameter()
					self._grid[column][row].use_default_message()
					self._grid[column][row].set_enabled(True)
					self._grid[column][row].send_value(0, True)
					self._grid[column][row]._on_value = 127
					self._grid[column][row]._off_value = 0
					self._grid[column][row].force_next_send()


			for index in range(6):
				self._menu[index]._on_value = 127
				self._menu[index]._off_value = 0

			for index in range(16):
				self._dial[index].use_default_message()
				self._dial[index].release_parameter()

			self._device.set_parameter_controls(None)
			self._device.set_enabled(False)
			self._device_navigator.set_enabled(False)
			self._mixer.update()
			self._matrix.reset()
		self.request_rebuild_midi_map()

	def _assign_page_constants(self):
		with self.component_guard():
			self._session_zoom.set_zoom_button(self._grid[7][7])
			self._session_zoom.set_button_matrix(self._matrix)
			for column in range(7):
				self._mixer.channel_strip(column).set_select_button(self._button[column])
				self._mixer.channel_strip(column).set_volume_control(self._fader[column])

			self._mixer.master_strip().set_volume_control(self._fader[7])
			self._mixer.master_strip().set_select_button(self._button[7])
			self._mixer.set_prehear_volume_control(self._dial[15])
			self._transport.set_play_button(self._menu[0])
			self._menu[0].send_value(PLAY_COLOR[self._rgb], True)
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._transport.set_stop_button(self._menu[1])
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._menu[1].send_value(STOP_COLOR[self._rgb], True)
			self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])

	def assign_page_0(self):
		with self.component_guard():
			self._backlight_type = 'static'
			self._session_zoom.set_enabled(True)
			for column in range(7):	
				self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
				self._grid[column][6]._on_value = SOLO_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_solo_button(self._grid[column][6])
				self._grid[column][7]._on_value = ARM_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_arm_button(self._grid[column][7])
				self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8])
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])

			for column in range(4):
				self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]]))

			for index in range(5):
				self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
				self._scene[index].set_launch_button(self._grid[7][index])
				self._grid[7][index].set_force_next_value()
				self._grid[7][index].turn_off()

			for index in range(4):
				self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]

			self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
			self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._transport.set_enabled(True)
			#self._mixer.update_all()
		self.request_rebuild_midi_map()
		#self.log_message('assign_page_0')

	def assign_page_1(self):
		with self.component_guard():
			self._backlight_type = 'pulse'
			self._session_zoom.set_enabled(False)
			for column in range(4):
				for row in range(4):
					self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True)
					self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True)
					self._grid[column][row].set_enabled(False)
					self._grid[column][row]._msg_channel = PAGE1_DRUM_CHANNEL
					self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row])
					self._grid[column + 4][row].set_enabled(False)
					self._grid[column + 4][row]._msg_channel = PAGE1_BASS_CHANNEL
					self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row])

			scale_mode_buttons = []
			for column in range(8):
				for row in range(3):
					self._grid[column][row + 4].set_enabled(False)
					self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True)
					self._grid[column][row + 4]._msg_channel = PAGE1_KEYS_CHANNEL
					self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12))

				for row in range(1):
					scale_mode_buttons.append(self._grid[column][7])

			self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons))
			self._scale_mode.set_enabled(True)
			self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]]))
			self._octave_mode.set_enabled(True)
			for column in range(7):
				self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]]))
				self._mixer.channel_strip(column).set_arm_button(self._button[column])

			self._device.set_enabled(True)
			device_param_controls = []
			for index in range(8):
				device_param_controls.append(self._dial[index])

			self._device.set_parameter_controls(tuple(device_param_controls))
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			for index in range(4):
				self._menu[2 + index]._on_value = DEVICE_NAV_COLOR[self._rgb]

			self._device_navigator.set_enabled(True)
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._transport.set_enabled(True)
		self.request_rebuild_midi_map()

	def assign_page_2(self):
		with self.component_guard():
			self._backlight_type = 'up'
			self._session_zoom.set_enabled(True)
			for column in range(7):
				self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
				self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb]
				self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6])
				self._grid[column][7]._msg_channel = 2
				self._grid[column][7].set_identifier(column)
				self._grid[column][7].reset()
				self._grid[column][7].set_enabled(False)
				self._grid[column][7].send_value(4, True)
				for row in range(5):
					self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])

			for row in range(5):
				self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
				self._scene[row].set_launch_button(self._grid[7][row])
				self._grid[7][row].set_force_next_value()
				self._grid[7][row].turn_off()

			for column in range(4):
				self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
				self._mixer.track_eq(column).set_enabled(True)

			for column in range(3):
				self._mixer.channel_strip(column + 4).set_pan_control(self._dial[column + 12])

			for index in range(4):
				self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]

			self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
			self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
			self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]])
			self._menu[0]._on_value = PLAY_COLOR[self._rgb]
			self._menu[1]._off_value = STOP_COLOR[self._rgb]
			self._menu[1]._on_value = STOP_COLOR[self._rgb]
			self._transport.set_enabled(True)
			#self._mixer.update()
		self.request_rebuild_midi_map()

	def assign_mod(self):
		with self.component_guard():
			self.deassign_matrix()
			self._host.set_enabled(True)
			self._modNum.set_enabled(True)
			self._host._set_dial_matrix(self._dial_matrix, self._dial_button_matrix)
			self._host._set_button_matrix(self._mod_matrix)
			self._host._set_key_buttons(tuple(self._key))
			if not self._host._active_client.is_connected():
				self.assign_alternate_mappings(self._modNum._mode_index + 1)

	def modNum_update(self):
		if self._modNum._is_enabled == True:
			self.assign_alternate_mappings(0)
			self._host._select_client(int(self._modNum._mode_index))
			self._host.display_active_client()
			if not self._host._active_client.is_connected():
				self.assign_alternate_mappings(self._modNum._mode_index + 1)
			for button in self._modNum._modes_buttons:
				if self._modNum._mode_index == self._modNum._modes_buttons.index(button):
					button.send_value(1)
				else:
					button.send_value(self._client[self._modNum._modes_buttons.index(button)]._mod_color)

	def assign_alternate_mappings(self, chan):
		for column in range(8):
			for row in range(8):
				self._grid[column][row].set_channel(chan)
		for knob in self._encoder:
			knob.set_channel(chan)
			knob.set_enabled(chan is 0)

		self.request_rebuild_midi_map()

	def display_mod_colors(self):
		pass

	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			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.set_appointed_device(device_to_select)
			self.request_rebuild_midi_map()

	def handle_sysex(self, midi_bytes):
		if len(midi_bytes) > 10:
			if midi_bytes[:11] == tuple([240,
			 126,
			 0,
			 6,
			 2,
			 0,
			 1,
			 97,
			 1,
			 0,
			 7]):
				self.log_message(str('>>>color detected'))
				self._rgb = 0
			elif midi_bytes[:11] == tuple([240,
			 126,
			 0,
			 6,
			 2,
			 0,
			 1,
			 97,
			 1,
			 0,
			 2]):
				self.log_message(str('>>>mono detected'))
				self._rgb = 1
		self._assign_session_colors()

	def to_encoder(self, num, val):
		rv = int(val * 127)
		self._device._parameter_controls[num].receive_value(rv)
		p = self._device._parameter_controls[num]._parameter_to_map_to
		newval = val * (p.max - p.min) + p.min
		p.value = newval

	def set_local_ring_control(self, val = 1):
		self._local_ring_control = val != 0

	def set_absolute_mode(self, val = 1):
		self._absolute_mode = val != 0

	def send_ring_leds(self):
		"""if self._host._is_enabled == True:
		leds = [240, 0, 1, 97, 8, 31]
		for index in range(12):
				wheel = self._encoder[index]
				bytes = wheel._get_ring()
				leds.append(bytes[0])
				leds.append(int(bytes[1]) + int(bytes[2]))
		leds.append(247)
		self._send_midi(tuple(leds))"""
		pass


	def _set_tempo_buttons(self, buttons):
		if self._tempo_buttons != None:
			self._tempo_buttons[0].remove_value_listener(self._tempo_value)
			self._tempo_buttons[1].remove_value_listener(self._tempo_value)
		self._tempo_buttons = buttons
		if buttons != None:
			for button in buttons:
				 assert isinstance(button, FlashingButtonElement)
			self._tempo_buttons[0].set_on_off_values(4, 0)
			self._tempo_buttons[0].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[1].set_on_off_values(4, 0)
			self._tempo_buttons[1].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[0].turn_on()
			self._tempo_buttons[1].turn_on()

	def _tempo_value(self, value, sender):
		if value > 0 and self._tempo_buttons.index(sender) == 0:
			self.song().tempo = round(min(self.song().tempo + 1, 999))
		elif value > 0 and self._tempo_buttons.index(sender) == 1:
			self.song().tempo = round(max(self.song().tempo - 1, 20))

	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, tuple([MonoEncoderElement2, 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 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)
					return clip_slot._clip_slot

		return clip_names

	def shift_update(self):
		pass
class Axiom_AIR_25_49_61(ControlSurface):
    """ Script for the M-Audio Axiom A.I.R. 25, 49 and 61 """

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._alt_device_component = None
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = "HyperControl"
            self._suggested_output_port = "HyperControl"
            self._single_fader_button_modes = None
            self._has_faders = True
            self._display_reset_delay = -1
            self._hc_byte = HC_BYTE
            self._waiting_for_first_response = True
            self._setup_controls()
            self._setup_displays()
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_modes()
            self._drum_group_midi_button = None
            self._drum_group_hyper_button = None
            for component in self.components:
                component.set_enabled(False)

    def disconnect(self):
        self._scheduled_messages = []
        for encoder in self._encoders:
            encoder.remove_value_listener(self._encoder_value)

        for fader in self._faders:
            fader.remove_value_listener(self._fader_value)

        for fader_button in self._fader_buttons:
            fader_button.remove_value_listener(self._fader_button_value)

        self._master_fader.remove_value_listener(self._fader_value)
        self._master_fader_button.remove_value_listener(self._fader_button_value)
        self._select_button.remove_value_listener(self._select_button_value)
        self._identify_button.remove_value_listener(self._identify_value)
        self._fader_group_midi_button.remove_value_listener(self._midi_button_value)
        self._fader_group_mix_button.remove_value_listener(self._hyper_button_value)
        self._fader_group_fx_button.remove_value_listener(self._hyper_button_value)
        self._encoder_group_midi_button.remove_value_listener(self._midi_button_value)
        self._encoder_group_mix_button.remove_value_listener(self._hyper_button_value)
        self._encoder_group_fx_button.remove_value_listener(self._hyper_button_value)
        if self._drum_group_midi_button != None:
            self._drum_group_midi_button.remove_value_listener(self._midi_button_value)
        if self._drum_group_hyper_button != None:
            self._drum_group_hyper_button.remove_value_listener(self._hyper_button_value)
        self._alt_device_component = None
        self._name_display = None
        self._value_display = None
        self._bank_display = None
        self._pad_display = None
        self._name_display_data_source = None
        self._value_display_data_source = None
        self._bank_display_data_source = None
        self._pad_display_data_source = None
        self._select_button = None
        self._left_button = None
        self._right_button = None
        self._up_button = None
        self._down_button = None
        self._loop_button = None
        self._ffwd_button = None
        self._rwd_button = None
        self._play_button = None
        self._stop_button = None
        self._rec_button = None
        self._master_fader_button = None
        self._fader_buttons = None
        self._faders = None
        self._encoders = None
        self._drum_pads = None
        self._identify_button = None
        self._main_group_hyper_button = None
        self._main_group_track_button = None
        self._main_group_fx_button = None
        self._encoder_group_midi_button = None
        self._encoder_group_mix_button = None
        self._encoder_group_fx_button = None
        self._fader_group_mode_button = None
        self._fader_group_midi_button = None
        self._fader_group_mix_button = None
        self._fader_group_fx_button = None
        self._drum_group_midi_button = None
        self._drum_group_roll_button = None
        self._drum_group_hyper_button = None
        self._mixer_for_encoders = None
        self._mixer_for_faders = None
        self._device_for_encoders = None
        self._device_for_faders = None
        self._transport = None
        self._session = None
        ControlSurface.disconnect(self)
        self._send_midi(SYSEX_START + DISABLE_HYPERCONTROL)

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(5, self._send_midi, IDENTITY_REQUEST)

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:10] == AXIOM_AIR_RESPONSE:
            if midi_bytes[12:15] < AXIOM_REV4_RESPONSE:
                self.schedule_message(1, self._send_midi, SYSEX_START + ENGAGE_HYPERCONTROL)
                self.schedule_message(2, self._send_midi, SYSEX_START + CLEAR_ALL)
                self.schedule_message(3, self._name_display.display_message, "Firmware")
                self.schedule_message(13, self._name_display.display_message, "Update")
                self.schedule_message(23, self._name_display.display_message, "Required")
                self.schedule_message(33, self._send_midi, SYSEX_START + DISABLE_HYPERCONTROL)
            elif midi_bytes[12:15] >= AXIOM_REV4_RESPONSE:
                if self._waiting_for_first_response == True:
                    self._waiting_for_first_response = False
                    self._has_faders = midi_bytes[10] != 50
                    self.schedule_message(1, self._send_midi, SYSEX_START + ENGAGE_HYPERCONTROL)
                    self.schedule_message(2, self._send_midi, SYSEX_START + SPECIAL_HYPERCONTROL)
                    self.schedule_message(3, self._complete_setup)
                else:
                    self._display_reset_delay = 0
        elif midi_bytes[0:8] == REQUEST_HYPERCONTROL:
            self.schedule_message(5, self._send_midi, IDENTITY_REQUEST)

    def update_display(self):
        ControlSurface.update_display(self)
        if self._display_reset_delay >= 0:
            self._display_reset_delay -= 1
            if self._display_reset_delay == -1:
                self._set_displays_to_default()

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._display_reset_delay = 0

    def restore_bank(self, bank_index):
        ControlSurface.restore_bank(self, bank_index)
        if self._alt_device_component != None:
            self._alt_device_component.restore_bank(bank_index)

    def set_appointed_device(self, device):
        ControlSurface.set_appointed_device(self, device)
        with self.component_guard():
            if self._alt_device_component != None:
                self._alt_device_component.set_device(device)

    def set_alt_device_component(self, device_component):
        self._alt_device_component = device_component

    def _update_device_selection(self):
        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)
        if self._alt_device_component != None:
            self._alt_device_component.set_device(device_to_select)

    def _setup_controls(self):
        self._left_button = create_button(99, "Left_Button")
        self._right_button = create_button(100, "Right_Button")
        self._up_button = create_button(101, "Up_Button")
        self._down_button = create_button(102, "Down_Button")
        self._loop_button = create_button(113, "Loop_Button")
        self._rwd_button = create_button(114, "Rwd_Button")
        self._ffwd_button = create_button(115, "FFwd_Button")
        self._stop_button = create_button(116, "Stop_Button")
        self._play_button = create_button(117, "Play_Button")
        self._rec_button = create_button(118, "Record_Button")
        self._select_button = ConfigurableButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, GLOBAL_CHANNEL, 98)
        self._select_button.name = "Select_Button"
        self._select_button.add_value_listener(self._select_button_value)
        self._main_group_hyper_button = create_configurable_button(104, "Fader_Group_HyperControl_Button", 2, 14)
        self._main_group_track_button = create_configurable_button(105, "Main_Group_Track_Button", 2, 11)
        self._main_group_fx_button = create_configurable_button(106, "Main_Group_Inst_FX_Button", 2, 11)
        self._identify_button = create_configurable_button(97, "Identify_Button", 2, 16)
        self._identify_button.add_value_listener(self._identify_value)
        self._fader_buttons = []
        for index in range(8):
            self._fader_buttons.append(create_configurable_button(49 + index, "Fader_Button_%d" % index))
            self._fader_buttons[-1].add_value_listener(self._fader_button_value, identify_sender=True)

        self._faders = []
        for index in range(8):
            self._faders.append(create_slider(33 + index, "Fader_%d" % index))
            self._faders[-1].add_value_listener(self._fader_value, identify_sender=True)

        self._master_fader_button = create_configurable_button(57, "Master_Fader_Button")
        self._master_fader_button.add_value_listener(self._fader_button_value, identify_sender=True)
        self._master_fader = create_slider(41, "Master_Fader")
        self._master_fader.add_value_listener(self._fader_value, identify_sender=True)
        self._fader_group_mode_button = create_configurable_button(61, "Fader_Group_Mode_Button")
        self._fader_group_midi_button = create_configurable_button(60, "Fader_Group_MIDI_Button")
        self._fader_group_midi_button.add_value_listener(self._midi_button_value, identify_sender=True)
        self._fader_group_mix_button = create_configurable_button(58, "Fader_Group_Mix_Button", 0, 1)
        self._fader_group_mix_button.add_value_listener(self._hyper_button_value, identify_sender=True)
        self._fader_group_fx_button = create_configurable_button(59, "Fader_Group_Inst_FX_Button", 0, -1)
        self._fader_group_fx_button.add_value_listener(self._hyper_button_value, identify_sender=True)
        self._encoders = []
        for index in range(8):
            self._encoders.append(create_encoder(17 + index, "Encoder_%d" % index))
            self._encoders[-1].add_value_listener(self._encoder_value, identify_sender=True)

        self._encoder_group_midi_button = create_configurable_button(27, "Encoder_Group_MIDI_Button", 0, 72)
        self._encoder_group_midi_button.add_value_listener(self._midi_button_value, identify_sender=True)
        self._encoder_group_mix_button = create_configurable_button(25, "Encoder_Group_Mix_Button", 0, 72)
        self._encoder_group_mix_button.add_value_listener(self._hyper_button_value, identify_sender=True)
        self._encoder_group_fx_button = create_configurable_button(26, "Encoder_Group_Inst_FX_Button", 0, 72)
        self._encoder_group_fx_button.add_value_listener(self._hyper_button_value, identify_sender=True)

    def _setup_drum_pads(self):
        self._drum_pads = []
        num_pads = 12 if self._has_faders else 16
        for index in range(8):
            self._drum_pads.append(create_configurable_button(81 + index, "Pad_%d" % index, 0, 0, MIDI_CC_TYPE))

        for index in range(num_pads - 8):
            self._drum_pads.append(
                ConfigurableButtonElement(
                    IS_MOMENTARY, MIDI_NOTE_TYPE, GLOBAL_CHANNEL - 1, 81 + index, GLOBAL_SEND_CHANNEL, 8, MIDI_CC_TYPE
                )
            )
            self._drum_pads[-1].name = "Pad_" + str(index + 8)

        self._drum_group_midi_button = create_configurable_button(91, "Drum_Group_MIDI_Button", 2, -2)
        self._drum_group_midi_button.add_value_listener(self._midi_button_value, identify_sender=True)
        self._drum_group_roll_button = create_configurable_button(90, "Drum_Group_Roll_Button", -1)
        self._drum_group_hyper_button = create_configurable_button(89, "Drum_Group_HyperControl_Button", 2, 2)
        self._drum_group_hyper_button.add_value_listener(self._hyper_button_value, identify_sender=True)

    def _setup_displays(self):
        self._name_display = PhysicalDisplayElement(12, 1)
        self._name_display.name = "Name_Display"
        self._name_display.set_message_parts(SYSEX_START + (21,), (0, 247))
        self._name_display.set_clear_all_message(CLEAR_NAME)
        self._name_display_data_source = DisplayDataSource()
        self._name_display.segment(0).set_data_source(self._name_display_data_source)
        self._value_display = NumericalDisplayElement(3, 1)
        self._value_display.name = "Value_Display"
        self._value_display.set_message_parts(SYSEX_START + (20, 48), (0, 247))
        self._value_display.set_clear_all_message(CLEAR_VALUE)
        self._value_display_data_source = DisplayDataSource()
        self._value_display.segment(0).set_data_source(self._value_display_data_source)
        self._bank_display = NumericalDisplayElement(3, 1)
        self._bank_display.name = "Bank_Display"
        self._bank_display.set_message_parts(SYSEX_START + (19,), (0, 247))
        self._bank_display.set_clear_all_message(CLEAR_BANK)
        self._bank_display_data_source = DisplayDataSource()
        self._bank_display.segment(0).set_data_source(self._bank_display_data_source)
        self._pad_display = NumericalDisplayElement(2, 1)
        self._pad_display.name = "Pad_Display"
        self._pad_display.set_message_parts(SYSEX_START + (18,), (0, 247))
        self._pad_display.set_clear_all_message(CLEAR_PAD)
        self._pad_display_data_source = DisplayDataSource()
        self._pad_display.segment(0).set_data_source(self._pad_display_data_source)

    def _setup_mixer(self):
        self._mixer_for_encoders = SpecialMixerComponent(self._name_display, self._value_display, 8)
        self._mixer_for_encoders.name = "Mixer_for_encoders"
        self._mixer_for_faders = SpecialMixerComponent(self._name_display, self._value_display, 8)
        self._mixer_for_faders.name = "Mixer_for_faders"

    def _setup_session(self):
        self._session = SpecialSessionComponent(8, 0)
        self._session.name = "Session_Control"
        self._session.selected_scene().name = "Selected_Scene"
        self._session.set_mixer(self._mixer_for_encoders)
        self._session.set_alt_mixer(self._mixer_for_faders)
        self._session.add_offset_listener(self._update_bank_value)

    def _setup_transport(self):
        self._transport = TransportComponent()
        self._transport.name = "Transport"
        self._transport.set_stop_button(self._stop_button)
        self._transport.set_play_button(self._play_button)
        self._transport.set_record_button(self._rec_button)
        transport_view_modes = TransportViewModeSelector(
            self._transport, self._session, self._ffwd_button, self._rwd_button, self._loop_button
        )
        transport_view_modes.name = "Transport_View_Modes"

    def _setup_device(self):
        self._device_for_encoders = BestBankDeviceComponent()
        self._device_for_encoders.name = "Device_Component_for_encoders"
        self._device_for_faders = BestBankDeviceComponent()
        self._device_for_faders.name = "Device_Component_for_faders"
        self.set_device_component(self._device_for_encoders)
        self.set_alt_device_component(self._device_for_faders)
        self._device_nav = DeviceNavComponent()
        self._device_nav.name = "Device_Nav_Component"

    def _setup_modes(self):
        self._fader_button_modes = FaderButtonModeSelector(self._mixer_for_faders, tuple(self._fader_buttons))
        self._fader_button_modes.name = "Fader_Button_Modes"
        self._fader_button_modes.set_mode_toggle(self._fader_group_mode_button)
        self._fader_modes = FaderModeSelector(
            self._mixer_for_faders,
            self._device_for_faders,
            tuple(self._faders),
            self._fader_button_modes,
            self._master_fader_button,
        )
        self._fader_modes.name = "Fader_Modes"
        self._fader_modes.set_mode_buttons((self._fader_group_mix_button, self._fader_group_fx_button))
        self._encoder_modes = EncoderModeSelector(
            self._mixer_for_encoders, self._device_for_encoders, tuple(self._encoders)
        )
        self._encoder_modes.name = "Encoder_Modes"
        self._encoder_modes.set_mode_buttons((self._encoder_group_mix_button, self._encoder_group_fx_button))
        main_modes = MainModeSelector(
            self._device_for_encoders,
            self._device_for_faders,
            self._session,
            self._mixer_for_faders,
            self._device_nav,
            self._up_button,
            self._down_button,
            self._left_button,
            self._right_button,
            self._select_button,
        )
        main_modes.name = "Main_Modes"
        main_modes.set_mode_buttons((self._main_group_track_button, self._main_group_fx_button))

    def _setup_master_fader(self):
        if self._has_faders:
            self._mixer_for_encoders.master_strip().set_volume_control(self._master_fader)
        else:
            self._mixer_for_encoders.selected_strip().set_volume_control(self._master_fader)

    def _setup_single_fader_button_modes(self):
        self._single_fader_button_modes = SingleFaderButtonModeSelector(
            self._mixer_for_encoders, self._fader_group_midi_button
        )
        self._single_fader_button_modes.name = "Single_Fader_Button_Modes"
        self._single_fader_button_modes.set_mode_toggle(self._fader_group_mode_button)

    def _complete_setup(self):
        self._setup_drum_pads()
        self._set_drum_pads_to_hc()
        self._setup_master_fader()
        if not self._has_faders:
            self._setup_single_fader_button_modes()
        for control in self.controls:
            if isinstance(control, InputControlElement):
                control.clear_send_cache()

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

        self._fader_group_midi_button.send_value(LED_OFF, True)
        self._encoder_group_midi_button.send_value(LED_OFF, True)
        self._main_group_hyper_button.send_value(AMB_FULL, True)
        self.request_rebuild_midi_map()
        self._on_selected_track_changed()
        self.schedule_message(1, self._show_startup_message)

    def _show_startup_message(self):
        self._send_midi(SYSEX_START + CLEAR_ALL)
        self._name_display.display_message("Ableton Live")
        self._display_reset_delay = INITIAL_DISPLAY_DELAY

    def _select_button_value(self, value):
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _identify_value(self, value):
        for encoder in self._encoders:
            encoder.set_identify_mode(value > 0)

        for fader in self._faders:
            fader.set_identify_mode(value > 0)

        self._master_fader.set_identify_mode(value > 0)
        self._display_reset_delay = 0
        self._identify_button.turn_on() if value > 0 else self._identify_button.turn_off()

    def _midi_button_value(self, value, sender):
        if value > 0:
            if sender is self._drum_group_midi_button:
                hc_byte = self._hc_byte ^ PADS
                if hc_byte != self._hc_byte:
                    self._hc_byte = hc_byte
                    self._drum_group_hyper_button.send_value(LED_OFF, True)
                    self.schedule_message(1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247))
            elif sender is self._encoder_group_midi_button:
                hc_byte = self._hc_byte ^ ENCODERS
                if hc_byte != self._hc_byte:
                    self._hc_byte = hc_byte
                    self._encoder_group_mix_button.send_value(LED_OFF, True)
                    self._encoder_group_fx_button.send_value(LED_OFF, True)
                    if self._encoder_modes.mode_index < 3:
                        self._encoder_modes.set_enabled(False)
                    self.schedule_message(1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247))
            elif sender is self._fader_group_midi_button:
                if self._has_faders:
                    hc_byte = self._hc_byte ^ FADERS
                    if hc_byte != self._hc_byte:
                        self._hc_byte = hc_byte
                        self._fader_group_mix_button.send_value(LED_OFF, True)
                        self._fader_group_fx_button.send_value(LED_OFF, True)
                        self._fader_group_mode_button.send_value(LED_OFF, True)
                        if self._fader_modes.mode_index < 2:
                            self._fader_modes.set_enabled(False)
                            self._fader_button_modes.set_enabled(False)
                        self.schedule_message(1, self._send_midi, SYSEX_START + (32, self._hc_byte, 247))
                else:
                    self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _hyper_button_value(self, value, sender):
        if value > 0:
            if sender is self._drum_group_hyper_button:
                if self._hc_byte | PADS != self._hc_byte:
                    self._hc_byte = self._hc_byte | PADS
                    self._send_midi(SYSEX_START + (32, self._hc_byte, 247))
                    self.schedule_message(1, self._set_drum_pads_to_hc)
            elif sender is self._encoder_group_fx_button or sender is self._encoder_group_mix_button:
                if self._hc_byte | ENCODERS != self._hc_byte:
                    self._hc_byte = self._hc_byte | ENCODERS
                    self._send_midi(SYSEX_START + (32, self._hc_byte, 247))
                    self._encoder_group_midi_button.turn_off()
                    if sender is self._encoder_group_fx_button:
                        self._encoder_modes.set_enabled(True)
                        self._display_reset_delay = 0
                        return
                    else:
                        self.schedule_message(1, self._encoder_modes.set_enabled, True)
                        self.schedule_message(1, self._encoder_modes.update)
                        self._display_reset_delay = 2
                        return
            elif sender is self._fader_group_fx_button or sender is self._fader_group_mix_button:
                if self._hc_byte | FADERS != self._hc_byte:
                    self._hc_byte = self._hc_byte | FADERS
                    self._send_midi(SYSEX_START + (32, self._hc_byte, 247))
                    self._fader_group_midi_button.turn_off()
                    self._fader_button_modes.set_enabled(True)
                    if sender is self._fader_group_fx_button:
                        self._fader_modes.set_enabled(True)
                        self._fader_button_modes.set_enabled(True)
                        self._display_reset_delay = 0
                        return
                    else:
                        self.schedule_message(1, self._fader_modes.set_enabled, True)
                        self.schedule_message(1, self._fader_modes.update)
                        self.schedule_message(1, self._fader_button_modes.set_enabled, True)
                        self.schedule_message(1, self._fader_button_modes.update)
                        self._display_reset_delay = 2
                        return
            self._display_reset_delay = 0

    def _set_drum_pads_to_hc(self):
        self._drum_group_midi_button.send_value(LED_OFF, True)
        self._drum_group_hyper_button.send_value(RED_FULL, True)
        for index in range(len(self._drum_pads)):
            self._drum_pads[index].send_value(RED_LOW, True)

    def _fader_button_value(self, value, sender):
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _fader_value(self, value, sender):
        param = sender.mapped_parameter()
        if param != None:
            param_range = param.max - param.min
            if param.name == "Track Volume":
                if sender == self._master_fader:
                    if self._has_faders:
                        name_string = "Master  Vol"
                    else:
                        name_string = (
                            self._mixer_for_faders.selected_strip().track_name_data_source().display_string() + "   Vol"
                        )
                else:
                    name_string = (
                        self._mixer_for_faders.channel_strip(self._faders.index(sender))
                        .track_name_data_source()
                        .display_string()
                        + "   Vol"
                    )
            else:
                name_string = param.name
                value = int((param.value - param.min) / param_range * 127)
            value_string = str(value)
        else:
            name_string = "<unmapped>"
            value_string = None
            self.schedule_message(1, self._set_value_string)
        self._set_name_string(name_string)
        self._set_value_string(value_string)

    def _encoder_value(self, value, sender):
        param = sender.mapped_parameter()
        if param != None:
            param_range = param.max - param.min
            if param.name == "Track Volume":
                name_string = (
                    self._mixer_for_encoders.channel_strip(self._encoders.index(sender))
                    .track_name_data_source()
                    .display_string()
                    + "   Vol"
                )
                value = int((param.value - param.min) / param_range * 127)
            elif param.name == "Track Panning":
                name_string = (
                    self._mixer_for_encoders.channel_strip(self._encoders.index(sender))
                    .track_name_data_source()
                    .display_string()
                    + "   Pan"
                )
                value = int(param.value / param_range * 127)
                if value < 0:
                    name_string += "  L"
                elif value > 0:
                    name_string += "  R"
                else:
                    name_string += "  C"
            else:
                name_string = param.name
                value = int((param.value - param.min) / param_range * 127)
            value_string = str(value)
        else:
            name_string = "<unmapped>"
            value_string = None
            self.schedule_message(1, self._set_value_string)
        self._set_name_string(name_string)
        self._set_value_string(value_string)

    def _set_displays_to_default(self):
        self._name_display.segment(0).set_data_source(
            self._mixer_for_encoders.selected_strip().track_name_data_source()
        )
        self._name_display.update()
        self._update_bank_value()
        self._set_value_string(None)
        self._send_midi(SYSEX_START + LCD_HC_DEFAULT)

    def _set_name_string(self, name_string):
        self._name_display.segment(0).set_data_source(self._name_display_data_source)
        self._name_display_data_source.set_display_string(name_string)
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _set_value_string(self, value_string=None):
        if value_string != None:
            self._value_display_data_source.set_display_string(value_string)
        else:
            self._value_display.reset()

    def _set_bank_string(self, bank_string=None):
        if bank_string != None:
            self._bank_display_data_source.set_display_string(bank_string)
        else:
            self._bank_display.reset()

    def _update_bank_value(self):
        bank = (self._session.track_offset() + 1) / self._session.width() + 1
        self._set_bank_string(str(bank))

    def _install_mapping(self, midi_map_handle, control, parameter, feedback_delay, feedback_map):
        if not self._in_build_midi_map:
            raise AssertionError
            raise midi_map_handle != None or AssertionError
            raise control != None and parameter != None or AssertionError
            raise isinstance(parameter, Live.DeviceParameter.DeviceParameter) or AssertionError
            raise isinstance(control, InputControlElement) or AssertionError
            raise isinstance(feedback_delay, int) or AssertionError
            if not isinstance(feedback_map, tuple):
                raise AssertionError
                success = False
                feedback_rule = None
                feedback_rule = control.message_type() is MIDI_NOTE_TYPE and Live.MidiMap.NoteFeedbackRule()
                feedback_rule.note_no = 0
                feedback_rule.vel_map = (0,)
            elif control.message_type() is MIDI_CC_TYPE:
                feedback_rule = Live.MidiMap.CCFeedbackRule()
                feedback_rule.cc_no = 0
                feedback_rule.cc_value_map = (0,)
            elif control.message_type() is MIDI_PB_TYPE:
                feedback_rule = Live.MidiMap.PitchBendFeedbackRule()
                feedback_rule.value_pair_map = feedback_map
            raise feedback_rule != None or AssertionError
            feedback_rule.channel = control.message_channel()
            feedback_rule.delay_in_ms = feedback_delay
            success = control.message_type() is MIDI_NOTE_TYPE and Live.MidiMap.map_midi_note_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(), control.message_identifier(), feedback_rule
            )
        elif control.message_type() is MIDI_CC_TYPE:
            success = Live.MidiMap.map_midi_cc_with_feedback_map(
                midi_map_handle,
                parameter,
                control.message_channel(),
                control.message_identifier(),
                control.message_map_mode(),
                feedback_rule,
                not control.needs_takeover(),
            )
        elif control.message_type() is MIDI_PB_TYPE:
            success = Live.MidiMap.map_midi_pitchbend_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(), feedback_rule, not control.needs_takeover()
            )
        return success
Пример #35
0
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            is_momentary = True
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = 'HyperControl'
            self._suggested_output_port = 'HyperControl'
            self._display_on_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 15, 79)
            self._waiting_for_first_response = True
            mixer1 = DisplayingMixerComponent(0)
            mixer1.set_select_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 111), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 110))
            mixer1.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 12))
            mixer1.set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 13))
            mixer2 = NotifyingMixerComponent(8)
            mixer2.set_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 15), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 14))
            mixer2.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 41))
            for index in range(8):
                mixer2.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 33 + index))

            device = PageableDeviceComponent(device_selection_follows_track_selection=True)
            self.set_device_component(device)
            ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 115)
            rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 114)
            loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 113)
            transport = TransportComponent()
            transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 116))
            transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117))
            transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 118))
            session = SessionComponent(0, 0)
            transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button)
            select_button_modes = SelectButtonModeSelector(mixer2, tuple([ ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 49 + offset) for offset in range(8) ]))
            select_button_modes.set_mode_toggle(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 57))
            self._mixer_encoder_modes = EncoderMixerModeSelector(mixer2)
            encoders = []
            for offset in range(8):
                encoders.append(PeekableEncoderElement(MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment))
                encoders[-1].set_feedback_delay(-1)

            mixer_or_device = MixerOrDeviceModeSelector(self._mixer_encoder_modes, device, tuple(encoders), tuple([ ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 74 + offset) for offset in range(4) ]))
            mixer_or_device.set_mode_toggle(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109))
            mixer_or_device.set_peek_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 78))
            self._track_display = PhysicalDisplayElement(8, 1)
            self._track_display.set_clear_all_message(SYSEX_START + (16, 247))
            self._track_display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247,))
            self._track_display.segment(0).set_data_source(mixer1.selected_strip().track_name_data_source())
            device_display = PhysicalDisplayElement(8, 1)
            device_display.set_message_parts(SYSEX_START + (17, 1, 0, 10), (247,))
            parameter_display = PhysicalDisplayElement(16, 1)
            parameter_display.set_message_parts(SYSEX_START + (17, 2, 0, 0), (247,))
            select_button_modes.set_mode_display(parameter_display)
            mixer1.set_display(parameter_display)
            mixer2.set_bank_display(parameter_display)
            page_displays = []
            for index in range(4):
                page_displays.append(PhysicalDisplayElement(5, 1))
                page_displays[-1].set_message_parts(SYSEX_START + (17,
                 4,
                 index,
                 0), (247,))

            encoder_display = PhysicalDisplayElement(80, 8)
            encoder_display.set_message_parts(SYSEX_START + (17, 3), (247,))
            for index in range(8):
                pos_id = tuple()
                if index != 0:
                    pos_id += (0,)
                if index > 3:
                    pos_id += (index % 4, 13)
                else:
                    pos_id += (index % 4, 0)
                encoder_display.segment(index).set_position_identifier(pos_id)

            mixer_or_device.set_displays(encoder_display, parameter_display, device_display, tuple(page_displays))
            for component in self.components:
                component.set_enabled(False)
Пример #36
0
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
Пример #37
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()
Пример #38
0
 def __init__(self, c_instance):
     ControlSurface.__init__(self, c_instance)
     transport = TransportComponent() #Instantiate a Transport Component
     transport.set_play_button(ButtonElement(True, 0, 0, 61)) #ButtonElement(is_momentary, msg_type, channel, identifier)
     transport.set_stop_button(ButtonElement(True, 0, 0, 63))
     transport.set_record_button(ButtonElement(True, 0, 0, 66))
Пример #39
0
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)
    
Пример #40
0
class Axiom_OJI(AxiomPro):
    """ Script for the M-Audio Axiom Pro OJI version """

    _browser_mode_enabled = False

    def __init__(self, *a, **k):
        #super(Axiom_OJI, self).__init__(*a, **k)
        ControlSurface.__init__(self, *a, **k)
        with self.component_guard():
            is_momentary = True
            #self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = u'HyperControl'
            self._suggested_output_port = u'HyperControl'
            self._display_on_button = ButtonElement(not is_momentary,
                                                    MIDI_CC_TYPE, 15, 79)
            self._waiting_for_first_response = True
            self._mixer1 = DisplayingMixerComponent(0)
            self._mixer1.set_select_buttons(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 111),
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 110))
            self._mixer1.set_mute_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 12))
            self._mixer1.set_solo_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 13))
            self._mixer2 = NotifyingMixerComponent(8)
            self._mixer2.set_bank_buttons(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 15),
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 14))
            self._mixer2.master_strip().set_volume_control(
                SliderElement(MIDI_CC_TYPE, 15, 41))
            for index in range(8):
                self._mixer2.channel_strip(index).set_volume_control(
                    SliderElement(MIDI_CC_TYPE, 15, 33 + index))

            self._device = PageableDeviceComponent(
                device_selection_follows_track_selection=True)
            self.set_device_component(self._device)
            self._ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15,
                                              115)
            self._rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15,
                                             114)
            self._loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15,
                                              113)
            self._transport = TransportComponent()
            self._transport.set_stop_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 116))
            self._transport.set_play_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117))
            self._transport.set_record_button(
                ButtonElement(is_momentary,
                              MIDI_CC_TYPE,
                              15,
                              118,
                              name='RecordButton'))
            self._session = SessionComponent(0, 0)
            self._transport_view_modes = TransportViewModeSelector(
                self._transport, self._session, self._ffwd_button,
                self._rwd_button, self._loop_button)
            self._select_button_modes = SelectButtonModeSelector(
                self._mixer2,
                tuple([
                    ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 49 + offset)
                    for offset in range(8)
                ]))
            self._select_button_modes.set_mode_toggle(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 57))
            self._mixer_encoder_modes = EncoderMixerModeSelector(self._mixer2)
            self._encoders = []
            for offset in range(8):
                self._encoders.append(
                    PeekableEncoderElement(
                        MIDI_CC_TYPE, 15, 17 + offset,
                        Live.MidiMap.MapMode.relative_smooth_two_compliment))
                self._encoders[-1].set_feedback_delay(-1)

            self._mixer_or_device = MixerOrDeviceModeSelector(
                self._mixer_encoder_modes, self._device, tuple(self._encoders),
                tuple([
                    ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 74 + offset)
                    for offset in range(4)
                ]))
            self._mixer_or_device.set_mode_toggle(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109))
            self._mixer_or_device.set_peek_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 78))
            self._track_display = PhysicalDisplayElement(8, 1)
            self._track_display.set_clear_all_message(SYSEX_START + (16, 247))
            self._track_display.set_message_parts(SYSEX_START + (17, 1, 0, 0),
                                                  (247, ))
            #self._track_display.segment(0).set_data_source(mixer1.selected_strip().track_name_data_source())
            self._device_display = PhysicalDisplayElement(8, 1)
            self._device_display.set_message_parts(
                SYSEX_START + (17, 1, 0, 10), (247, ))
            self._parameter_display = PhysicalDisplayElement(16, 1)
            self._parameter_display.set_message_parts(
                SYSEX_START + (17, 2, 0, 0), (247, ))
            #self._select_button_modes.set_mode_display(parameter_display)
            #self._mixer1.set_display(parameter_display)
            #self._mixer2.set_bank_display(parameter_display)
            self._page_displays = []
            for index in range(4):
                self._page_displays.append(PhysicalDisplayElement(5, 1))
                self._page_displays[-1].set_message_parts(
                    SYSEX_START + (17, 4, index, 0), (247, ))

            self._encoder_display = PhysicalDisplayElement(80, 8)
            self._encoder_display.set_message_parts(SYSEX_START + (17, 3),
                                                    (247, ))
            for index in range(8):
                pos_id = tuple()
                if index != 0:
                    pos_id += (0, )
                if index > 3:
                    pos_id += (index % 4, 13)
                else:
                    pos_id += (index % 4, 0)
                self._encoder_display.segment(index).set_position_identifier(
                    pos_id)

            self._data_sources = [
                DisplayDataSource('                           ')
                for index in range(7)
            ]
            top_display = PhysicalDisplayElement(20, 1)
            top_display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247, ))
            top_display.set_clear_all_message(SYSEX_START + (16, 247))
            self._header_display = top_display
            self._display1 = top_display.segment(0)
            long_display = PhysicalDisplayElement(80, 4)
            long_display.set_message_parts(SYSEX_START + (
                17,
                3,
            ), (247, ))
            self._display2 = long_display.segment(0)
            pos_id = tuple()
            pos_id += (0, 0)
            self._display2.set_position_identifier(pos_id)
            self._display3 = long_display.segment(1)
            pos_id = tuple()
            pos_id += (0, 1, 0)
            self._display3.set_position_identifier(pos_id)
            self._display4 = long_display.segment(2)
            pos_id = tuple()
            pos_id += (0, 2, 0)
            self._display4.set_position_identifier(pos_id)
            self._display5 = long_display.segment(3)
            pos_id = tuple()
            pos_id += (0, 3, 0)
            self._display5.set_position_identifier(pos_id)
            middle_display = PhysicalDisplayElement(20, 1)
            middle_display.set_message_parts(SYSEX_START + (17, 2, 0, 0),
                                             (247, ))
            self._display6 = middle_display.segment(0)
            bottom_display = PhysicalDisplayElement(20, 1)
            bottom_display.set_message_parts(SYSEX_START + (17, 4, 0, 0),
                                             (247, ))
            self._display7 = bottom_display.segment(0)

            self._browser_displays = [
                self._display1, self._display2, self._display3, self._display4,
                self._display5, self._display6, self._display7
            ]
            self._drumpads = [
                ButtonElement(True,
                              MIDI_NOTE_TYPE,
                              15,
                              81 + index,
                              name='Pad_' + str(index)) for index in range(8)
            ]
            self._setup_m4l_interface()

        self.log_message('Axiom_OJI script installed')

    """
	def __init__(self, *a, **k):
		super(Axiom_OJI, self).__init__(*a, **k)
		with self.component_guard():
			#self._data_sources = (DisplayDataSource('TEST') for index in range(7))
			self._display1 = PhysicalDisplayElement(16, 1)
			self._display1.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247,))
			self._header_display = self._display1
			self._header_display.set_clear_all_message(SYSEX_START + (16, 247))
			self._display2 = PhysicalDisplayElement(16, 1)
			self._display2.set_message_parts(SYSEX_START + (17, 3, 0, 0), (247,))
			self._display3 = PhysicalDisplayElement(16, 1)
			self._display3.set_message_parts(SYSEX_START + (17, 3, 1, 0), (247,))
			self._display4 = PhysicalDisplayElement(16, 1)
			self._display4.set_message_parts(SYSEX_START + (17, 3, 2, 0), (247,))
			self._display5 = PhysicalDisplayElement(16, 1)
			self._display5.set_message_parts(SYSEX_START + (17, 3, 3, 0), (247,))
			self._display6 = PhysicalDisplayElement(16, 1)
			self._display6.set_message_parts(SYSEX_START + (17, 2, 0, 0), (247,))
			self._display7 = PhysicalDisplayElement(16, 1)
			self._display7 .set_message_parts(SYSEX_START + (17, 4, 0, 0), (247,))
			self._browser_displays = [self._display1, self._display2, self._display3, self._display4, self._display5, self._display6, self._display7]
	"""

    def _setup_m4l_interface(self):
        self._m4l_interface = M4LInterfaceComponent(
            controls=self.controls,
            component_guard=self.component_guard,
            priority=10)
        self._m4l_interface.name = "M4LInterface"
        self.get_control_names = self._m4l_interface.get_control_names
        self.get_control = self._m4l_interface.get_control
        self.grab_control = self._m4l_interface.grab_control
        self.release_control = self._m4l_interface.release_control

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:-2] == SYSEX_START + (32, ):
            msg_id_byte = midi_bytes[-2]
            is_setup_response = msg_id_byte in (46, 38)
            has_sliders = msg_id_byte == 46
            if is_setup_response:
                if self._waiting_for_first_response:
                    self._waiting_for_first_response = False
                    self._display_on_button.send_value(0)
                    if not self._browser_mode_enabled:
                        for component in self.components:
                            component.set_enabled(True)

                    self._display_on_button.send_value(127)
                    self._send_midi(SYSEX_START + (16, 247))
                    self._send_midi(SYSEX_START +
                                    (17, 3, 0, 1, 65, 98, 108, 101, 116, 111,
                                     110, 32, 76, 105, 118, 101, 32, 67, 111,
                                     110, 116, 114, 111, 108, 32, 0, 1, 4, 83,
                                     117, 114, 102, 97, 99, 101, 32, 118, 49,
                                     46, 48, 46, 48, 46, 247))
                self._mixer_encoder_modes.set_show_volume_page(not has_sliders)
                #if not self._browser_mode_enabled:
                for display in self._displays:
                    display.set_block_messages(False)

                self.schedule_message(25, self._refresh_displays)
                #self.schedule_message(30, self._enable_browser)
            elif msg_id_byte == 43:
                self._send_midi(SYSEX_START + (16, 247))
                #if not self._browser_mode_enabled:
                for display in self._displays:
                    if display is self._track_display:
                        display.update()
                    else:
                        display.set_block_messages(True)

    def _enable_browser(self):
        self.enable_browser_mode(True)

    def enable_browser_mode(self, enable):
        self._browser_mode_enabled = enable > 0
        debug('enable_browser_mode:' + str(enable))
        if enable:
            for component in self.components:
                component.set_enabled(False)
            self._header_display.reset()
            self._track_display.segment(0).set_data_source(None)
            for index in range(7):
                debug('index: ' + str(index))
                self._browser_displays[index].set_data_source(
                    self._data_sources[index])
        else:
            self._header_display.reset()
            for index in range(7):
                debug('index: ' + str(index))
                self._browser_displays[index].set_data_source(None)
            for component in self.components:
                component.set_enabled(True)

    def _enable_browser_mode(self, enable):
        self._browser_mode_enabled = enable > 0
        #debug('enable_browser_mode', enable)
        if enable:
            #debug('here 1')
            for component in self.components:
                component.set_enabled(False)
            self._header_display.reset()
            #debug('here 2')
            #for index, display in enumerate(self._browser_displays):
            #debug('index:', index, 'display:', display)
            #self._data_sources[index].clear()
            #display.set_data_source(self._data_sources[index])
        else:
            for component in self.components:
                component.set_enabled(True)

    def write_to_lcd(self, display, message):
        if self._browser_mode_enabled and display in range(7):
            self._data_sources[display].set_display_string(message)

    def test_browser(self):
        debug('test_browser')
        browser = self.application.browser
        debug('browser is:', browser)
        user_folders = browser.user_folders
        debug('user_folders are:', user_folders)
        for item in user_folders:
            #debug('item is:', item, item.name)
            if item.name == 'defaultPresets':
                inneritems = item.iter_children
                for inneritem in inneritems:
                    debug('inneritem:', inneritem)
                    if inneritem.name == 'Default.aupreset':
                        browser.load_item(inneritem)
                        break

    def load_preset(self,
                    target=None,
                    folder=None,
                    directory='defaultPresets'):
        debug('load_preset()', target, folder, directory)
        if not target is None:
            browser = Live.Application.get_application(
            ).browser  ##if not self.application.view.browse_mode else self.application.browser.hotswap_target
            user_folders = browser.user_folders
            for item in user_folders:
                if item.name == directory:
                    if not folder is None:
                        folder_target = None
                        item_iterator = item.iter_children
                        inneritems = [inneritem for inneritem in item_iterator]
                        for inneritem in inneritems:
                            if inneritem.name == folder:
                                folder_target = inneritem
                                break
                        if folder_target:
                            item_iterator = folder_target.iter_children
                            inneritems = [
                                inneritem for inneritem in item_iterator
                            ]
                            for inneritem in inneritems:
                                if isinstance(target, int):
                                    if target < len(inneritems):
                                        if inneritems[target].is_loadable:
                                            browser.load_item(
                                                inneritems[target])
                                            break
                                        elif inneritems[target].is_folder:
                                            debug(inneritems[target],
                                                  '.is_folder')
                                            innertarget = inneritems[target]
                                            innertarget_iterator = innertarget.iter_children
                                            innertargetitems = [
                                                innertargetitem
                                                for innertargetitem in
                                                innertarget_iterator
                                            ]
                                            #debug('innertargetitems:', innertargetitems)
                                            if len(innertargetitems
                                                   ) > 0 and innertargetitems[
                                                       0].is_loadable:
                                                browser.load_item(
                                                    innertargetitems[0])
                                                break
                                            else:
                                                debug(innertargetitems[0],
                                                      'item isnt loadable 0')
                                                break
                                        else:
                                            debug(inneritems[target],
                                                  'item isnt loadable 1')
                                            break
                                else:
                                    if inneritem.name == target:
                                        if inneritem.is_loadable:
                                            browser.load_item(inneritem)
                                        else:
                                            debug(inneritem,
                                                  'item isnt loadable 2')
                                        break
                    else:
                        item_iterator = item.iter_children
                        inneritems = [inneritem for inneritem in item_iterator]
                        for inneritem in inneritems:
                            if isinstance(target, int):
                                if target < len(inneritems):
                                    if inneritems[target].is_loadable:
                                        browser.load_item(inneritems[target])
                                        break
                                    else:
                                        debug(inneritems[target],
                                              'item isnt loadable 3')
                                        break
                            else:
                                if inneritem.name == target:
                                    if inneritem.is_loadable:
                                        browser.load_item(inneritem)
                                        break
                                    else:
                                        debug(inneritem,
                                              'item isnt loadable 4')
                                        break

    def get_preset_names(self, folder=None, directory='defaultPresets'):
        #debug('get_preset_names', folder, directory)
        preset_names = [
            'no target', 'no target', 'no target', 'no target', 'no target',
            'no target', 'no target', 'no target'
        ]
        browser = Live.Application.get_application(
        ).browser  ##if not self.application.view.browse_mode else self.application.browser.hotswap_target
        user_folders = browser.user_folders
        for item in user_folders:
            if item.name == directory:
                if not folder is None:
                    folder_target = None
                    item_iterator = item.iter_children
                    inneritems = [inneritem for inneritem in item_iterator]
                    for inneritem in inneritems:
                        if inneritem.name == folder:
                            folder_target = inneritem
                            break
                    if folder_target:
                        item_iterator = folder_target.iter_children
                        preset_names = [
                            inneritem.name for inneritem in item_iterator
                        ]
                else:
                    item_iterator = item.iter_children
                    preset_names = [
                        inneritem.name for inneritem in item_iterator
                    ]
        #debug('names:', preset_names)
        return preset_names

    def write_presets_to_lcd(self, folder=None, directory='defaultPresets'):
        #debug('write_presets_to_lcd')
        preset_names = self.get_preset_names(folder, directory)
        #debug('names:', preset_names)
        for i, name in enumerate(preset_names):
            if i < 7:
                #debug('name:', i, name)
                self.write_to_lcd(i, name[:20])
Пример #41
0
    def _setup_components(self):

        # Session

        self._session = SessionComponent(8, len(self._scene_launch_buttons))
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._scene_launch_button)
        self._session.set_stop_all_clips_button(self._scene_stop_button)

        for index in range(8):
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_launch_button(self._clip_launch_buttons[index])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(
            tuple(self._clip_stop_buttons))

        # Undo

        self._do_undo.subject = self._clip_undo_button

        # Transport

        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(self._stop_button)
        transport.set_play_button(self._play_button)
        transport.set_record_button(self._rec_button)
        transport.set_loop_button(self._loop_button)

        self._transport_view_modes = TransportViewModeSelector(
            transport, self._session, self._ffwd_button, self._rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

        session_recording = SessionRecordingComponent(
            ClipCreator(),
            ViewControlComponent(),
            name='Session_Recording',
            is_enabled=False,
            layer=Layer(record_button=self._overdub_button))

        # Device

        # device = DeviceComponent()
        # device.name = 'Device_Component'
        # self.set_device_component(device)
        # device.set_parameter_controls(self._encoders)

        # Navigation

        self._session_navigation = SessionNavigationComponent(
            name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

        # Playing
        # self._session.set_scene_launch_buttons(tuple(self._scene_launch_buttons))
        for index in range(len(self._scene_launch_buttons)):
            scene = self._session.scene(index)
            scene.set_launch_button(self._scene_launch_buttons[index])
Пример #42
0
class LiveStrip_A(ControlSurface):
    #Control Surface is central base class. acts as container.
    __module__ = __name__
    __doc__ = "Ableton Live control surface script for liveStrip A"

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._suppress_send_midi = True
            self._suppress_session_highlight = True
            #non-throw-away variables ???
            #self._suggested_input_port = 'LiveStrip'		#???
            #self._suggested_output_port = 'LiveStrip'	#???
            #self._control_is_with_automap = False #for buttons ??? mabye for user-defined mappings
            self._transport = None  #setup a blank transport
            self._session = None  #setup a blank session
            self._device = None  #setup a blank device
            #self._is_locked = False #for device or track
            self.setup_button_control()  #buttons first - important
            #self.setup_rotary_control()   #then rotary encoders - important
            self.setup_transport_control()  #then transport..
            self.setup_session_control()  #..then the rest
            self.setup_device_control()
            self.assign_button_control(
            )  #after everything is set up we can then assign the buttons to things. ref this for updating aswell ???
            self._end_buttons[0].add_value_listener(self._bt0_value)
            self._end_buttons[1].add_value_listener(self._bt1_value)
            self._end_buttons[2].add_value_listener(self._bt2_value)
            self._end_buttons[3].add_value_listener(self._bt3_value)
            self.set_highlighting_session_component(self._session)
            self._suppress_session_highlight = False
        self.log_message("LiveStrip loaded")

    #def refresh_state(self):
    #nothing

    def disconnect(self):
        self._suppress_send_midi = True
        #clean up things
        self._end_buttons[0].remove_value_listener(self._bt0_value)
        self._end_buttons[1].remove_value_listener(self._bt1_value)
        self._end_buttons[2].remove_value_listener(self._bt2_value)
        self._end_buttons[3].remove_value_listener(self._bt3_value)
        #create entry in log file then do final control surface disconnect
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            " - LiveStrip disconnected")
        ControlSurface.disconnect(self)
        return None

    def setup_button_control(self):
        #setup the buttons on the end of the LiveStrip
        #but does not assign them
        #prob do something like enter menu mode by selecting 1 & 2 together, ..blink, confirm, ..then use buttons and knobs for selection.
        is_momentary = True  #button setting (throw-away variable)
        self._end_buttons = [
            ButtonElement(is_momentary, 0, settings.MIDI_CHANNEL,
                          settings.END_NOTES[index]) for index in range(4)
        ]
        for index in range(4):
            #self._end_buttons[index] = ButtonElement(is_momentary, 0, settings.MIDI_CHANNEL, settings.END_NOTES[index])
            self._end_buttons[index].name = settings.BUTTONS_MAP_LIST[
                settings.END_BUTTONS_CURRENT[index]]

    #def setup_rotary_control(self):
    #setup the rotary encoders

    def setup_transport_control(self):
        #is_momentary = True #button setting (throw-away variable)
        self._transport = TransportComponent(
        )  #Instantiate a Transport Component
        #for index in range(4):
        #if settings.END_BUTTONS_CURRENT[index] == 4: #BUTTONS_MAP_LIST - play
        #self._transport.set_play_button(self._end_buttons[index]) #ButtonElement(is_momentary, msg_type, channel, identifier)
        #for index in range(4):
        #if settings.END_BUTTONS_CURRENT[index] == 5: #BUTTONS_MAP_LIST - stop
        #self._transport.set_stop_button(self._end_buttons[index])

    def setup_session_control(self):
        #do i actually need session control ??? ...erm..  ...no, i don't think i do
        #num_tracks = 1 #8 columns (tracks) - see consts
        #num_scenes = 8 #8 rows (scenes) - see consts
        #(num_tracks, num_scenes) a session highlight ("red box")
        #self.session = SessionComponent(num_tracks,num_scenes)
        self._session = SessionComponent(settings.NUM_TRACKS,
                                         settings.NUM_SCENES)
        self._session.set_offsets(0, 0)

    def setup_device_control(self):
        #is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_param_controls = []
        #for index in range(8):
        #  device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
        #if None not in device_param_controls:
        #  self._device.set_parameter_controls(tuple(device_param_controls))
        #self._device.set_on_off_button(self._note_map[DEVICEONOFF])	#have to hand this a button
        #for index in range(4):
        #if settings.END_BUTTONS_CURRENT[index] == 1:	#BUTTONS_MAP_LIST - device lock
        #self._device.set_lock_button(self._end_buttons[index])	#watch out, this way could set several to be the same
        #for index in range(4):
        #if settings.END_BUTTONS_CURRENT[index] == 2:	#BUTTONS_MAP_LIST - device onOff
        #self._device.set_on_off_button(self._end_buttons[index])	#watch out, this way could set several to be the same

        self.set_device_component(self._device)

    def assign_button_control(self):
        for index in range(4):
            self.assign_individual_button_control(index)

    def assign_individual_button_control(self, index):
        if settings.END_BUTTONS_CURRENT[
                index] == 0:  #BUTTONS_MAP_LIST - NONE, or internal to LiveStrip unit.
            #self._device.set_lock_button(self._end_buttons[index])	#watch out, this way could set several to be the same
            do_nothing = True
        elif settings.END_BUTTONS_CURRENT[
                index] == 1:  #BUTTONS_MAP_LIST - play
            self._transport.set_play_button(
                self._end_buttons[index]
            )  #ButtonElement(is_momentary, msg_type, channel, identifier)
        elif settings.END_BUTTONS_CURRENT[
                index] == 2:  #BUTTONS_MAP_LIST - stop
            self._transport.set_stop_button(self._end_buttons[index])
        elif settings.END_BUTTONS_CURRENT[
                index] == 3:  #BUTTONS_MAP_LIST - device lock
            self._device.set_lock_button(self._end_buttons[index])
        elif settings.END_BUTTONS_CURRENT[
                index] == 4:  #BUTTONS_MAP_LIST - device on off
            self._device.set_on_off_button(self._end_buttons[index])
        elif settings.END_BUTTONS_CURRENT[index] == 5:  #BUTTONS_MAP_LIST - ???
            #self._device.set_on_off_button(self._end_buttons[index])
            do_nothing = False

        self._end_buttons[index].name = settings.BUTTONS_MAP_LIST[
            settings.END_BUTTONS_CURRENT[index]]  #set the name

    def _bt0_value(self, value):
        #callback when bt0 is triggered
        assert value in range(128)
        self.button_trigger(0, value)
        self.log_message("_bt0_value triggered %d" % (value))

    def _bt1_value(self, value):
        #callback when bt1 is triggered
        assert value in range(128)
        self.button_trigger(1, value)
        self.log_message("_bt1_value triggered %d" % (value))

    def _bt2_value(self, value):
        #callback when bt2 is triggered
        assert value in range(128)
        self.button_trigger(2, value)
        self.log_message("_bt2_value triggered %d" % (value))

    def _bt3_value(self, value):
        #callback when bt3 is triggered
        assert value in range(128)
        self.button_trigger(3, value)
        self.log_message("_bt3_value triggered %d" % (value))

    def button_trigger(self, index, value):
        if settings.END_BUTTONS_CURRENT[
                index] == 0:  #BUTTONS_MAP_LIST - NONE, or internal to LiveStrip unit.
            #self._device.set_lock_button(self._end_buttons[index])	#watch out, this way could set several to be the same
            do_nothing = True
        elif settings.END_BUTTONS_CURRENT[
                index] == 1:  #BUTTONS_MAP_LIST - play
            if (value != 0):
                do_nothing = False
#self._play_button.turn_on()
            else:
                do_nothing = True
#self._play_button.turn_off()
        elif settings.END_BUTTONS_CURRENT[
                index] == 2:  #BUTTONS_MAP_LIST - stop
            self._transport.set_stop_button(self._end_buttons[index])
        elif settings.END_BUTTONS_CURRENT[
                index] == 3:  #BUTTONS_MAP_LIST - device lock
            self._device.set_lock_button(self._end_buttons[index])
        elif settings.END_BUTTONS_CURRENT[
                index] == 4:  #BUTTONS_MAP_LIST - device on off
            self._device.set_on_off_button(self._end_buttons[index])
        elif settings.END_BUTTONS_CURRENT[index] == 5:  #BUTTONS_MAP_LIST - ???
            #self._device.set_on_off_button(self._end_buttons[index])
            do_nothing = False
Пример #43
0
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            is_momentary = True
            self._device_selection_follows_track_selection = True
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = 'HyperControl'
            self._suggested_output_port = 'HyperControl'
            self._display_on_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 15, 79)
            self._waiting_for_first_response = True
            mixer1 = DisplayingMixerComponent(0)
            mixer1.set_select_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 111), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 110))
            mixer1.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 12))
            mixer1.set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 13))
            mixer2 = NotifyingMixerComponent(8)
            mixer2.set_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 15), ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 14))
            mixer2.master_strip().set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 41))
            for index in range(8):
                mixer2.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, 15, 33 + index))

            device = PageableDeviceComponent()
            self.set_device_component(device)
            ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 115)
            rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 114)
            loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 113)
            transport = TransportComponent()
            transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 116))
            transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117))
            transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 118))
            session = SessionComponent(0, 0)
            transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button)
            select_button_modes = SelectButtonModeSelector(mixer2, tuple([ ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 49 + offset) for offset in range(8) ]))
            select_button_modes.set_mode_toggle(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 57))
            self._mixer_encoder_modes = EncoderMixerModeSelector(mixer2)
            encoders = []
            for offset in range(8):
                encoders.append(PeekableEncoderElement(MIDI_CC_TYPE, 15, 17 + offset, Live.MidiMap.MapMode.relative_smooth_two_compliment))
                encoders[-1].set_feedback_delay(-1)

            mixer_or_device = MixerOrDeviceModeSelector(self._mixer_encoder_modes, device, tuple(encoders), tuple([ ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 74 + offset) for offset in range(4) ]))
            mixer_or_device.set_mode_toggle(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109))
            mixer_or_device.set_peek_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 78))
            self._track_display = PhysicalDisplayElement(8, 1)
            self._track_display.set_clear_all_message(SYSEX_START + (16, 247))
            self._track_display.set_message_parts(SYSEX_START + (17, 1, 0, 0), (247,))
            self._track_display.segment(0).set_data_source(mixer1.selected_strip().track_name_data_source())
            device_display = PhysicalDisplayElement(8, 1)
            device_display.set_message_parts(SYSEX_START + (17, 1, 0, 10), (247,))
            parameter_display = PhysicalDisplayElement(16, 1)
            parameter_display.set_message_parts(SYSEX_START + (17, 2, 0, 0), (247,))
            select_button_modes.set_mode_display(parameter_display)
            mixer1.set_display(parameter_display)
            mixer2.set_bank_display(parameter_display)
            page_displays = []
            for index in range(4):
                page_displays.append(PhysicalDisplayElement(5, 1))
                page_displays[-1].set_message_parts(SYSEX_START + (17,
                 4,
                 index,
                 0), (247,))

            encoder_display = PhysicalDisplayElement(80, 8)
            encoder_display.set_message_parts(SYSEX_START + (17, 3), (247,))
            for index in range(8):
                pos_id = tuple()
                if index != 0:
                    pos_id += (0,)
                if index > 3:
                    pos_id += (index % 4, 13)
                else:
                    pos_id += (index % 4, 0)
                encoder_display.segment(index).set_position_identifier(pos_id)

            mixer_or_device.set_displays(encoder_display, parameter_display, device_display, tuple(page_displays))
            for component in self.components:
                component.set_enabled(False)
Пример #44
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)
class Axiom_AIR_25_49_61(ControlSurface):
    """ Script for the M-Audio Axiom A.I.R. 25, 49 and 61 """
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._alt_device_component = None
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'HyperControl'
            self._suggested_output_port = 'HyperControl'
            self._single_fader_button_modes = None
            self._has_faders = True
            self._display_reset_delay = -1
            self._hc_byte = HC_BYTE
            self._waiting_for_first_response = True
            self._setup_controls()
            self._setup_displays()
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_modes()
            self._drum_group_midi_button = None
            self._drum_group_hyper_button = None
            for component in self.components:
                component.set_enabled(False)

        return

    def disconnect(self):
        self._scheduled_messages = []
        for encoder in self._encoders:
            encoder.remove_value_listener(self._encoder_value)

        for fader in self._faders:
            fader.remove_value_listener(self._fader_value)

        for fader_button in self._fader_buttons:
            fader_button.remove_value_listener(self._fader_button_value)

        self._master_fader.remove_value_listener(self._fader_value)
        self._master_fader_button.remove_value_listener(
            self._fader_button_value)
        self._select_button.remove_value_listener(self._select_button_value)
        self._identify_button.remove_value_listener(self._identify_value)
        self._fader_group_midi_button.remove_value_listener(
            self._midi_button_value)
        self._fader_group_mix_button.remove_value_listener(
            self._hyper_button_value)
        self._fader_group_fx_button.remove_value_listener(
            self._hyper_button_value)
        self._encoder_group_midi_button.remove_value_listener(
            self._midi_button_value)
        self._encoder_group_mix_button.remove_value_listener(
            self._hyper_button_value)
        self._encoder_group_fx_button.remove_value_listener(
            self._hyper_button_value)
        if self._drum_group_midi_button != None:
            self._drum_group_midi_button.remove_value_listener(
                self._midi_button_value)
        if self._drum_group_hyper_button != None:
            self._drum_group_hyper_button.remove_value_listener(
                self._hyper_button_value)
        self._alt_device_component = None
        self._name_display = None
        self._value_display = None
        self._bank_display = None
        self._pad_display = None
        self._name_display_data_source = None
        self._value_display_data_source = None
        self._bank_display_data_source = None
        self._pad_display_data_source = None
        self._select_button = None
        self._left_button = None
        self._right_button = None
        self._up_button = None
        self._down_button = None
        self._loop_button = None
        self._ffwd_button = None
        self._rwd_button = None
        self._play_button = None
        self._stop_button = None
        self._rec_button = None
        self._master_fader_button = None
        self._fader_buttons = None
        self._faders = None
        self._encoders = None
        self._drum_pads = None
        self._identify_button = None
        self._main_group_hyper_button = None
        self._main_group_track_button = None
        self._main_group_fx_button = None
        self._encoder_group_midi_button = None
        self._encoder_group_mix_button = None
        self._encoder_group_fx_button = None
        self._fader_group_mode_button = None
        self._fader_group_midi_button = None
        self._fader_group_mix_button = None
        self._fader_group_fx_button = None
        self._drum_group_midi_button = None
        self._drum_group_roll_button = None
        self._drum_group_hyper_button = None
        self._mixer_for_encoders = None
        self._mixer_for_faders = None
        self._device_for_encoders = None
        self._device_for_faders = None
        self._transport = None
        self._session = None
        ControlSurface.disconnect(self)
        self._send_midi(SYSEX_START + DISABLE_HYPERCONTROL)
        return

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(5, self._send_midi, IDENTITY_REQUEST)

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:10] == AXIOM_AIR_RESPONSE:
            if midi_bytes[12:15] < AXIOM_REV4_RESPONSE:
                self.schedule_message(1, self._send_midi,
                                      SYSEX_START + ENGAGE_HYPERCONTROL)
                self.schedule_message(2, self._send_midi,
                                      SYSEX_START + CLEAR_ALL)
                self.schedule_message(3, self._name_display.display_message,
                                      'Firmware')
                self.schedule_message(13, self._name_display.display_message,
                                      'Update')
                self.schedule_message(23, self._name_display.display_message,
                                      'Required')
                self.schedule_message(33, self._send_midi,
                                      SYSEX_START + DISABLE_HYPERCONTROL)
            elif midi_bytes[12:15] >= AXIOM_REV4_RESPONSE:
                if self._waiting_for_first_response == True:
                    self._waiting_for_first_response = False
                    self._has_faders = midi_bytes[10] != 50
                    self.schedule_message(1, self._send_midi,
                                          SYSEX_START + ENGAGE_HYPERCONTROL)
                    self.schedule_message(2, self._send_midi,
                                          SYSEX_START + SPECIAL_HYPERCONTROL)
                    self.schedule_message(3, self._complete_setup)
                else:
                    self._display_reset_delay = 0
        elif midi_bytes[0:8] == REQUEST_HYPERCONTROL:
            self.schedule_message(5, self._send_midi, IDENTITY_REQUEST)

    def update_display(self):
        ControlSurface.update_display(self)
        if self._display_reset_delay >= 0:
            self._display_reset_delay -= 1
            if self._display_reset_delay == -1:
                self._set_displays_to_default()

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._display_reset_delay = 0

    def restore_bank(self, bank_index):
        ControlSurface.restore_bank(self, bank_index)
        if self._alt_device_component != None:
            self._alt_device_component.restore_bank(bank_index)
        return

    def set_appointed_device(self, device):
        ControlSurface.set_appointed_device(self, device)
        with self.component_guard():
            if self._alt_device_component != None:
                self._alt_device_component.set_device(device)
        return

    def set_alt_device_component(self, device_component):
        self._alt_device_component = device_component

    def _update_device_selection(self):
        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)
        if self._alt_device_component != None:
            self._alt_device_component.set_device(device_to_select)
        return

    def _setup_controls(self):
        self._left_button = create_button(99, 'Left_Button')
        self._right_button = create_button(100, 'Right_Button')
        self._up_button = create_button(101, 'Up_Button')
        self._down_button = create_button(102, 'Down_Button')
        self._loop_button = create_button(113, 'Loop_Button')
        self._rwd_button = create_button(114, 'Rwd_Button')
        self._ffwd_button = create_button(115, 'FFwd_Button')
        self._stop_button = create_button(116, 'Stop_Button')
        self._play_button = create_button(117, 'Play_Button')
        self._rec_button = create_button(118, 'Record_Button')
        self._select_button = ConfigurableButtonElement(
            IS_MOMENTARY, MIDI_CC_TYPE, GLOBAL_CHANNEL, 98)
        self._select_button.name = 'Select_Button'
        self._select_button.add_value_listener(self._select_button_value)
        self._main_group_hyper_button = create_configurable_button(
            104, 'Fader_Group_HyperControl_Button', 2, 14)
        self._main_group_track_button = create_configurable_button(
            105, 'Main_Group_Track_Button', 2, 11)
        self._main_group_fx_button = create_configurable_button(
            106, 'Main_Group_Inst_FX_Button', 2, 11)
        self._identify_button = create_configurable_button(
            97, 'Identify_Button', 2, 16)
        self._identify_button.add_value_listener(self._identify_value)
        self._fader_buttons = []
        for index in range(8):
            self._fader_buttons.append(
                create_configurable_button(49 + index,
                                           'Fader_Button_%d' % index))
            self._fader_buttons[-1].add_value_listener(
                self._fader_button_value, identify_sender=True)

        self._faders = []
        for index in range(8):
            self._faders.append(create_slider(33 + index, 'Fader_%d' % index))
            self._faders[-1].add_value_listener(self._fader_value,
                                                identify_sender=True)

        self._master_fader_button = create_configurable_button(
            57, 'Master_Fader_Button')
        self._master_fader_button.add_value_listener(self._fader_button_value,
                                                     identify_sender=True)
        self._master_fader = create_slider(41, 'Master_Fader')
        self._master_fader.add_value_listener(self._fader_value,
                                              identify_sender=True)
        self._fader_group_mode_button = create_configurable_button(
            61, 'Fader_Group_Mode_Button')
        self._fader_group_midi_button = create_configurable_button(
            60, 'Fader_Group_MIDI_Button')
        self._fader_group_midi_button.add_value_listener(
            self._midi_button_value, identify_sender=True)
        self._fader_group_mix_button = create_configurable_button(
            58, 'Fader_Group_Mix_Button', 0, 1)
        self._fader_group_mix_button.add_value_listener(
            self._hyper_button_value, identify_sender=True)
        self._fader_group_fx_button = create_configurable_button(
            59, 'Fader_Group_Inst_FX_Button', 0, -1)
        self._fader_group_fx_button.add_value_listener(
            self._hyper_button_value, identify_sender=True)
        self._encoders = []
        for index in range(8):
            self._encoders.append(
                create_encoder(17 + index, 'Encoder_%d' % index))
            self._encoders[-1].add_value_listener(self._encoder_value,
                                                  identify_sender=True)

        self._encoder_group_midi_button = create_configurable_button(
            27, 'Encoder_Group_MIDI_Button', 0, 72)
        self._encoder_group_midi_button.add_value_listener(
            self._midi_button_value, identify_sender=True)
        self._encoder_group_mix_button = create_configurable_button(
            25, 'Encoder_Group_Mix_Button', 0, 72)
        self._encoder_group_mix_button.add_value_listener(
            self._hyper_button_value, identify_sender=True)
        self._encoder_group_fx_button = create_configurable_button(
            26, 'Encoder_Group_Inst_FX_Button', 0, 72)
        self._encoder_group_fx_button.add_value_listener(
            self._hyper_button_value, identify_sender=True)

    def _setup_drum_pads(self):
        self._drum_pads = []
        num_pads = 12 if self._has_faders else 16
        for index in range(8):
            self._drum_pads.append(
                create_configurable_button(81 + index, 'Pad_%d' % index, 0, 0,
                                           MIDI_CC_TYPE))

        for index in range(num_pads - 8):
            self._drum_pads.append(
                ConfigurableButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE,
                                          GLOBAL_CHANNEL - 1, 81 + index,
                                          GLOBAL_SEND_CHANNEL, 8,
                                          MIDI_CC_TYPE))
            self._drum_pads[-1].name = 'Pad_' + str(index + 8)

        self._drum_group_midi_button = create_configurable_button(
            91, 'Drum_Group_MIDI_Button', 2, -2)
        self._drum_group_midi_button.add_value_listener(
            self._midi_button_value, identify_sender=True)
        self._drum_group_roll_button = create_configurable_button(
            90, 'Drum_Group_Roll_Button', -1)
        self._drum_group_hyper_button = create_configurable_button(
            89, 'Drum_Group_HyperControl_Button', 2, 2)
        self._drum_group_hyper_button.add_value_listener(
            self._hyper_button_value, identify_sender=True)

    def _setup_displays(self):
        self._name_display = PhysicalDisplayElement(12, 1)
        self._name_display.name = 'Name_Display'
        self._name_display.set_message_parts(SYSEX_START + (21, ), (0, 247))
        self._name_display.set_clear_all_message(CLEAR_NAME)
        self._name_display_data_source = DisplayDataSource()
        self._name_display.segment(0).set_data_source(
            self._name_display_data_source)
        self._value_display = NumericalDisplayElement(3, 1)
        self._value_display.name = 'Value_Display'
        self._value_display.set_message_parts(SYSEX_START + (20, 48), (0, 247))
        self._value_display.set_clear_all_message(CLEAR_VALUE)
        self._value_display_data_source = DisplayDataSource()
        self._value_display.segment(0).set_data_source(
            self._value_display_data_source)
        self._bank_display = NumericalDisplayElement(3, 1)
        self._bank_display.name = 'Bank_Display'
        self._bank_display.set_message_parts(SYSEX_START + (19, ), (0, 247))
        self._bank_display.set_clear_all_message(CLEAR_BANK)
        self._bank_display_data_source = DisplayDataSource()
        self._bank_display.segment(0).set_data_source(
            self._bank_display_data_source)
        self._pad_display = NumericalDisplayElement(2, 1)
        self._pad_display.name = 'Pad_Display'
        self._pad_display.set_message_parts(SYSEX_START + (18, ), (0, 247))
        self._pad_display.set_clear_all_message(CLEAR_PAD)
        self._pad_display_data_source = DisplayDataSource()
        self._pad_display.segment(0).set_data_source(
            self._pad_display_data_source)

    def _setup_mixer(self):
        self._mixer_for_encoders = SpecialMixerComponent(
            self._name_display, self._value_display, 8)
        self._mixer_for_encoders.name = 'Mixer_for_encoders'
        self._mixer_for_faders = SpecialMixerComponent(self._name_display,
                                                       self._value_display, 8)
        self._mixer_for_faders.name = 'Mixer_for_faders'

    def _setup_session(self):
        self._session = SpecialSessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.set_mixer(self._mixer_for_encoders)
        self._session.set_alt_mixer(self._mixer_for_faders)
        self._session.add_offset_listener(self._update_bank_value)

    def _setup_transport(self):
        self._transport = TransportComponent()
        self._transport.name = 'Transport'
        self._transport.set_stop_button(self._stop_button)
        self._transport.set_play_button(self._play_button)
        self._transport.set_record_button(self._rec_button)
        transport_view_modes = TransportViewModeSelector(
            self._transport, self._session, self._ffwd_button,
            self._rwd_button, self._loop_button)
        transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        self._device_for_encoders = BestBankDeviceComponent()
        self._device_for_encoders.name = 'Device_Component_for_encoders'
        self._device_for_faders = BestBankDeviceComponent()
        self._device_for_faders.name = 'Device_Component_for_faders'
        self.set_device_component(self._device_for_encoders)
        self.set_alt_device_component(self._device_for_faders)
        self._device_nav = DeviceNavComponent()
        self._device_nav.name = 'Device_Nav_Component'

    def _setup_modes(self):
        self._fader_button_modes = FaderButtonModeSelector(
            self._mixer_for_faders, tuple(self._fader_buttons))
        self._fader_button_modes.name = 'Fader_Button_Modes'
        self._fader_button_modes.set_mode_toggle(self._fader_group_mode_button)
        self._fader_modes = FaderModeSelector(self._mixer_for_faders,
                                              self._device_for_faders,
                                              tuple(self._faders),
                                              self._fader_button_modes,
                                              self._master_fader_button)
        self._fader_modes.name = 'Fader_Modes'
        self._fader_modes.set_mode_buttons(
            (self._fader_group_mix_button, self._fader_group_fx_button))
        self._encoder_modes = EncoderModeSelector(self._mixer_for_encoders,
                                                  self._device_for_encoders,
                                                  tuple(self._encoders))
        self._encoder_modes.name = 'Encoder_Modes'
        self._encoder_modes.set_mode_buttons(
            (self._encoder_group_mix_button, self._encoder_group_fx_button))
        main_modes = MainModeSelector(self._device_for_encoders,
                                      self._device_for_faders, self._session,
                                      self._mixer_for_faders, self._device_nav,
                                      self._up_button, self._down_button,
                                      self._left_button, self._right_button,
                                      self._select_button)
        main_modes.name = 'Main_Modes'
        main_modes.set_mode_buttons(
            (self._main_group_track_button, self._main_group_fx_button))

    def _setup_master_fader(self):
        if self._has_faders:
            self._mixer_for_encoders.master_strip().set_volume_control(
                self._master_fader)
        else:
            self._mixer_for_encoders.selected_strip().set_volume_control(
                self._master_fader)

    def _setup_single_fader_button_modes(self):
        self._single_fader_button_modes = SingleFaderButtonModeSelector(
            self._mixer_for_encoders, self._fader_group_midi_button)
        self._single_fader_button_modes.name = 'Single_Fader_Button_Modes'
        self._single_fader_button_modes.set_mode_toggle(
            self._fader_group_mode_button)

    def _complete_setup(self):
        self._setup_drum_pads()
        self._set_drum_pads_to_hc()
        self._setup_master_fader()
        if not self._has_faders:
            self._setup_single_fader_button_modes()
        for control in self.controls:
            if isinstance(control, InputControlElement):
                control.clear_send_cache()

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

        self._fader_group_midi_button.send_value(LED_OFF, True)
        self._encoder_group_midi_button.send_value(LED_OFF, True)
        self._main_group_hyper_button.send_value(AMB_FULL, True)
        self.request_rebuild_midi_map()
        self._on_selected_track_changed()
        self.schedule_message(1, self._show_startup_message)

    def _show_startup_message(self):
        self._send_midi(SYSEX_START + CLEAR_ALL)
        self._name_display.display_message('Ableton Live')
        self._display_reset_delay = INITIAL_DISPLAY_DELAY

    def _select_button_value(self, value):
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _identify_value(self, value):
        for encoder in self._encoders:
            encoder.set_identify_mode(value > 0)

        for fader in self._faders:
            fader.set_identify_mode(value > 0)

        self._master_fader.set_identify_mode(value > 0)
        self._display_reset_delay = 0
        self._identify_button.turn_on(
        ) if value > 0 else self._identify_button.turn_off()

    def _midi_button_value(self, value, sender):
        if value > 0:
            if sender is self._drum_group_midi_button:
                hc_byte = self._hc_byte ^ PADS
                if hc_byte != self._hc_byte:
                    self._hc_byte = hc_byte
                    self._drum_group_hyper_button.send_value(LED_OFF, True)
                    self.schedule_message(
                        1, self._send_midi,
                        SYSEX_START + (32, self._hc_byte, 247))
            elif sender is self._encoder_group_midi_button:
                hc_byte = self._hc_byte ^ ENCODERS
                if hc_byte != self._hc_byte:
                    self._hc_byte = hc_byte
                    self._encoder_group_mix_button.send_value(LED_OFF, True)
                    self._encoder_group_fx_button.send_value(LED_OFF, True)
                    if self._encoder_modes.mode_index < 3:
                        self._encoder_modes.set_enabled(False)
                    self.schedule_message(
                        1, self._send_midi,
                        SYSEX_START + (32, self._hc_byte, 247))
            elif sender is self._fader_group_midi_button:
                if self._has_faders:
                    hc_byte = self._hc_byte ^ FADERS
                    if hc_byte != self._hc_byte:
                        self._hc_byte = hc_byte
                        self._fader_group_mix_button.send_value(LED_OFF, True)
                        self._fader_group_fx_button.send_value(LED_OFF, True)
                        self._fader_group_mode_button.send_value(LED_OFF, True)
                        if self._fader_modes.mode_index < 2:
                            self._fader_modes.set_enabled(False)
                            self._fader_button_modes.set_enabled(False)
                        self.schedule_message(
                            1, self._send_midi,
                            SYSEX_START + (32, self._hc_byte, 247))
                else:
                    self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _hyper_button_value(self, value, sender):
        if value > 0:
            if sender is self._drum_group_hyper_button:
                if self._hc_byte | PADS != self._hc_byte:
                    self._hc_byte = self._hc_byte | PADS
                    self._send_midi(SYSEX_START + (32, self._hc_byte, 247))
                    self.schedule_message(1, self._set_drum_pads_to_hc)
            elif sender is self._encoder_group_fx_button or sender is self._encoder_group_mix_button:
                if self._hc_byte | ENCODERS != self._hc_byte:
                    self._hc_byte = self._hc_byte | ENCODERS
                    self._send_midi(SYSEX_START + (32, self._hc_byte, 247))
                    self._encoder_group_midi_button.turn_off()
                    if sender is self._encoder_group_fx_button:
                        self._encoder_modes.set_enabled(True)
                        self._display_reset_delay = 0
                        return
                    else:
                        self.schedule_message(1,
                                              self._encoder_modes.set_enabled,
                                              True)
                        self.schedule_message(1, self._encoder_modes.update)
                        self._display_reset_delay = 2
                        return
            elif sender is self._fader_group_fx_button or sender is self._fader_group_mix_button:
                if self._hc_byte | FADERS != self._hc_byte:
                    self._hc_byte = self._hc_byte | FADERS
                    self._send_midi(SYSEX_START + (32, self._hc_byte, 247))
                    self._fader_group_midi_button.turn_off()
                    self._fader_button_modes.set_enabled(True)
                    if sender is self._fader_group_fx_button:
                        self._fader_modes.set_enabled(True)
                        self._fader_button_modes.set_enabled(True)
                        self._display_reset_delay = 0
                        return
                    else:
                        self.schedule_message(1, self._fader_modes.set_enabled,
                                              True)
                        self.schedule_message(1, self._fader_modes.update)
                        self.schedule_message(
                            1, self._fader_button_modes.set_enabled, True)
                        self.schedule_message(1,
                                              self._fader_button_modes.update)
                        self._display_reset_delay = 2
                        return
            self._display_reset_delay = 0

    def _set_drum_pads_to_hc(self):
        self._drum_group_midi_button.send_value(LED_OFF, True)
        self._drum_group_hyper_button.send_value(RED_FULL, True)
        for index in range(len(self._drum_pads)):
            self._drum_pads[index].send_value(RED_LOW, True)

    def _fader_button_value(self, value, sender):
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _fader_value(self, value, sender):
        param = sender.mapped_parameter()
        if param != None:
            param_range = param.max - param.min
            if param.name == 'Track Volume':
                if sender == self._master_fader:
                    if self._has_faders:
                        name_string = 'Master  Vol'
                    else:
                        name_string = self._mixer_for_faders.selected_strip(
                        ).track_name_data_source().display_string() + '   Vol'
                else:
                    name_string = self._mixer_for_faders.channel_strip(
                        self._faders.index(sender)).track_name_data_source(
                        ).display_string() + '   Vol'
            else:
                name_string = param.name
                value = int((param.value - param.min) / param_range * 127)
            value_string = str(value)
        else:
            name_string = '<unmapped>'
            value_string = None
            self.schedule_message(1, self._set_value_string)
        self._set_name_string(name_string)
        self._set_value_string(value_string)
        return

    def _encoder_value(self, value, sender):
        param = sender.mapped_parameter()
        if param != None:
            param_range = param.max - param.min
            if param.name == 'Track Volume':
                name_string = self._mixer_for_encoders.channel_strip(
                    self._encoders.index(sender)).track_name_data_source(
                    ).display_string() + '   Vol'
                value = int((param.value - param.min) / param_range * 127)
            elif param.name == 'Track Panning':
                name_string = self._mixer_for_encoders.channel_strip(
                    self._encoders.index(sender)).track_name_data_source(
                    ).display_string() + '   Pan'
                value = int(param.value / param_range * 127)
                if value < 0:
                    name_string += '  L'
                elif value > 0:
                    name_string += '  R'
                else:
                    name_string += '  C'
            else:
                name_string = param.name
                value = int((param.value - param.min) / param_range * 127)
            value_string = str(value)
        else:
            name_string = '<unmapped>'
            value_string = None
            self.schedule_message(1, self._set_value_string)
        self._set_name_string(name_string)
        self._set_value_string(value_string)
        return

    def _set_displays_to_default(self):
        self._name_display.segment(0).set_data_source(
            self._mixer_for_encoders.selected_strip().track_name_data_source())
        self._name_display.update()
        self._update_bank_value()
        self._set_value_string(None)
        self._send_midi(SYSEX_START + LCD_HC_DEFAULT)
        return

    def _set_name_string(self, name_string):
        self._name_display.segment(0).set_data_source(
            self._name_display_data_source)
        self._name_display_data_source.set_display_string(name_string)
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _set_value_string(self, value_string=None):
        if value_string != None:
            self._value_display_data_source.set_display_string(value_string)
        else:
            self._value_display.reset()
        return

    def _set_bank_string(self, bank_string=None):
        if bank_string != None:
            self._bank_display_data_source.set_display_string(bank_string)
        else:
            self._bank_display.reset()
        return

    def _update_bank_value(self):
        bank = (self._session.track_offset() + 1) / self._session.width() + 1
        self._set_bank_string(str(bank))

    def _install_mapping(self, midi_map_handle, control, parameter,
                         feedback_delay, feedback_map):
        if not self._in_build_midi_map:
            raise AssertionError
            raise midi_map_handle != None or AssertionError
            raise control != None and parameter != None or AssertionError
            raise isinstance(
                parameter,
                Live.DeviceParameter.DeviceParameter) or AssertionError
            raise isinstance(control, InputControlElement) or AssertionError
            raise isinstance(feedback_delay, int) or AssertionError
            if not isinstance(feedback_map, tuple):
                raise AssertionError
                success = False
                feedback_rule = None
                feedback_rule = control.message_type(
                ) is MIDI_NOTE_TYPE and Live.MidiMap.NoteFeedbackRule()
                feedback_rule.note_no = 0
                feedback_rule.vel_map = (0, )
            elif control.message_type() is MIDI_CC_TYPE:
                feedback_rule = Live.MidiMap.CCFeedbackRule()
                feedback_rule.cc_no = 0
                feedback_rule.cc_value_map = (0, )
            elif control.message_type() is MIDI_PB_TYPE:
                feedback_rule = Live.MidiMap.PitchBendFeedbackRule()
                feedback_rule.value_pair_map = feedback_map
            raise feedback_rule != None or AssertionError
            feedback_rule.channel = control.message_channel()
            feedback_rule.delay_in_ms = feedback_delay
            success = control.message_type(
            ) is MIDI_NOTE_TYPE and Live.MidiMap.map_midi_note_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(),
                control.message_identifier(), feedback_rule)
        elif control.message_type() is MIDI_CC_TYPE:
            success = Live.MidiMap.map_midi_cc_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(),
                control.message_identifier(), control.message_map_mode(),
                feedback_rule, not control.needs_takeover())
        elif control.message_type() is MIDI_PB_TYPE:
            success = Live.MidiMap.map_midi_pitchbend_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(),
                feedback_rule, not control.needs_takeover())
        return success
Пример #46
0
class BlockMod(MonOhm):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid Block "


	def __init__(self, *a, **k):
		self._shift_button = None
		super(BlockMod, self).__init__(*a, **k)
		self._host_name = 'BlockMod'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self._rgb = 1
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._mem = [4, 8, 12, 16]
		self.modhandler._color_type = 'Monochrome'
	

	"""script initialization methods"""
	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(8)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(2):
			self._fader[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, SLIDER_CC[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
		#for index in range(8):
		#	self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(8):
			self._dial[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, KNOB_CC[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index + 8, self)
		for index in range(4):
			self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, FUNCTION_NOTES[index], 'Menu_' + str(index), self)	
		#self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._livid = DoublePressElement(MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self))
		self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Shift_Button_Left', self)
		self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Shift_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))
		self._dummy_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 125)
		self._dummy_button.name = 'Dummy1'
		self._dummy_button2 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 126)
		self._dummy_button2.name = 'Dummy2'
		self._dummy_button3 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 127)
		self._dummy_button2.name = 'Dummy3'
		self._dial_matrix = ButtonMatrixElement()
		self._dial_matrix.add_row(self._dial)
	

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

	def _setup_crossfader(self):
		pass
	

	def _setup_mod(self):
		super(BlockMod, self)._setup_mod()
		self.modhandler.nav_box.on_value = 8
	

	def _setup_layers(self):
		self._device_navigator.layer = Layer(priority = 5, prev_button = self._menu[2], next_button = self._menu[3])
		self._device.mod_layer = AddLayerMode(self._device, Layer(priority = 5, bank_prev_button = self._menu[0], bank_next_button = self._menu[1]))
		self._transport.mod_layer = AddLayerMode(self._transport, Layer(priority = 5, play_button = self._menu[2], stop_button = self._menu[3]))
		self.modhandler.set_mod_button(self._livid)
		self.modhandler.layer = Layer(priority = 5, 
									grid = self._monomod,
									nav_up_button = self._menu[0],
									nav_down_button = self._menu[1],
									nav_left_button = self._menu[2],
									nav_right_button =  self._menu[3],
									shift_button = self._shift_r,
									alt_button = self._shift_l,
									parameter_controls = self._dial_matrix)
		self.modhandler.legacy_shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6,
									channel_buttons = self._monomod.submatrix[:, 1:2],
									nav_matrix = self._monomod.submatrix[:4, 2:6]))
		self.modhandler.shift_mode = AddLayerMode(self.modhandler, Layer(priority = 6, 
									lock_button = self._livid,
									device_selector_matrix = self._monomod.submatrix[:, :1],
									key_buttons = self._monomod.submatrix[:, 7:8]))
		self.modhandler.shiftlock_mode = AddLayerMode(self.modhandler, Layer(priority = 6, 
									key_buttons = self._monomod.submatrix[:, 7:8]))
	

	def _setup_modes(self):
		self._monomod_mode = MonomodModeComponent(self, self.monomod_mode_update)
		self._monomod_mode.name = 'Monomod_Mode'
		self._monomod_mode.layer = Layer(priority = 5, mode_toggle = self._livid)
		self._monomod_mode.set_enabled(True)
		self._on_shift_doublepress_value.subject = self._livid.double_press
		self._shift_mode = BlockModShiftModeComponent(self, self.shift_update) 
		self._shift_mode.name = 'Shift_Mode'
		#self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
		self._shift_mode.layer = Layer(priority = 3, toggle1 = self._shift_l, toggle2 = self._shift_r)
		self._shift_mode.set_enabled(True)
		self._l_function_mode = FunctionModeComponent(self, self.l_function_update)
		self._l_function_mode.name = 'Left_Function_Mode'
		self._r_function_mode = FunctionModeComponent(self, self.r_function_update)
		self._r_function_mode.name = 'Right_Function_Mode'
		self._m_function_mode = FunctionModeComponent(self, self.m_function_update)
		self._m_function_mode.name = 'Main_Function_Mode'
		self._function_modes = [self._l_function_mode, self._r_function_mode, self._m_function_mode]
	

	@subject_slot('value')
	def _on_shift_doublepress_value(self, value):
		#self._monomod_mode.set_mode(abs(self._monomod_mode._mode_index -1))
		pass
	

	"""shift/zoom methods"""
	def deassign_matrix(self):
		self._session_zoom.set_button_matrix(None)
		self._session_zoom2.set_button_matrix(None)
		#self._session.set_stop_track_clip_buttons(None)
		#self._session2.set_stop_track_clip_buttons(None)
		self._session_zoom_main.set_button_matrix(None)
		#self._session_main.set_stop_track_clip_buttons(None)
		for column in range(4):
			self._mixer2.channel_strip(column).set_select_button(None)
			self._mixer2.return_strip(column).set_mute_button(None)
			self._mixer2.return_strip(column).set_solo_button(None)
			self._mixer2.return_strip(column).set_arm_button(None)
			self._mixer2.return_strip(column).set_crossfade_toggle(None)
			self._mixer2.return_strip(column).set_select_button(None)			#shouldn't this be somewhere else?
			self._mixer2.channel_strip(column).set_crossfade_toggle(None)
			self._mixer2.channel_strip(column).set_mute_button(None)
			self._mixer2.channel_strip(column).set_solo_button(None)
			self._mixer2.channel_strip(column).set_arm_button(None)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(None)
				self._scene2[row].clip_slot(column).set_launch_button(None)
		for index in range(5):
			self._scene[index].set_launch_button(None)
			self._scene2[index].set_launch_button(None)
			self._scene_main[index].set_launch_button(None)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session_zoom2.set_nav_buttons(None, None, None, None)
		self._session_zoom_main.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		self._session2.set_track_bank_buttons(None, None)
		self._session2.set_scene_bank_buttons(None, None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
		for column in range(8):
			self._mixer.channel_strip(column).set_select_button(None)
			self._mixer.channel_strip(column).set_crossfade_toggle(None)
			self._mixer.channel_strip(column).set_mute_button(None)
			self._mixer.channel_strip(column).set_solo_button(None)
			self._mixer.channel_strip(column).set_arm_button(None)
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(None)
			for row in range(8):
				self._grid[column][row].set_channel(0)
				self._grid[column][row].release_parameter()
				self._grid[column][row].use_default_message()
				self._grid[column][row].set_enabled(True)
				self._grid[column][row].set_on_off_values(127, 0)
				self._grid[column][row].send_value(0, True)
		#self._send_reset.set_buttons(tuple(None for index in range(4)))
	

	def zoom_off(self):
		for column in range(4):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
			if(self._r_function_mode._mode_index in range(0,3)):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.channel_strip(column).set_mute_button(self._grid[column + 4][5])
				self._grid[column + 4][6].set_on_value(ARM[self._rgb])
				self._mixer2.channel_strip(column).set_arm_button(self._grid[column + 4][6])
				for row in range(5):
					self._scene2[row].clip_slot(column).set_launch_button(self._grid[column + 4][row])
			elif(self._r_function_mode._mode_index is 3):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.return_strip(column).set_mute_button(self._grid[column + 4][5])
				for row in range(5):
					self._grid[column + 4][row].send_value(USER1_COLOR[self._rgb], True)
					self._grid[column + 4][row].set_channel(RIGHT_USER1_CHANNEL)
					self._grid[column + 4][row].set_identifier(RIGHT_USER1_MAP[column][row])
					self._grid[column + 4][row].set_enabled(False)	 #this has to happen for translate to work
				#self._session_zoom2.set_ignore_buttons(True)
		if(self._r_function_mode._mode_index is 0):
			for index in range(4):
				self._grid[index + 4][7].send_value(SEND_RESET[self._rgb], True)
			#self._send_reset.set_buttons(tuple(self._grid[index + 4][7] for index in range(4)))
	

	def zoom_off_m(self):
		self.deassign_dials()
		for column in range(8):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(self._grid[column][row])
		#self._session_zoom.set_button_matrix(self._matrix)
	

	def zoom_left(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
			self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons2.append(self._grid[index + 4][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene[index].set_launch_button(self._grid[7][index])
		#self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session.set_stop_track_clip_buttons(self._matrix.submatrix[:4][7:])
		#self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		#self._session2.set_stop_track_clip_buttons(self._matrix.submatrix[4:8][7:])
		self._session_zoom.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		#self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.set_matrix(self._monomod.submatrix[4:8][7:])
		self._device_selector.set_offset(4)
	

	def zoom_right(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene2[index].set_launch_button(self._grid[7][index])
		#self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session.set_stop_track_clip_buttons(self._matrix.submatrix[:4][7:])
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
				track_stop_buttons2.append(self._grid[index + 4][6])
			#self._session2.set_stop_track_clip_buttons(self._matrix.submatrix[4:8][7:])
			#self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		self._session_zoom2.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		#self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.set_matrix(self._monomod.submatrix[:4][7:])
		self._device_selector.set_offset(0)
	

	def zoom_main(self):
		track_stop_buttons = []
		for index in range(8):
			self._grid[index][6].set_on_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_on_value(SCENE_LAUNCH[self._rgb])
			self._scene_main[index].set_launch_button(self._grid[7][index])
		#self._session_main.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		#self._session_main.set_stop_track_clip_buttons(self._matrix[0:8][7:])
		self._session_zoom_main.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		#self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.set_matrix(self._monomod.submatrix[4:8][7:])
		self._device_selector.set_offset(4)
	


	"""function mode callbacks"""
	def l_function_update(self):
		mode = self._l_function_mode._mode_index
		if(self._l_function_mode.is_enabled() is False):
			self._l_function_mode.set_mode_buttons(None)
		if not self.modhandler.is_enabled():
			if(self._l_function_mode.is_enabled() is True):
				if(len(self._l_function_mode._modes_buttons) is 0):
					for index in range(4):
						self._mixer.channel_strip(index).set_select_button(None)
					buttons = []
					for index in range(4):
						buttons.append(self._grid[index][7]) 
					self._l_function_mode.set_mode_buttons(tuple(buttons))
				if(self._shift_mode._mode_index is 2):
					for index in range(4):
						if(mode != index):
							self._grid[index][7].turn_off()
						else:
							self._grid[index][7].turn_on()
			if(mode is 0):
				self.assign_device_dials()
				self.show_message('Mixer Split:Dials Device Mode')
			elif(mode is 1):
				self.assign_send_dials()
				self.show_message('Mixer Split:Dials Send Mode')
			elif(mode is 2):
				self.assign_split_volume_dials()
				self.show_message('Mixer Split:Dials Volume Mode')
			elif(mode is 3):
				self.assign_user_dials()
				self.show_message('Mixer Split:Dials User Map Mode')
	

	def r_function_update(self):
		mode = self._r_function_mode._mode_index
		if(self._r_function_mode.is_enabled() is False):
			self._r_function_mode.set_mode_buttons(None)
			#self._session2.set_show_highlight(False)
			#self._session._highlighting_callback(self._session._track_offset, self._session._scene_offset, 4, 5, 1)
		if not self.modhandler.is_enabled():
			if(self._r_function_mode.is_enabled() is True):
				if(len(self._r_function_mode._modes_buttons) is 0):
					for index in range(4):
						self._mixer2.channel_strip(index).set_select_button(None)
					buttons = []
					for index in range(4):
						buttons.append(self._grid[index + 4][7]) 
					self._r_function_mode.set_mode_buttons(tuple(buttons))
				if(self._shift_mode._mode_index is 3):
					for index in range(4):
						if(mode != index):
							self._grid[index + 4][7].turn_off()
						else:
							self._grid[index + 4][7].turn_on()
			self._session2.set_offsets(int(self._mem[mode]), self._session2._scene_offset)
			self.show_message('Mixer Split: Track Offset' + str(RIGHT_MODE_OFFSETS[mode]))
	

	def m_function_update(self):
		mode = self._m_function_mode._mode_index
		if(self._m_function_mode.is_enabled() is False):
			self._m_function_mode.set_mode_buttons(None)
			#self._session.set_show_highlight(False)
			#self._session2.set_show_highlight(False)
			#self._session_main._highlighting_callback(self._session_main._track_offset, self._session_main._scene_offset, 8, 5, 1)
		if not self.modhandler.is_enabled():
			if(self._m_function_mode.is_enabled() is True):
				if(len(self._m_function_mode._modes_buttons) is 0):
					for index in range(8):
						self._mixer.channel_strip(index).set_select_button(None)
					buttons = []
					for index in range(4):
						buttons.append(self._grid[index][7]) 
					self._m_function_mode.set_mode_buttons(tuple(buttons))
				if(self._shift_mode._mode_index is 4):
					for index in range(4):
						if(mode != index):
							self._grid[index][7].turn_off()
						else:
							self._grid[index][7].turn_on()
			if(mode is 0):
				self.assign_device_dials()
				self.show_message('Mixer Linked:Dials Device Mode')
			elif(mode is 1):
				self.assign_send_dials()
				self.show_message('Mixer Linked:Dials Send Mode')
			elif(mode is 2):
				self.assign_volume_dials()
				self.show_message('Mixer Linked:Dials Volume Mode')
			elif(mode is 3):
				self.assign_user_dials()
				self.show_message('Mixer Linked:Dials User Map Mode')
	

	def shift_update(self):
		self._clutch_device_selection = True
		#self.allow_updates(False)
		#if(not self._in_build_midi_map):
		#	self.set_suppress_rebuild_requests(True)
		self.deassign_channel_select_buttons()
		self.deassign_matrix()
		self.deassign_menu()
		if(self._monomod_mode._mode_index is 0):		#if monomod is not on
			if(self._shift_mode._mode_index is 0):							#if no shift is pressed
				#self._shift_mode._mode_toggle1.turn_off()
				#self._shift_mode._mode_toggle2.turn_off()
				if(self.split_mixer() is False):
					self.set_split_mixer(True)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_channel_select_buttons()
				#self._recalculate_selected_channel()
				#self.assign_transport_to_menu()
				self.assign_session_nav_to_menu()
				self.l_function_update()
				self.r_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session)
				self._session._do_show_highlight()	
				#self._session.set_show_highlight(True)
			elif(self._shift_mode._mode_index is 1):						#if no shift is pressed, but mixer is linked
				#self._shift_mode._mode_toggle1.turn_on()
				#self._shift_mode._mode_toggle2.turn_on()
				if(self.split_mixer() is True):
					self.set_split_mixer(False)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off_m()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_main_channel_select_buttons()
				self.assign_session_main_nav_to_menu()
				self.m_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session_main)
				self._session_main._do_show_highlight()
			elif(self._shift_mode._mode_index > 1):						#if a shift is pressed
				self.assign_device_nav_to_menu()
				self.deassign_channel_select_buttons()
				if(self._shift_mode._mode_index is 2):					#if shift left
					#self._shift_mode._mode_toggle1.turn_on()
					self.zoom_left()
					self._session_zoom._on_zoom_value(1)
					self._session.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._l_function_mode.set_enabled(True)
					self.set_highlighting_session_component(self._session)
					self._session._do_show_highlight()
				elif(self._shift_mode._mode_index is 3):				#if shift right
					#self._shift_mode._mode_toggle2.turn_on()
					self.zoom_right()
					self._session_zoom2._on_zoom_value(1)
					self._session2.set_enabled(True)  #this is a workaround so that the stop buttons still function
					self._r_function_mode.set_enabled(True)
					self.assign_master_fader()
					if(self._r_function_mode._mode_index < 4):
						self.set_highlighting_session_component(self._session2)
						self._session2._do_show_highlight()
				elif(self._shift_mode._mode_index is 4):				#if either shift pressed while mixer is linked
					#self._shift_mode._mode_toggle1.turn_on()
					#self._shift_mode._mode_toggle2.turn_on()
					self.zoom_main()
					self._session_zoom_main._on_zoom_value(1)
					self._session_main.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._m_function_mode.set_enabled(True)
					self.assign_master_fader()
					self.set_highlighting_session_component(self._session_main)
					self._session_main._do_show_highlight()
				self._device_selector.set_enabled(True)
		else:
			for mode in self._function_modes:
				mode.set_enabled(False)
			#self.modhandler._shift_value(int(self._shift_mode._mode_index>1))
		self.allow_updates(True)
		#self.set_suppress_rebuild_requests(False)
		self._clutch_device_selection = False
		if(self._shift_mode._mode_index < 2):
			self._monobridge._send('touch', 'off')
		else:
			self._monobridge._send('touch', 'on')
	

	"""left control management methods"""
	def deassign_dials(self):
		for index in range(8):
			self._dial[index].use_default_message()
			self._dial[index].release_parameter()
			self._dial[index].set_enabled(True)
		if(self._device._parameter_controls != None):
			for control in self._device._parameter_controls:
				control.release_parameter()
			self._device._parameter_controls = None
		self._mixer.selected_strip().set_send_controls(None)
		self._mixer.selected_strip().set_volume_control(None)
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(None)
			self._mixer.channel_strip(track+4).set_volume_control(None)
			self._mixer2.channel_strip(track).set_volume_control(None)
			self._mixer2.return_strip(track).set_volume_control(None)
	

	def assign_device_dials(self):
		self._ohm_type = OHM_TYPE[0]
		self._ohm = OHM_VALUE[0]
		self.deassign_dials()
		self._device.set_enabled(True)
		device_param_controls = []
		for index in range(8):
			device_param_controls.append(self._dial[index])
		self._device.set_parameter_controls(tuple(device_param_controls))
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_send_dials(self):
		self._ohm_type = OHM_TYPE[1]
		self._ohm = OHM_VALUE[1]
		self.deassign_dials()
		dials = []
		for index in range(4):
			dials.append(self._dial[index])
		for index in range(4):
			if(self._mixer2.return_strip(index)):
				self._mixer2.return_strip(index).set_volume_control(self._dial[index + 4])
		self._mixer.selected_strip().set_send_controls(tuple(dials))
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(8):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_split_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
			self._mixer2.channel_strip(track).set_volume_control(self._dial[track+4])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_user_dials(self):
		self._ohm_type = OHM_TYPE[3]
		self._ohm = OHM_VALUE[3]
		self.deassign_dials()
		for index in range(8):
			self._dial[index].set_channel(L_USER_DIAL_CHAN)
			self._dial[index].set_identifier(L_USER_DIAL_MAP[index])
			self._dial[index].set_enabled(False)
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	


	"""menu button management methods"""
	def deassign_menu(self):
		self._device.set_lock_button(None)
		self._device.set_on_off_button(None)
		#self._device_navigator.set_device_nav_buttons(None, None)	
		self._device_navigator.set_enabled(False)
		self._device.set_bank_nav_buttons(None, None)
		self._transport.set_play_button(None)	
		self._transport.set_record_button(None) 
		self._transport.set_stop_button(None)
		self._transport.set_loop_button(None)	
		self._transport.set_overdub_button(None)	
		self._session.set_stop_all_clips_button(None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
	

	def assign_device_nav_to_menu(self):
		#self._device_navigator.set_device_nav_buttons(self._menu[2], self._menu[3]) 
		self._device_navigator.set_enabled(True)
		self._device.set_bank_nav_buttons(self._menu[0], self._menu[1])
	

	def assign_transport_to_menu(self):
		self._transport.set_play_button(self._menu[0])	
		self._transport.set_record_button(self._menu[2])
		self._transport.set_stop_button(self._menu[1])
		session.set_stop_all_clips_button(self._menu[3])
	

	def assign_session_nav_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_monomod_shift_to_menu(self):
		#self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[2])
		self._device_navigator.set_enabled(True)
		self._device.set_bank_nav_buttons(self._menu[1], self._menu[0])
	

	def assign_session_bank_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session2_bank_to_menu(self):
		self._session2.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session2.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session_main_nav_to_menu(self):
		self._session_main.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session_main.set_scene_bank_buttons(self._menu[1], self._menu[0])
	


	"""channel selection management methods"""
	def deassign_channel_select_buttons(self):
		for index in range(8):
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(None)
			self._grid[index][7].release_parameter()
		for index in range(4):
			self._mixer2.channel_strip(index).set_select_button(None)
			self._mixer2.return_strip(index).set_select_button(None)
			self._mixer2.master_strip().set_select_button(None)
			self._grid[index + 4][7].release_parameter()
	

	def assign_channel_select_buttons(self):
		for index in range(4):
			#if(self._mixer.channel_strip(index)):
			self._grid[index][7].set_on_off_values(127, 0)
			self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index][7].set_on_off_values(127, 0)
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])	
		else:
			for index in range(4):
				self._grid[index][7].set_on_off_values(1, 0)
				self._mixer2.return_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_return_select_buttons(self):
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0) 
			if(self._mixer.channel_strip(index)):
				self._grid[index + 4][7].set_on_value(1)
				self._mixer.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_l_channel_select_buttons(self):
		self._mixer.set_select_buttons(None, None)
		self._session.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_r_channel_select_buttons(self):
		self._mixer2.set_select_buttons(None, None)
		self._session2.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0)
			if(self._mixer2.channel_strip(index)):
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_main_channel_select_buttons(self):
		for index in range(8):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._grid[index][7].set_on_value(127)
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_master_fader(self):
		self._mixer.set_crossfader_control(None)
		self._mixer.master_strip().set_volume_control(self._fader[1])
	

	def assign_crossfader(self):
		self._mixer.master_strip().set_volume_control(None)
		self._mixer.set_crossfader_control(self._fader[1])
	


	"""called on timer"""
	def update_display(self):
		super(BlockMod, self).update_display()
		if(self._timer == 0):
			self._shift_pressed_timer = -12
	

	def strobe(self):
		if(self._ohm_type != 'static'):
			if(self._ohm_type is 'pulse'):
				self._ohm = int(math.fabs(((self._timer * 8) % 64) -32) +32)
			if(self._ohm_type is 'up'):
				self._ohm = int(((self._timer * 4) % 64) + 16)
			if(self._ohm_type is 'down'):
				self._ohm = int(math.fabs(int(((self._timer * 4) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))	
	

	def handle_sysex(self, midi_bytes):
		pass
	

	def _on_session_offset_changes(self):
		if self._r_function_mode._mode_index in range(0,4):
			self._mem[int(self._r_function_mode._mode_index)] = self._session2.track_offset()
	



#	a
Пример #47
0
class OhmModesHH(ControlSurface):
	__module__ = __name__
	__doc__ = " OhmModes controller script, custom script for Herbie Hancock by amounra "


	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		with self.component_guard():
			self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= OhmModesHH2 log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
			#self.set_suppress_rebuild_requests(True) # Turn off rebuild MIDI map until after we're done setting up
			self.revision = 'HH'
			self.flash_status = 1
			self._backlight = 127
			self._backlight_type = 'static'
			self._ohm = 127
			self._ohm_type = 'static'
			self._pad_translations = PAD_TRANSLATION
			self._rgb = 1
			self._keys_octave = 5
			self._keys_scale = 0
			self._tempo_buttons = None
			self._scene_indexes = [[[0,0],  [8, 0], [16, 0], [24, 0], [32, 0],  [40, 0]], 
									[[0,0],  [8, 0], [16, 0], [24, 0], [32, 0],  [40, 0]], 
									[[0,0],  [8, 0], [16, 0], [24, 0], [32, 0],  [40, 0]], 
									[[0,0],  [8, 0], [16, 0], [24, 0], [32, 0],  [40, 0]], 
									[[0,0],  [8, 0], [16, 0], [24, 0], [32, 0],  [40, 0]]]
			self._scene_bank = 0
			self._bank_is_on = False
			self._setup_monobridge()
			self._setup_controls()
			self._setup_transport_control() # Run the transport setup part of the script
			self._setup_mixer_control() # Setup the mixer object
			self._setup_session_control()  # Setup the session object 
			self._setup_device_control() # Setup the device object
			self._setup_crossfader()
			self._setup_looper()
			#self._setup_scene_selector()
			#self._setup_modes() 
			self._assign_page_constants()
			self.assign_page_0()
			self._setup_hilight_knobs()
			self._last_device = None
			self._timer = 0
			#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._on_selected_scene_changed()
			self.show_message('OhmModes Control Surface Loaded')
			self._send_midi(tuple(switchxfader))
			#self.schedule_message(10, self.query_ohm, None)
			#self.song().view.selected_scene = self.song().scenes[0]
			self._assign_session_colors()
		
	def query_ohm(self):
		#self.log_message('querying Ohm')
		self._send_midi(tuple(check_model))

	

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



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

	def get_device_bank(self):
		return self._device._bank_index
	

	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(16)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(8):
			self._fader[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_FADERS[index], Live.MidiMap.MapMode.absolute)
			self._fader[index].name = 'Fader_' + str(index), self
		for index in range(8):
			self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(16):
			self._dial[index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, OHM_DIALS[index], Live.MidiMap.MapMode.absolute)
			self._dial[index].name = 'Dial_' + str(index)
		for index in range(6):
			self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_MENU[index], 'Menu_' + str(index), self)	
		self._crossfader = EncoderElement(MIDI_CC_TYPE, CHANNEL, CROSSFADER, Live.MidiMap.MapMode.absolute)
		self._crossfader.name = "Crossfader"
		self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Page_Button_Left', self)
		self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Page_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(6):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
	
		
	def _setup_modes(self):
		self._shift_mode = ShiftModeComponent(self) 
		self._shift_mode.name = 'Shift_Mode'
		#self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
		#self._select_mode = ModeSelectorComponent(self)
		#self._select_mode.name = 'Select_Mode'
		#self._select_mode.set_mode_toggle(self._menu[5])
		#self._select_mode.update = self.select_mode_update(self._select_mode)
		#self._menu[5].add_value_listener(self._select_mode)
		#self._scale_mode = ScaleModeComponent(self)
		#self._scale_mode.name = "Scale_Mode"
		#self._octave_mode = OctaveModeComponent(self)
		#self._octave_mode.name = "Octave_Mode"
	

			
		
	

	def select_mode_update(self, mode_selector):
		def update():
			if mode_selector._mode_index>0:
				pass
		return update
		
	

	def _setup_looper(self):
		self._looper = [None for index in range(2)]
		for index in range(2):
			self._looper[index] = LooperListenerComponent(self, index + 1)
			self._looper[index].assign_buttons(self._button[index*4], self._button[(index*4)+1], self._button[(index*4)+2], self._button[(index*4)+3])
	

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

	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (7) #A mixer is one-dimensional; 
		global mixer
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])
		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True
		self.song().view.selected_track = mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error


	def _setup_session_control(self):
		is_momentary = True
		num_tracks = 7
		num_scenes = 7  ###changed from 5 for HH 
		global session
		session = SessionComponent(num_tracks, num_scenes)
		session.name = "Session"
		session.set_offsets(0, 0)
		self._session = session		 
		self._scene = [None for index in range(num_scenes)]
		for row in range(num_scenes):
			self._scene[row] = 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)		
		session.set_mixer(mixer)
		self._session_zoom = SessionZoomingComponent(session)	 
		self._session_zoom.name = 'Session_Overview'
		#self._session_zoom.set_enabled(False)
		self.set_highlighting_session_component(self._session)

		
	def _assign_session_colors(self):
		num_tracks = 7
		num_scenes = 7 
		self._session.set_stop_clip_value(STOP_CLIP_COLOR[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_TRIGD_TO_PLAY_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_triggered_to_record_value(CLIP_TRIGD_TO_RECORD_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_stopped_value(CLIP_STOPPED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_started_value(CLIP_STARTED_COLOR[self._rgb])
				self._scene[row].clip_slot(column).set_recording_value(CLIP_RECORDING_COLOR[self._rgb])		
		self._session_zoom.set_stopped_value(ZOOM_STOPPED_COLOR[self._rgb])
		self._session_zoom.set_playing_value(ZOOM_PLAYING_COLOR[self._rgb])
		self._session_zoom.set_selected_value(ZOOM_SELECTED_COLOR[self._rgb])
		

	def _setup_device_control(self):
		self._device = DeviceComponent()
		self._device.name = 'Device_Component'
		self.set_device_component(self._device)
		self._device_navigator = DetailViewControllerComponent()
		self._device_navigator.name = 'Device_Navigator'
		self._device_selection_follows_track_selection = FOLLOW
		
	def device_follows_track(self, val):
		self._device_selection_follows_track_selection = (val == 1)
		return self
		
	def _setup_crossfader(self):
		self._mixer.set_crossfader_control(self._crossfader)
	

	def _setup_scene_selector(self):
		for index in range(5):
			self._menu[index].add_value_listener(self._select_new_scene, True)
	

	def set_bank(self, val):
		self._scene_bank = int(val)
		self._monobridge._send('bank', self._scene_bank)
		self._display_bank()
	

	def _select_mode(self, value):
		self.log_message('select mode update' + str(value))
		self._bank_is_on = value!=0
		if self._bank_is_on is True:
			self._display_bank()
		else:
			self._on_selected_scene_changed()
	

	def _select_new_scene(self, value, sender):
		if self._bank_is_on is False:
			if value > 0:
				new_scene = int(self._scene_indexes[self._scene_bank][self._menu.index(sender)][0])
				new_track = int(self._scene_indexes[self._scene_bank][self._menu.index(sender)][1])
				self.log_message('select new scene ' + str(new_scene) + ' and track ' + str(new_track))
				all_scenes = self.song().scenes
				all_tracks = self.song().tracks
				if (new_scene < len(all_scenes)) and (new_track < len(all_tracks)):
					self.song().view.selected_scene = all_scenes[(new_scene)]
					self.song().view.selected_track = all_tracks[(new_track)]
					self._session.set_offsets(self._scene_indexes[self._scene_bank][self._menu.index(sender)][1], self._scene_indexes[self._scene_bank][self._menu.index(sender)][0])
		else:
			if value > 0:
				self._scene_bank = int(self._menu.index(sender))
				self._monobridge._send('bank', self._scene_bank)
				self._display_bank()
	

	def _display_bank(self):
		if(self._bank_is_on):
			for index in range(5):
				if index == self._scene_bank:
					self._menu[index].send_value(11)
				else:
					self._menu[index].send_value(0)
	



	def _on_selected_scene_changed(self):
		ControlSurface._on_selected_scene_changed(self)
		#self.log_message('scene offset: ' + str(self._session._scene_offset))
		for index in range(6):
			if self._session._scene_offset == self._scene_indexes[self._scene_bank][index][0]:  ## and self._session._scene_offset < self._scene_indexes[index + 1]:
				self._menu[index].turn_on()
			else:
				self._menu[index].turn_off()
		#if self._session._scene_offset >= self._scene_indexes[5]:
		#	self._menu[5].turn_on
		#else:
		#	self._menu[5].turn_off
			
	
	def _setup_hilight_knobs(self):
		self._dial[15].add_value_listener(self._knob_set_scene, True)
		self._dial[14].add_value_listener(self._knob_set_track, True)
	

	def _knob_set_scene(self, value, sender):
		all_scenes = self.song().scenes
		num_scenes = len(all_scenes)
		new_scene = float(value/127.0) * float(num_scenes - 1)
		self.song().view.selected_scene = all_scenes[int(new_scene)]
		self._session.set_offsets(self._session._track_offset, int(new_scene))
	

	def _knob_set_track(self, value, sender):
		#self.log_message(str(value))
		all_tracks = self.song().visible_tracks  #self.song().tracks
		num_tracks = len(self.song().visible_tracks)
		new_track = float(value/127.0) * float(num_tracks - 1)
		#self.log_message(str(int(new_track)))
		#self.log_message(str(value) + str(float(value/127.0)))
		self.song().view.selected_track = all_tracks[int(new_track)]
		self._session.set_offsets(int(new_track), self._session._scene_offset)
	

	def disconnect(self):
		"""clean things up on disconnect"""
		for index in range(5):
			if self._menu[index].value_has_listener(self._select_new_scene):
				self._menu[index].remove_value_listener(self._select_new_scene)
		if self._menu[5].value_has_listener(self._select_mode):
			self._menu[5].remove_value_listener(self._select_mode)
		if self._dial[15].value_has_listener(self._knob_set_scene):
			self._dial[15].remove_value_listener(self._knob_set_scene)
		if self._dial[15].value_has_listener(self._knob_set_scene):		
			self._dial[15].remove_value_listener(self._knob_set_scene)
		self.song().view.remove_selected_track_listener(self._update_selected_device)
		ControlSurface.disconnect(self)
		self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= OhmModes log closed =--------------") #Create entry in log file
		return None

	def _get_num_tracks(self):
		return self.num_tracks

	def flash(self):
		#if(self.flash_status > 0):
		for index in range(6):
			if(self._menu[index]._flash_state>0):
				self._menu[index].flash(self._timer)
		for row in range(8):
			if(self._button[row]._flash_state > 0):
				self._button[row].flash(self._timer)
			for column in range(8):
				button = self._grid[column][row]
				if(button._flash_state > 0):
					button.flash(self._timer)


	def strobe(self):
		if(self._backlight_type != 'static'):
			if(self._backlight_type is 'pulse'):
				self._backlight = int(math.fabs(((self._timer * 16) % 64) -32) +32)
			if(self._backlight_type is 'up'):
				self._backlight = int(((self._timer * 8) % 64) + 16)
			if(self._backlight_type is 'down'):
				self._backlight = int(math.fabs(int(((self._timer * 8) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 27, int(self._backlight)]))
		if(self._ohm_type != 'static'):
			if(self._ohm_type is 'pulse'):
				self._ohm = int(math.fabs(((self._timer * 16) % 64) -32) +32)
			if(self._ohm_type is 'up'):
				self._ohm = int(((self._timer * 8) % 64) + 16)
			if(self._ohm_type is 'down'):
				self._ohm = int(math.fabs(int(((self._timer * 8) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))	

	def deassign_matrix(self):
		#self._scale_mode.set_mode_buttons(None)
		#self._scale_mode.set_enabled(False)
		#self._octave_mode.set_mode_buttons(None)
		#self._octave_mode.set_enabled(False)
		#self._session_zoom.set_button_matrix(None)
		#if self._dial[15].has_value_listener(self._knob_set_scene):
		#	self._dial[15].remove_value_listener(self._knob_set_scene)
		#if self._dial[14].has_value_listener(self._knob_set_track):
		#	self._dial[14].remove_value_listener(self._knob_set_track)
		self._session_zoom.set_enabled(False)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		for column in range(7):
			self._mixer.channel_strip(column).set_crossfade_toggle(None)
			self._mixer.channel_strip(column).set_mute_button(None)
			self._mixer.channel_strip(column).set_solo_button(None)
			self._mixer.channel_strip(column).set_arm_button(None)
			self._mixer.channel_strip(column).set_send_controls(None)
			self._mixer.channel_strip(column).set_pan_control(None)
			self._mixer.track_eq(column).set_enabled(False)
			for row in range(7):
				self._scene[row].clip_slot(column).set_launch_button(None)
		for column in range(8):
			#self._button[column]._on_value = SELECT_COLOR[self._rgb]
			for row in range(8):
				self._grid[column][row].set_channel(0)
				self._grid[column][row].release_parameter()
				self._grid[column][row].use_default_message()
				self._grid[column][row].set_enabled(True)
				self._grid[column][row].send_value(0, True)
				self._grid[column][row]._on_value = 127
				self._grid[column][row]._off_value = 0
		#for index in range(8):
		#	self._button[index].set_channel(0)
		#	self._button[index].use_default_message()
		#	self._button[index].set_enabled(True)
		#	self._button[index].reset()
		#for index in range(6):
		#	self._menu[index]._on_value = 127
		#	self._menu[index]._off_value = 0
		#	self._menu[index].reset()
		#for index in range(16):
		#	self._dial[index].use_default_message()
		#	self._dial[index].release_parameter()
			#self._dial[index].set_enabled(True)
		if(self._device._parameter_controls != None):
			for control in self._device._parameter_controls:
				control.release_parameter()
			self._device._parameter_controls = None
		self._device_navigator.set_enabled(False)
		self._mixer.update()
		self._matrix.reset()

		"""HH Specific"""
		#self._mixer.master_strip().set_select_button(None)
		#for column in range(7):
		#	self._mixer.channel_strip(column).set_select_button(None)
		self._session_zoom.set_zoom_button(None)
		self._transport.set_play_button(None)
		self._transport.set_stop_button(None)
		self._device_navigator.set_device_nav_buttons(None, None)
		
		#for index in range(2):
		#	self._looper[index].find_looper()
		
	def _assign_page_constants(self):
		#self._session_zoom.set_zoom_button(self._button[7]) #commented out pn 070111
		#self._session_zoom.set_zoom_button(self._grid[7][7]) #added pn 070111
		#self._session_zoom.set_button_matrix(self._matrix)
		#self._session_zoom.set_enabled(True)
		#for column in range(7):
			#self._mixer.channel_strip(column).set_select_button(self._button[column])
		#	self._mixer.channel_strip(column).set_volume_control(self._fader[column])
		#self._mixer.master_strip().set_volume_control(self._fader[7])
		#for column in range(8):
		#	self._button[column]._on_value = SELECT_COLOR[self._rgb]
		#self._mixer.master_strip().set_select_button(self._button[7]) #added pn 070111
		#self._mixer.set_prehear_volume_control(self._dial[15])
		#self._transport.set_play_button(self._menu[0])
		#self._menu[0].send_value(PLAY_COLOR[self._rgb], True)	
		#self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		#self._transport.set_stop_button(self._menu[1])
		#self._menu[1]._off_value = STOP_COLOR[self._rgb]
		#self._menu[1]._on_value = STOP_COLOR[self._rgb]
		#self._menu[1].send_value(STOP_COLOR[self._rgb], True)	
		self._livid._on_value = TAP_COLOR[self._rgb]
		self._transport.set_tap_tempo_button(self._livid)
		#self._livid.send_value(TAP_COLOR, True)
		#self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])
		for index in range(2):
			self._menu[index + 4]._on_value = SESSION_NAV[self._rgb]
			self._menu[index * 3]._on_value = SESSION_NAV[self._rgb]
		self._session.set_track_bank_buttons(self._menu[5], self._menu[4])
		self._session.set_scene_bank_buttons(self._menu[3], self._menu[0])


	def assign_page_0(self):
		self._backlight_type = 'static'
		#self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_enabled(True)
		for column in range(7):
			#self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			#self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			#self._grid[column][6]._on_value = SOLO_COLOR[self._rgb]
			#self._mixer.channel_strip(column).set_solo_button(self._grid[column][6])
			#self._grid[column][7]._on_value = ARM_COLOR[self._rgb]
			#self._mixer.channel_strip(column).set_arm_button(self._grid[column][7])
			#self._mixer.channel_strip(column).set_pan_control(self._dial[column + 8])
			for row in range(7):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		#for column in range(4):
		#	self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column], self._dial[column + 4]]))
		track_stop_buttons = []
		for index in range(7):
			self._grid[7][index]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[index].set_launch_button(self._grid[7][index])
			self._grid[index][7]._on_value = TRACK_STOP[self._rgb]
			self._grid[index][7]._off_value = TRACK_STOP[self._rgb]
			track_stop_buttons.append(self._grid[index][7])
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session.set_stop_all_clips_button(self._grid[7][7])
		#for index in range(4):
		#	self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		#self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		#self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
		#for index in range(6):
		#	self._menu[index]._on_value = HHMENU[index][1]
		#	self._menu[index]._off_value = HHMENU[index][0]
		for index in range(8):
			self._button[index].set_channel(2)
			self._button[index].set_identifier(index)
			#self._button[index].reset()
			self._button[index].set_enabled(False)
		self.request_rebuild_midi_map()
		for index in range(7):
			self._grid[index][7].turn_on()
		for index in range(2):
			self._looper[index]._state_change()
			self._button[1 + (index * 4)].send_value(3)
			self._button[2 + (index * 4)].send_value(6)
			self._button[3 + (index * 4)].send_value(1)

	def assign_page_1(self):
		self._backlight_type = 'pulse'
		self._session_zoom.set_enabled(False)
		for column in range(4):
			for row in range(4):
				self._grid[column][row].set_channel(PAGE1_DRUM_CHANNEL)
				self._grid[column][row].set_identifier(PAGE1_DRUM_MAP[column][row])
				self._grid[column][row].send_value(DRUM_COLOR[self._rgb], True)
				self._grid[column][row].set_enabled(False)
				self._grid[column + 4][row].set_channel(PAGE1_BASS_CHANNEL)
				self._grid[column + 4][row].set_identifier(PAGE1_BASS_MAP[column][row])
				self._grid[column + 4][row].send_value(BASS_COLOR[self._rgb], True)
				self._grid[column + 4][row].set_enabled(False)
		scale_mode_buttons = []
		for column in range(8):
			for row in range(3):
				self._grid[column][row + 4].set_enabled(False)
				self._grid[column][row + 4].set_channel(PAGE1_KEYS_CHANNEL)
				self._grid[column][row + 4].set_identifier(int(PAGE1_KEYS_MAP[column][row]) + int(PAGE1_MODES_MAP[self._scale_mode._mode_index][column]) + int(self._octave_mode._mode_index * 12))
				self._grid[column][row + 4].send_value(KEYS_COLOR[self._rgb], True)
			for row in range(1):
				scale_mode_buttons.append(self._grid[column][7])
		self._scale_mode.set_mode_buttons(tuple(scale_mode_buttons))
		self._scale_mode.set_enabled(True)
		#self._octave_mode.set_mode_buttons(tuple([self._menu[5], self._menu[2]]))
		#self._octave_mode.set_enabled(True)
		for column in range(7):
			self._mixer.channel_strip(column).set_send_controls(tuple([self._dial[column + 8]]))
			#self._button[column].set_on_off_values(REC_ARM, 0)
			#self._mixer.channel_strip(column).set_arm_button(self._button[column])
		self._device.set_enabled(True)
		device_param_controls = []
		for index in range(8):
			device_param_controls.append(self._dial[index])
		self._device.set_parameter_controls(tuple(device_param_controls))
		#for index in range(4):
		#	self._menu[2 + index]._on_value = (DEVICE_NAV_COLOR[self._rgb])
		#self._device_navigator.set_enabled(True)

		"""HH Specific from Constants"""
		#self._mixer.master_strip().set_select_button(self._button[7])
		#for column in range(7):
		#	self._button[column].set_on_off_values(REC_ARM, 0)
		#self._session_zoom.set_zoom_button(self._grid[7][7])
		#self._transport.set_play_button(self._menu[0])
		#self._menu[0].send_value(PLAY_COLOR[self._rgb], True)	
		#self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		#self._transport.set_stop_button(self._menu[1])
		#self._menu[1]._off_value = STOP_COLOR[self._rgb]
		#self._menu[1]._on_value = STOP_COLOR[self._rgb]
		#self._menu[1].send_value(STOP_COLOR[self._rgb], True)
		#self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])
		for index in range(8):
			self._button[index].set_channel(2)
			self._button[index].set_identifier(index)
			#self._button[index].reset()
			self._button[index].set_enabled(False)
		self.request_rebuild_midi_map()
		#for index in range(8):
		#	self._grid[index][7].send(self.
		for index in range(2):
			self._looper[index]._state_change()
			self._button[1 + (index * 4)].send_value(3)
			self._button[2 + (index * 4)].send_value(6)
			self._button[3 + (index * 4)].send_value(1)
	
	def assign_page_2(self):
		self._backlight_type = 'up'
		#self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_enabled(False)
		for column in range(7):
			self._grid[column][5]._on_value = MUTE_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6]._on_value = CROSSFADE_ASSIGN_COLOR[self._rgb]
			self._mixer.channel_strip(column).set_crossfade_toggle(self._grid[column][6])
			self._grid[column][7].set_channel(2)
			self._grid[column][7].set_identifier(column)
			self._grid[column][7].reset()
			self._grid[column][7].set_enabled(False)
			self._grid[column][7].send_value(4, True)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
		for row in range(5):
			self._grid[7][row]._off_value = SCENE_LAUNCH_COLOR[self._rgb]
			self._scene[row].set_launch_button(self._grid[7][row])
		for column in range(4):
			self._mixer.track_eq(column).set_gain_controls(tuple([self._dial[column + 8], self._dial[column + 4], self._dial[column]]))
			self._mixer.track_eq(column).set_enabled(True)	
		for column in range(3):
			self._mixer.channel_strip(column+4).set_pan_control(self._dial[column + 12])
		#for index in range(4):
		#	self._menu[2 + index]._on_value = NAV_BUTTON_COLOR[self._rgb]
		#self._session.set_track_bank_buttons(self._menu[4], self._menu[3])
		#self._session.set_scene_bank_buttons(self._menu[5], self._menu[2])
		self._set_tempo_buttons([self._grid[7][5], self._grid[7][6]])
		
		"""HH Specific from Constants"""
		#self._mixer.master_strip().set_select_button(self._button[7])
		#for column in range(7):
		#	self._mixer.channel_strip(column).set_select_button(self._button[column])
		#for index in range(8):
		#	self._button[index].set_on_off_values(SELECT_COLOR[self._rgb], 0)
		self._session_zoom.set_zoom_button(self._grid[7][7])
		#self._transport.set_play_button(self._menu[0])
		#self._menu[0].send_value(PLAY_COLOR[self._rgb], True)	
		#self._menu[0]._on_value = PLAY_COLOR[self._rgb]
		#self._transport.set_stop_button(self._menu[1])
		#self._menu[1]._off_value = STOP_COLOR[self._rgb]
		#self._menu[1]._on_value = STOP_COLOR[self._rgb]
		#self._menu[1].send_value(STOP_COLOR[self._rgb], True)
		#self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[4])
		for index in range(8):
			self._button[index].set_channel(2)
			self._button[index].set_identifier(index)
			#self._button[index].reset()
			self._button[index].set_enabled(False)
		self.request_rebuild_midi_map()
		for index in range(2):
			self._looper[index]._state_change()
			self._button[1 + (index * 4)].send_value(3)
			self._button[2 + (index * 4)].send_value(6)
			self._button[3 + (index * 4)].send_value(1)
		
	
	def _update_selected_device(self):
		if self._device_selection_follows_track_selection is True:
			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.set_device(device_to_select)
			self.set_appointed_device(device_to_select)
			#self._device_selector.set_enabled(True)
			self.request_rebuild_midi_map()
		return None
	
	def handle_sysex(self, midi_bytes):
		#self.log_message(str('>>sysexIN') + str(midi_bytes))
		if len(midi_bytes) > 10:
			#self.log_message(str('>>sysex>10') + str(midi_bytes[:11]))
			if midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7]):
				self.log_message(str('>>>color detected'))
				self._rgb = 1
			elif midi_bytes[:11] == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2]):
				self.log_message(str('>>>mono detected'))
				self._rgb = 0
		self._assign_session_colors()
		#self._shift_mode.update()
		self.deassign_matrix()
		self._assign_page_constants()
		self.assign_page_0()
		#self._setup_hilight_knobs()
		for index in range(8):
			self._grid[7][index].send_value(SCENE_LAUNCH_COLOR[self._rgb])
		for index in range(7):
			self._grid[index][7].turn_on()

# 	def handle_sysex(self, midi_bytes):
# 		#assert(isinstance (midi_bytes, tuple))
# 		##self.log_message(str('sysex') + str(midi_bytes))
# 		if midi_bytes == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 7, 0, 15, 10, 0, 0, 247]):
# 			self.log_message(str('color detected'))
# 			self._rgb = 1
# 		elif midi_bytes == tuple([240, 126, 0, 6, 2, 0, 1, 97, 1, 0, 2, 0, 0, 1, 1, 0, 247]):
# 			self.log_message(str('mono detected'))
# 			self._rgb = 0
# 		self._assign_session_colors()

	def receive_midi(self, midi_bytes):
		""" Live -> Script
		MIDI messages are only received through this function, when explicitly 
		forwarded in 'build_midi_map'.
	"""
		assert (midi_bytes != None)
		assert isinstance(midi_bytes, tuple)
		##self.log_message('got message' + str(midi_bytes))
		#self.set_suppress_rebuild_requests(True)
		with self.component_guard():
			if (len(midi_bytes) is 3):
				msg_type = (midi_bytes[0] & 240)
				forwarding_key = [midi_bytes[0]]
				if (msg_type is not MIDI_PB_TYPE):
					forwarding_key.append(midi_bytes[1])
				if (tuple(forwarding_key) in self._forwarding_registry.keys()):
					recipient = self._forwarding_registry[tuple(forwarding_key)]
					if (recipient != None):
						recipient.receive_value(midi_bytes[2])
				else:
					self.log_message(('Got unknown message: ' + str(midi_bytes)))
			else:
				self.handle_sysex(midi_bytes)
		#self.set_suppress_rebuild_requests(False)		 

	def _set_tempo_buttons(self, buttons):
		if self._tempo_buttons != None:
			self._tempo_buttons[0].remove_value_listener(self._tempo_value)
			self._tempo_buttons[1].remove_value_listener(self._tempo_value)
		self._tempo_buttons = buttons
		if buttons != None:
			for button in buttons:
				assert isinstance(button, FlashingButtonElement)
			self._tempo_buttons[0].set_on_off_values(4, 0)
			self._tempo_buttons[0].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[1].set_on_off_values(4, 0)
			self._tempo_buttons[1].add_value_listener(self._tempo_value, True)
			self._tempo_buttons[0].turn_on()
			self._tempo_buttons[1].turn_on()

	def _tempo_value(self, value, sender):
		if (value > 0) and (self._tempo_buttons.index(sender) == 0):
			self.song().tempo = round(min((self.song().tempo + 1), 999))
		elif (value > 0) and (self._tempo_buttons.index(sender) == 1):
			self.song().tempo = round(max((self.song().tempo - 1), 20))
			
		

	def set_scene_index_value(self, bank_index, scene, track):
		bank = int(bank_index)/5
		index = int(bank_index)%5
		self.log_message('set_scene_index_value' + str(bank) + str(index) + str(scene) + str(track))
		#self.log_message( str(type(index)) + str(type(scene)) + str(type(track)))
		self._scene_indexes[bank][index][0] = scene
		self._scene_indexes[bank][index][1] = track
		#self._on_selected_scene_changed()
	

	def connect_script_instances(self, instanciated_scripts):
		#link = False
		#offsets = [0, 0]
		#new_channel = CHAN
		for s in instanciated_scripts:
			if isinstance(s, APC) or s is self:
				#link = True
				if not s._session._is_linked():
					s._session._link()
					#self.log_message('found other linked instance')
					#offsets[0] += (int(self._link_offset[0]) * 8)
					#offsets[1] += (int(self._link_offset[1]) * 4)
					#new_channel += 1
		#if link and not self._session._is_linked():
			#self._session.set_offsets(offsets[0], offsets[1])
			#self._session._link()
		#self._set_code_channels(new_channel)
	
	
#
#
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        
Пример #49
0
class OP1(ControlSurface):
	def __init__(self, c_instance):
		ControlSurface.__init__(self, c_instance)
		self.c_instance = c_instance

		self.retries_count = 0
		self.device_connected = False

		self.clip_color_callbacks = {}
		self.slot_callbacks = {}

		self.text_start_sequence = (0xf0, 0x0, 0x20, 0x76, 0x00, 0x03)
		self.text_end_sequence = (0xf7,)
		self.enable_sequence = (0xf0, 0x00, 0x20, 0x76, 0x00, 0x01, 0x02, 0xf7)
		self.disable_sequence = (0xf0, 0x00, 0x20, 0x76, 0x00, 0x01, 0x00, 0xf7)

		self.id_sequence = (0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7)

		self.text_color_start_sequence = (0xf0, 0x0, 0x20, 0x76, 0x00, 0x04)

		self.log('INITIALIZING')

		self.app = Live.Application.get_application()

		#maj = self.app.get_major_version()
		#min = self.app.get_minor_version()
		#bug = self.app.get_bugfix_version()
		#self.show_message(str(1) + "." + str(0) + "." + str(9))

		self.show_message("Version " + VERSION)

		# reseting text
		self.write_text(' ')

		# reset display clips
		self.reset_display_clips()

		# getting browser visible state
		self.session_browser_visible = self.app.view.is_view_visible("Browser")
		
		# getting browser visible state
		self.arrange_browser_visible = self.app.view.is_view_visible("Browser")

		# getting session view visible state
		self.session_visible = self.app.view.is_view_visible("Session")

		# getting arrange view visible state
		self.arrange_visible = self.app.view.is_view_visible("Arranger")

		# getting detail view visible state
		self.detail_visible = self.app.view.is_view_visible("Detail")

		# getting back to arranger state
		self.back_to_arranger_state = self.song().back_to_arranger

		# initializing channel strip to null
		self._channel_strip = None

		# initializing transport component
		self._transport = TransportComponent()

		# initializing mixer component
		self._mixer = MixerComponent(NUM_TRACKS,2)

		# initializing session component
		self._session = SessionComponent(NUM_TRACKS,NUM_ROWS)
		self._session.add_offset_listener(self.session_offset_changed)

		# configuring operation mode selector buttons
		self._operation_mode_buttons = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_MODE_1_BUTTON), ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_MODE_2_BUTTON), ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_MODE_3_BUTTON), ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_MODE_4_BUTTON), 
		
		# initializing operation mode selector
		self._operation_mode_selector = OP1ModeSelectorComponent(self, self._transport, self._mixer, self._session)
		
		# setting operation mode selector buttons
		self._operation_mode_selector.set_mode_buttons(self._operation_mode_buttons)

		# adding value listener for operation mode index
		self._operation_mode_selector.add_mode_index_listener(self.mode_index_changed)

		# setting global transport assignments
		self._transport.set_record_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_REC_BUTTON))
		self._transport.set_play_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_PLAY_BUTTON))
		self._transport.set_stop_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_STOP_BUTTON))  
		self._transport.set_metronome_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_METRONOME_BUTTON))  
		self._transport.set_tap_tempo_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_HELP_BUTTON))
		self._transport.set_punch_buttons(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS1_BUTTON), ButtonElement(True,MIDI_CC_TYPE, CHANNEL, OP1_SS2_BUTTON))
		self._transport.set_loop_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS3_BUTTON))
		self._transport.set_overdub_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS4_BUTTON))

		# setting global session assignments
		self._session.set_scene_bank_buttons(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_COM),ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_MICRO))

		# setting misc listeners
		self.browser_toggle_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL, 15)
		self.browser_toggle_button.add_value_listener(self.browser_toggle_button_callback)

		self.mainview_toggle_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL, 16)
		self.mainview_toggle_button.add_value_listener(self.mainview_toggle_button_callback)

		self.detailview_toggle_button = ButtonElement(False, MIDI_CC_TYPE, CHANNEL, 17)
		self.detailview_toggle_button.add_value_listener(self.detailview_toggle_button_callback)

		self.clear_track_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, 25)
		self.clear_track_button.add_value_listener(self.clear_track_button_callback)

		self.back_to_arranger_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, 26)
		self.back_to_arranger_button.add_value_listener(self.back_to_arranger_button_callback)

		# adding value listener for selected track change
		self.song().view.add_selected_track_listener(self.selected_track_changed)

		# adding value listener for selected scene change
		self.song().view.add_selected_scene_listener(self.selected_scene_changed)

		# setting assignments for currently selected track
		self.selected_track_changed()

		# setting assignments for currently selected scene
		self.selected_scene_changed()

	def handle_sysex(self, midi_bytes):
		if ((midi_bytes[6]==32) and (midi_bytes[7]==118)):
			self.device_connected = True
			self.log("OP-1 CONNECTED. SENDING ABLETON LIVE MODE INIT SEQUENCE")
			self._send_midi(self.enable_sequence)

	def add_clip_slot_listeners(self):
		#self.log('ADDING CLIP SLOT LISTENERS')
		
		# creating an empty list for all clip slots
		clip_slots = []

		# getting a reference to all tracks
		tracks = self.song().tracks
		
		# appending all tracks clip slots to clip_slots
		for track in tracks:
			clip_slots.append(track.clip_slots)

		# iterating over all clip slots
		for t in range(len(clip_slots)):
			for c in range(len(clip_slots[t])):
				clip_slot = clip_slots[t][c]

				# adding has clip listener to clip slot
				self.add_slot_listener(clip_slot)

				# if clip slot has clip
				if clip_slot.has_clip:
					# adding clip listeners
					self.add_clip_listener(clip_slot.clip)

	def rem_clip_slot_listeners(self):
		#self.log('REMOVING CLIP SLOT LISTENERS')

		# iterate over all clip color change callbacks
		for c in self.clip_color_callbacks:
			# if clip still exists
			if c != None:
				# and it has a has clip listener
				if c.color_has_listener(self.clip_color_callbacks[c]) == 1:
					# remove it
					c.remove_color_listener(self.clip_color_callbacks[c])

		# iterate over all clip slot callbacks
		for cs in self.slot_callbacks:
			# if clip slot still exists
			if cs != None:
				# and it has a has clip listener
				if cs.has_clip_has_listener(self.slot_callbacks[cs]) == 1:
					# remove it
					cs.remove_has_clip_listener(self.slot_callbacks[cs])

	def add_slot_listener(self, cs):
		# setting has clip listener
		callback = lambda :self.has_clip_listener(cs)

		# if we don't have a clip slot has clip listener for this clip slot yet
		if not(self.slot_callbacks.has_key(cs)):
			# adding has clip callback to clip slot
			cs.add_has_clip_listener(callback)

			# saving callback for future release
			self.slot_callbacks[cs] = callback

	def add_clip_listener(self, clip):
		# setting callback for clip color change
		color_callback = lambda :self.update_display_clips()

		# if we don't have a clip color change callback for this clip yet
		if not(self.clip_color_callbacks.has_key(clip)):
			# adding clip color change callback
			clip.add_color_listener(color_callback)

			# saving callback for future release
			self.clip_color_callbacks[clip] = color_callback

	def has_clip_listener(self, cs):
		# clip slot has clip listener callback
		if cs.has_clip:
			# add clip listener
			self.add_clip_listener(cs.clip)
		else:
			# update display if clip slot was removed
			self.update_display_clips()

	def session_offset_changed(self):
		# if session component offset changes, update display
		self.update_display_clips()

	def selected_scene_changed(self):
		# if on clip mode update display
		if (self._operation_mode_selector.mode_index==OP1_MODE_CLIP):
			self.update_display_clip_mode()

	def mode_index_changed(self):
		# update display to current mode info
		if (self._operation_mode_selector.mode_index==OP1_MODE_PERFORM):
			self.update_display_perform_mode()
		elif (self._operation_mode_selector.mode_index==OP1_MODE_CLIP):
			self.update_display_clip_mode()
		elif (self._operation_mode_selector.mode_index==OP1_MODE_TRANSPORT):
			self.update_display_transport_mode()
		elif (self._operation_mode_selector.mode_index==OP1_MODE_MIXER):
			self.update_display_mixer_mode()

	def	clear_track_button_callback(self, value):
		# if clear track button was called, reset track
		if (value==127):
			for i in range(len(self.song().tracks)):
				self.song().tracks[i].arm = 0
				self.song().tracks[i].solo = 0
				self.song().tracks[i].mute = 0

			for i in range(len(self.song().return_tracks)):
				self.song().tracks[i].solo = 0
				self.song().tracks[i].mute = 0

	def clear_return_track_assignment(self, strip):
		# clear return track assingments
		strip.set_volume_control(None)
		strip.set_pan_control(None)
		strip.set_mute_button(None)
		strip.set_solo_button(None)
	
	def clear_track_assignment(self, strip):
		# clear track assignments
		strip.set_volume_control(None)
		strip.set_pan_control(None)
		strip.set_mute_button(None)
		strip.set_solo_button(None)
		strip.set_arm_button(None)

	def clear_tracks_assigments(self):
		# for all normal tracks, clear assignments
		for i in range(NUM_TRACKS):
			strip = self._mixer.channel_strip(i)
			if (strip!=None):
				self.clear_track_assignment(strip)

		# for all return tracks, clear assignments
		for i in range(2):
			return_strip = self._mixer.return_strip(i)
			if (return_strip!=None):
				self.clear_return_track_assignment(return_strip)

	def selected_track_changed(self):
		# if on mixer mode update display
		if (self._operation_mode_selector.mode_index==OP1_MODE_MIXER):
			self.update_display_mixer_mode()

		# clear track assignments
		self.clear_tracks_assigments()

		# getting selected strip
		self._channel_strip = self._mixer.selected_strip()

		# perform track assignments 
		self._channel_strip.set_volume_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_1, Live.MidiMap.MapMode.relative_two_compliment))
		self._channel_strip.set_pan_control(EncoderElement(MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_2, Live.MidiMap.MapMode.relative_two_compliment))

		# setting a tuple of encoders to control sends
		send_controls = EncoderElement(MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_3, Live.MidiMap.MapMode.relative_two_compliment), EncoderElement(MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_4, Live.MidiMap.MapMode.relative_two_compliment),

		# setting send encoders
		self._channel_strip.set_send_controls(tuple(send_controls))

		# setting solo button
		self._channel_strip.set_solo_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS6_BUTTON))

		# if track can be armed, set arm button
		if (self._channel_strip._track.can_be_armed):
			self._channel_strip.set_arm_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS7_BUTTON))

		# if track is no master, set mute button
		if (self._channel_strip._track!=self.song().master_track):
			self._channel_strip.set_mute_button(ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS5_BUTTON))


	def browser_toggle_button_callback(self, value):
		if (value==127):
			if (self.session_visible):
				if (self.session_browser_visible==True):
					self.session_browser_visible=False
					self.app.view.hide_view("Browser")
				else:
					self.session_browser_visible=True
					self.app.view.show_view("Browser")

			if (self.arrange_visible):
				if (self.arrange_browser_visible==True):
					self.arrange_browser_visible=False
					self.app.view.hide_view("Browser")
				else:
					self.arrange_browser_visible=True
					self.app.view.show_view("Browser")

	def back_to_arranger_button_callback(self, value):
		if (value==127):
			self.song().back_to_arranger = False

	def mainview_toggle_button_callback(self, value):
		if (value==127):
			if (self.session_visible==True):
				self.session_visible=False
				self.arrange_visible=True
				self.app.view.show_view("Arranger")
				self.arrange_browser_visible = self.app.view.is_view_visible("Browser");
			else:
				self.session_visible=True
				self.arrange_visible=False
				self.app.view.show_view("Session")
				self.session_browser_visible = self.app.view.is_view_visible("Browser");

	def detailview_toggle_button_callback(self, value):
		if (value==127):
			if (self.detail_visible==True):
				self.detail_visible=False
				self.app.view.hide_view("Detail")
			else:
				self.detail_visible=True
				self.app.view.show_view("Detail")

	def write_text(self, msg):
		text_list = []
		sequence = ()
		
		text_list.append(len(msg.strip()))
		
		for i in msg.strip():
   			text_list.append(ord(i))
   		
   		sequence = self.text_start_sequence + tuple(text_list) + self.text_end_sequence
		
		self._send_midi(sequence)

	def suggest_input_port(self):
		return "OP-1 Midi Device"

	def suggest_output_port(self):
		return "OP-1 Midi Device"

	def update_display_perform_mode(self):
		self.write_text("perform\rmode")

	def reset_display_clips(self):
		count = 0
		colors = []
		length = []
		sequence = ()
		
		for i in range (NUM_TRACKS):
			count+=1

			colors.append(0x00)
			colors.append(0x00)
			colors.append(0x00)

		length.append(count)
		sequence = self.text_color_start_sequence + tuple(length) + tuple(colors) + self.text_end_sequence
		self._send_midi(sequence)

	def update_display_clips(self):
		#self.log("UPDATING DISPLAY CLIPS")
		count = 0
		colors = []
		length = []
		sequence = ()
		
		tracks_len = len(self.song().tracks)-self._session._track_offset

		if (tracks_len>NUM_TRACKS):
			tracks_len = NUM_TRACKS

		for i in range (tracks_len):
			count+=1

			clip_slot = self._session.scene(0).clip_slot(i)
			
			if (clip_slot!=None):
				if (clip_slot.has_clip()!=False):
					clip_color = clip_slot._clip_slot.clip.color
					colors.append(((clip_color>>16)&0x000000ff)>>1)
					colors.append(((clip_color>>8)&0x000000ff)>>1)
					colors.append((clip_color&0x000000ff)>>1)
				else:
					colors.append(0x00)
					colors.append(0x00)
					colors.append(0x00)
			else:
				colors.append(0x00)
				colors.append(0x00)
				colors.append(0x00)

		length.append(count)
		sequence = self.text_color_start_sequence + tuple(length) + tuple(colors) + self.text_end_sequence
		self._send_midi(sequence)

	def update_display_clip_mode(self):
		self.write_text("sel. scene\r" + str(self.song().view.selected_scene.name.lower().strip()))

	def update_display_transport_mode(self):
		song_time = str(self.song().get_current_beats_song_time())
		self.write_text("song pos.\r" + song_time[:len(song_time)-4])

	def update_display_mixer_mode(self):
		self.write_text("sel. track\r" + str(self.song().view.selected_track.name.lower()))

	def update_display(self):
		if not(self.device_connected):
			if (self.retries_count<5):
				self.log("TRYING OP-1 CONNECTION")
				self.retries_count+=1
				self._send_midi(self.id_sequence)
				time.sleep(1)

		# if in transport mode, update display with song position
		if (self._operation_mode_selector.mode_index==OP1_MODE_TRANSPORT):
			self.update_display_transport_mode()

		# checking if app current view is session
		if (self.app.view.is_view_visible("Session")):
			# checking if session browser state is diferent from the internal
			if (self.session_browser_visible != self.app.view.is_view_visible("Browser")):
				self.session_browser_visible = self.app.view.is_view_visible("Browser")

		# checking if app current view is arrange
		if (self.app.view.is_view_visible("Arranger")):
			# checking if arrange browser state is diferent from the internal
			if (self.arrange_browser_visible != self.app.view.is_view_visible("Browser")):
				self.arrange_browser_visible = self.app.view.is_view_visible("Browser")

		# checking if app current view is detail
		if (self.app.view.is_view_visible("Detail")):
			# checking if detail state is diferent from the internal
			if (self.detail_visible != self.app.view.is_view_visible("Detail")):
				self.detail_visible = self.app.view.is_view_visible("Detail")

	def refresh_state(self):
		self.log("REFRESH STATE")
		self.retries_count = 0
		self.device_connected = False

	def build_midi_map(self, midi_map_handle):
		#self.log("BUILD MIDI MAP")

		assert (self._suppress_requests_counter == 0)
		self._in_build_midi_map = True
		self._midi_map_handle = midi_map_handle
		self._forwarding_registry = {}
		for control in self.controls:
			if isinstance(control, InputControlElement):
				control.install_connections()
		self._midi_map_handle = None
		self._in_build_midi_map = False
		if (self._pad_translations != None):
			self._c_instance.set_pad_translation(self._pad_translations)

		# remove clip listeners
		self.rem_clip_slot_listeners()
		
		# add clip listeners
		self.add_clip_slot_listeners()
		
		# update display
		self.update_display_clips()
		
	def log(self, msg):
		self.c_instance.log_message("[TE OP-1] " + msg)

	def disconnect(self):
		# removing clip slots listeners
		self.rem_clip_slot_listeners()

		# removing value listener for track changed
		self.song().view.remove_selected_track_listener(self.selected_track_changed)

		# removing value listener for scene changed
		self.song().view.remove_selected_scene_listener(self.selected_scene_changed)

		# removing value listener for operation mode index
		self._operation_mode_selector.remove_mode_index_listener(self.mode_index_changed)

		# removing global transport assignments
		self._transport.set_punch_buttons(None, None)
		self._transport.set_loop_button(None)
		self._transport.set_overdub_button(None)
		self._transport.set_record_button(None)
		self._transport.set_play_button(None)
		self._transport.set_stop_button(None)  
		self._transport.set_metronome_button(None)  
		self._transport.set_tap_tempo_button(None)

		# removing global session assignments
		self._session.set_scene_bank_buttons(None, None)
		
		# removing misc listeners
		self.browser_toggle_button.remove_value_listener(self.browser_toggle_button_callback)
		self.mainview_toggle_button.remove_value_listener(self.mainview_toggle_button_callback)
		self.detailview_toggle_button.remove_value_listener(self.detailview_toggle_button_callback)
		self.clear_track_button.remove_value_listener(self.clear_track_button_callback)
		self.back_to_arranger_button.remove_value_listener(self.back_to_arranger_button_callback)
		
		# sending special ableton mode disable sequence
		self._send_midi(self.disable_sequence)
		
		# disconnecting control surface
		ControlSurface.disconnect(self)
		
		self.log("DISCONNECTED")
Пример #50
0
class ProjectX(ControlSurface):
    __module__ = __name__
    __doc__ = " ProjectX keyboard 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)

        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= ProjectX log opened =--------------")

        with self.component_guard():
            self._create_transport_control()
            self._create_mixer_control()
            self._create_session_control()

        self.request_rebuild_midi_map()
        self.log_message("Captain's last log stardate ****")

    def _create_transport_control(self):
        is_momentary = True

        self._transport = TransportComponent(is_enabled=True, name='Transport')
        """set up the buttons"""
        self._transport.set_play_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 61))
        self._transport.set_stop_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 63))
        self._transport.set_record_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 66))
        self._transport.set_overdub_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 68))
        self._transport.set_nudge_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 75),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 73))
        self._transport.set_tap_tempo_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 78))
        self._transport.set_metronome_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 80))
        self._transport.set_loop_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 82))
        self._transport.set_punch_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 85),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 87))
        self._transport.set_seek_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 90),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 92))
        """set up the sliders"""
        self._transport.set_tempo_control(
            SliderElement(MIDI_CC_TYPE, CHANNEL, 26),
            SliderElement(MIDI_CC_TYPE, CHANNEL, 25))
        self._transport.set_song_position_control(
            SliderElement(MIDI_CC_TYPE, CHANNEL, 24))

        self.log_message("Captain's log stardate 1")

    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")

    def _create_session_control(self):
        is_momentary = True
        num_tracks = 1
        num_scenes = 7
        global session
        session = SessionComponent(num_tracks, num_scenes)
        session.set_offsets(0, 0)
        """set up the session navigation buttons"""
        session.set_select_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 25),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 27))
        session.set_scene_bank_buttons(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 51),
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 49))
        session.set_stop_all_clips_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 70))
        session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, 30))
        """Here we set up the scene launch assignments for the session"""
        launch_notes = [60, 62, 64, 65, 67, 69, 71]
        for index in range(num_scenes):
            session.scene(index).set_launch_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              launch_notes[index]))
        """Here we set up the track stop launch assignment(s) for the session"""
        stop_track_buttons = []
        for index in range(num_tracks):
            stop_track_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL,
                              58 + index))
        session.set_stop_track_clip_buttons(tuple(stop_track_buttons))
        """Here we set up the clip launch assignments for the session"""
        clip_launch_notes = [48, 50, 52, 53, 55, 57, 59]
        for index in range(num_scenes):
            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.log_message("Captain's log stardate 3")

    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)
        """here we set the mixer and session to the selected track, when the selected track changes"""
        selected_track = self.song().view.selected_track
        mixer.channel_strip(0).set_track(selected_track)
        all_tracks = ((self.song().tracks + self.song().return_tracks) +
                      (self.song().master_track, ))
        index = list(all_tracks).index(selected_track)
        session.set_offsets(index, session._scene_offset)

    def disconnect(self):
        """clean things up on disconnect"""
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= ProjectX log closed =--------------")
        ControlSurface.disconnect(self)
        return None
Пример #51
0
class OP1(ControlSurface):
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.c_instance = c_instance

        self.retries_count = 0
        self.device_connected = False

        self.clip_color_callbacks = {}
        self.slot_callbacks = {}

        self.text_start_sequence = (0xf0, 0x0, 0x20, 0x76, 0x00, 0x03)
        self.text_end_sequence = (0xf7, )
        self.enable_sequence = (0xf0, 0x00, 0x20, 0x76, 0x00, 0x01, 0x02, 0xf7)
        self.disable_sequence = (0xf0, 0x00, 0x20, 0x76, 0x00, 0x01, 0x00,
                                 0xf7)

        self.id_sequence = (0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7)

        self.text_color_start_sequence = (0xf0, 0x0, 0x20, 0x76, 0x00, 0x04)

        self.log('INITIALIZING')

        self.app = Live.Application.get_application()

        #maj = self.app.get_major_version()
        #min = self.app.get_minor_version()
        #bug = self.app.get_bugfix_version()
        #self.show_message(str(1) + "." + str(0) + "." + str(9))

        self.show_message("Version " + VERSION)

        # reseting text
        self.write_text(' ')

        # reset display clips
        self.reset_display_clips()

        # getting browser visible state
        self.session_browser_visible = self.app.view.is_view_visible("Browser")

        # getting browser visible state
        self.arrange_browser_visible = self.app.view.is_view_visible("Browser")

        # getting session view visible state
        self.session_visible = self.app.view.is_view_visible("Session")

        # getting arrange view visible state
        self.arrange_visible = self.app.view.is_view_visible("Arranger")

        # getting detail view visible state
        self.detail_visible = self.app.view.is_view_visible("Detail")

        # getting back to arranger state
        self.back_to_arranger_state = self.song().back_to_arranger

        # initializing channel strip to null
        self._channel_strip = None

        # initializing transport component
        self._transport = TransportComponent()

        # initializing mixer component
        self._mixer = MixerComponent(NUM_TRACKS, 2)

        # initializing session component
        self._session = SessionComponent(NUM_TRACKS, NUM_ROWS)
        self._session.add_offset_listener(self.session_offset_changed)

        # configuring operation mode selector buttons
        self._operation_mode_buttons = ButtonElement(
            True, MIDI_CC_TYPE, CHANNEL, OP1_MODE_1_BUTTON), ButtonElement(
                True, MIDI_CC_TYPE, CHANNEL, OP1_MODE_2_BUTTON), ButtonElement(
                    True, MIDI_CC_TYPE, CHANNEL,
                    OP1_MODE_3_BUTTON), ButtonElement(True, MIDI_CC_TYPE,
                                                      CHANNEL,
                                                      OP1_MODE_4_BUTTON),

        # initializing operation mode selector
        self._operation_mode_selector = OP1ModeSelectorComponent(
            self, self._transport, self._mixer, self._session)

        # setting operation mode selector buttons
        self._operation_mode_selector.set_mode_buttons(
            self._operation_mode_buttons)

        # adding value listener for operation mode index
        self._operation_mode_selector.add_mode_index_listener(
            self.mode_index_changed)

        # setting global transport assignments
        self._transport.set_record_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_REC_BUTTON))
        self._transport.set_play_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_PLAY_BUTTON))
        self._transport.set_stop_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_STOP_BUTTON))
        self._transport.set_metronome_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_METRONOME_BUTTON))
        self._transport.set_tap_tempo_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_HELP_BUTTON))
        self._transport.set_punch_buttons(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS1_BUTTON),
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS2_BUTTON))
        self._transport.set_loop_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS3_BUTTON))
        self._transport.set_overdub_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS4_BUTTON))

        # setting global session assignments
        self._session.set_scene_bank_buttons(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_COM),
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_MICRO))

        # setting misc listeners
        self.browser_toggle_button = ButtonElement(False, MIDI_CC_TYPE,
                                                   CHANNEL, 15)
        self.browser_toggle_button.add_value_listener(
            self.browser_toggle_button_callback)

        self.mainview_toggle_button = ButtonElement(False, MIDI_CC_TYPE,
                                                    CHANNEL, 16)
        self.mainview_toggle_button.add_value_listener(
            self.mainview_toggle_button_callback)

        self.detailview_toggle_button = ButtonElement(False, MIDI_CC_TYPE,
                                                      CHANNEL, 17)
        self.detailview_toggle_button.add_value_listener(
            self.detailview_toggle_button_callback)

        self.clear_track_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL,
                                                25)
        self.clear_track_button.add_value_listener(
            self.clear_track_button_callback)

        self.back_to_arranger_button = ButtonElement(True, MIDI_CC_TYPE,
                                                     CHANNEL, 26)
        self.back_to_arranger_button.add_value_listener(
            self.back_to_arranger_button_callback)

        # adding value listener for selected track change
        self.song().view.add_selected_track_listener(
            self.selected_track_changed)

        # adding value listener for selected scene change
        self.song().view.add_selected_scene_listener(
            self.selected_scene_changed)

        # setting assignments for currently selected track
        self.selected_track_changed()

        # setting assignments for currently selected scene
        self.selected_scene_changed()

    def handle_sysex(self, midi_bytes):
        if ((midi_bytes[6] == 32) and (midi_bytes[7] == 118)):
            self.device_connected = True
            self.log("OP-1 CONNECTED. SENDING ABLETON LIVE MODE INIT SEQUENCE")
            self._send_midi(self.enable_sequence)

    def add_clip_slot_listeners(self):
        #self.log('ADDING CLIP SLOT LISTENERS')

        # creating an empty list for all clip slots
        clip_slots = []

        # getting a reference to all tracks
        tracks = self.song().tracks

        # appending all tracks clip slots to clip_slots
        for track in tracks:
            clip_slots.append(track.clip_slots)

        # iterating over all clip slots
        for t in range(len(clip_slots)):
            for c in range(len(clip_slots[t])):
                clip_slot = clip_slots[t][c]

                # adding has clip listener to clip slot
                self.add_slot_listener(clip_slot)

                # if clip slot has clip
                if clip_slot.has_clip:
                    # adding clip listeners
                    self.add_clip_listener(clip_slot.clip)

    def rem_clip_slot_listeners(self):
        #self.log('REMOVING CLIP SLOT LISTENERS')

        # iterate over all clip color change callbacks
        for c in self.clip_color_callbacks:
            # if clip still exists
            if c != None:
                # and it has a has clip listener
                if c.color_has_listener(self.clip_color_callbacks[c]) == 1:
                    # remove it
                    c.remove_color_listener(self.clip_color_callbacks[c])

        # iterate over all clip slot callbacks
        for cs in self.slot_callbacks:
            # if clip slot still exists
            if cs != None:
                # and it has a has clip listener
                if cs.has_clip_has_listener(self.slot_callbacks[cs]) == 1:
                    # remove it
                    cs.remove_has_clip_listener(self.slot_callbacks[cs])

    def add_slot_listener(self, cs):
        # setting has clip listener
        callback = lambda: self.has_clip_listener(cs)

        # if we don't have a clip slot has clip listener for this clip slot yet
        if not (self.slot_callbacks.has_key(cs)):
            # adding has clip callback to clip slot
            cs.add_has_clip_listener(callback)

            # saving callback for future release
            self.slot_callbacks[cs] = callback

    def add_clip_listener(self, clip):
        # setting callback for clip color change
        color_callback = lambda: self.update_display_clips()

        # if we don't have a clip color change callback for this clip yet
        if not (self.clip_color_callbacks.has_key(clip)):
            # adding clip color change callback
            clip.add_color_listener(color_callback)

            # saving callback for future release
            self.clip_color_callbacks[clip] = color_callback

    def has_clip_listener(self, cs):
        # clip slot has clip listener callback
        if cs.has_clip:
            # add clip listener
            self.add_clip_listener(cs.clip)
        else:
            # update display if clip slot was removed
            self.update_display_clips()

    def session_offset_changed(self):
        # if session component offset changes, update display
        self.update_display_clips()

    def selected_scene_changed(self):
        # if on clip mode update display
        if (self._operation_mode_selector.mode_index == OP1_MODE_CLIP):
            self.update_display_clip_mode()

    def mode_index_changed(self):
        # update display to current mode info
        if (self._operation_mode_selector.mode_index == OP1_MODE_PERFORM):
            self.update_display_perform_mode()
        elif (self._operation_mode_selector.mode_index == OP1_MODE_CLIP):
            self.update_display_clip_mode()
        elif (self._operation_mode_selector.mode_index == OP1_MODE_TRANSPORT):
            self.update_display_transport_mode()
        elif (self._operation_mode_selector.mode_index == OP1_MODE_MIXER):
            self.update_display_mixer_mode()

    def clear_track_button_callback(self, value):
        # if clear track button was called, reset track
        if (value == 127):
            for i in range(len(self.song().tracks)):
                self.song().tracks[i].arm = 0
                self.song().tracks[i].solo = 0
                self.song().tracks[i].mute = 0

            for i in range(len(self.song().return_tracks)):
                self.song().tracks[i].solo = 0
                self.song().tracks[i].mute = 0

    def clear_return_track_assignment(self, strip):
        # clear return track assingments
        strip.set_volume_control(None)
        strip.set_pan_control(None)
        strip.set_mute_button(None)
        strip.set_solo_button(None)

    def clear_track_assignment(self, strip):
        # clear track assignments
        strip.set_volume_control(None)
        strip.set_pan_control(None)
        strip.set_mute_button(None)
        strip.set_solo_button(None)
        strip.set_arm_button(None)

    def clear_tracks_assigments(self):
        # for all normal tracks, clear assignments
        for i in range(NUM_TRACKS):
            strip = self._mixer.channel_strip(i)
            if (strip != None):
                self.clear_track_assignment(strip)

        # for all return tracks, clear assignments
        for i in range(2):
            return_strip = self._mixer.return_strip(i)
            if (return_strip != None):
                self.clear_return_track_assignment(return_strip)

    def selected_track_changed(self):
        # if on mixer mode update display
        if (self._operation_mode_selector.mode_index == OP1_MODE_MIXER):
            self.update_display_mixer_mode()

        # clear track assignments
        self.clear_tracks_assigments()

        # getting selected strip
        self._channel_strip = self._mixer.selected_strip()

        # perform track assignments
        self._channel_strip.set_volume_control(
            EncoderElement(MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_1,
                           Live.MidiMap.MapMode.relative_two_compliment))
        self._channel_strip.set_pan_control(
            EncoderElement(MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_2,
                           Live.MidiMap.MapMode.relative_two_compliment))

        # setting a tuple of encoders to control sends
        send_controls = EncoderElement(
            MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_3,
            Live.MidiMap.MapMode.relative_two_compliment), EncoderElement(
                MIDI_CC_TYPE, CHANNEL, OP1_ENCODER_4,
                Live.MidiMap.MapMode.relative_two_compliment),

        # setting send encoders
        self._channel_strip.set_send_controls(tuple(send_controls))

        # setting solo button
        self._channel_strip.set_solo_button(
            ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS6_BUTTON))

        # if track can be armed, set arm button
        if (self._channel_strip._track.can_be_armed):
            self._channel_strip.set_arm_button(
                ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS7_BUTTON))

        # if track is no master, set mute button
        if (self._channel_strip._track != self.song().master_track):
            self._channel_strip.set_mute_button(
                ButtonElement(True, MIDI_CC_TYPE, CHANNEL, OP1_SS5_BUTTON))

    def browser_toggle_button_callback(self, value):
        if (value == 127):
            if (self.session_visible):
                if (self.session_browser_visible == True):
                    self.session_browser_visible = False
                    self.app.view.hide_view("Browser")
                else:
                    self.session_browser_visible = True
                    self.app.view.show_view("Browser")

            if (self.arrange_visible):
                if (self.arrange_browser_visible == True):
                    self.arrange_browser_visible = False
                    self.app.view.hide_view("Browser")
                else:
                    self.arrange_browser_visible = True
                    self.app.view.show_view("Browser")

    def back_to_arranger_button_callback(self, value):
        if (value == 127):
            self.song().back_to_arranger = False

    def mainview_toggle_button_callback(self, value):
        if (value == 127):
            if (self.session_visible == True):
                self.session_visible = False
                self.arrange_visible = True
                self.app.view.show_view("Arranger")
                self.arrange_browser_visible = self.app.view.is_view_visible(
                    "Browser")
            else:
                self.session_visible = True
                self.arrange_visible = False
                self.app.view.show_view("Session")
                self.session_browser_visible = self.app.view.is_view_visible(
                    "Browser")

    def detailview_toggle_button_callback(self, value):
        if (value == 127):
            if (self.detail_visible == True):
                self.detail_visible = False
                self.app.view.hide_view("Detail")
            else:
                self.detail_visible = True
                self.app.view.show_view("Detail")

    def write_text(self, msg):
        text_list = []
        sequence = ()

        text_list.append(len(msg.strip()))

        for i in msg.strip():
            text_list.append(ord(i))

        sequence = self.text_start_sequence + tuple(
            text_list) + self.text_end_sequence

        self._send_midi(sequence)

    def suggest_input_port(self):
        return "OP-1 Midi Device"

    def suggest_output_port(self):
        return "OP-1 Midi Device"

    def update_display_perform_mode(self):
        self.write_text("perform\rmode")

    def reset_display_clips(self):
        count = 0
        colors = []
        length = []
        sequence = ()

        for i in range(NUM_TRACKS):
            count += 1

            colors.append(0x00)
            colors.append(0x00)
            colors.append(0x00)

        length.append(count)
        sequence = self.text_color_start_sequence + tuple(length) + tuple(
            colors) + self.text_end_sequence
        self._send_midi(sequence)

    def update_display_clips(self):
        #self.log("UPDATING DISPLAY CLIPS")
        count = 0
        colors = []
        length = []
        sequence = ()

        tracks_len = len(self.song().tracks) - self._session._track_offset

        if (tracks_len > NUM_TRACKS):
            tracks_len = NUM_TRACKS

        for i in range(tracks_len):
            count += 1

            clip_slot = self._session.scene(0).clip_slot(i)

            if (clip_slot != None):
                if (clip_slot.has_clip() != False):
                    clip_color = clip_slot._clip_slot.clip.color
                    colors.append(((clip_color >> 16) & 0x000000ff) >> 1)
                    colors.append(((clip_color >> 8) & 0x000000ff) >> 1)
                    colors.append((clip_color & 0x000000ff) >> 1)
                else:
                    colors.append(0x00)
                    colors.append(0x00)
                    colors.append(0x00)
            else:
                colors.append(0x00)
                colors.append(0x00)
                colors.append(0x00)

        length.append(count)
        sequence = self.text_color_start_sequence + tuple(length) + tuple(
            colors) + self.text_end_sequence
        self._send_midi(sequence)

    def update_display_clip_mode(self):
        self.write_text(
            "sel. scene\r" +
            str(self.song().view.selected_scene.name.lower().strip()))

    def update_display_transport_mode(self):
        song_time = str(self.song().get_current_beats_song_time())
        self.write_text("song pos.\r" + song_time[:len(song_time) - 4])

    def update_display_mixer_mode(self):
        self.write_text("sel. track\r" +
                        str(self.song().view.selected_track.name.lower()))

    def update_display(self):
        if not (self.device_connected):
            if (self.retries_count < 5):
                self.log("TRYING OP-1 CONNECTION")
                self.retries_count += 1
                self._send_midi(self.id_sequence)
                time.sleep(1)

        # if in transport mode, update display with song position
        if (self._operation_mode_selector.mode_index == OP1_MODE_TRANSPORT):
            self.update_display_transport_mode()

        # checking if app current view is session
        if (self.app.view.is_view_visible("Session")):
            # checking if session browser state is diferent from the internal
            if (self.session_browser_visible !=
                    self.app.view.is_view_visible("Browser")):
                self.session_browser_visible = self.app.view.is_view_visible(
                    "Browser")

        # checking if app current view is arrange
        if (self.app.view.is_view_visible("Arranger")):
            # checking if arrange browser state is diferent from the internal
            if (self.arrange_browser_visible !=
                    self.app.view.is_view_visible("Browser")):
                self.arrange_browser_visible = self.app.view.is_view_visible(
                    "Browser")

        # checking if app current view is detail
        if (self.app.view.is_view_visible("Detail")):
            # checking if detail state is diferent from the internal
            if (self.detail_visible !=
                    self.app.view.is_view_visible("Detail")):
                self.detail_visible = self.app.view.is_view_visible("Detail")

    def refresh_state(self):
        self.log("REFRESH STATE")
        self.retries_count = 0
        self.device_connected = False

    def build_midi_map(self, midi_map_handle):
        #self.log("BUILD MIDI MAP")

        assert (self._suppress_requests_counter == 0)
        self._in_build_midi_map = True
        self._midi_map_handle = midi_map_handle
        self._forwarding_registry = {}
        for control in self.controls:
            if isinstance(control, InputControlElement):
                control.install_connections()
        self._midi_map_handle = None
        self._in_build_midi_map = False
        if (self._pad_translations != None):
            self._c_instance.set_pad_translation(self._pad_translations)

        # remove clip listeners
        self.rem_clip_slot_listeners()

        # add clip listeners
        self.add_clip_slot_listeners()

        # update display
        self.update_display_clips()

    def log(self, msg):
        self.c_instance.log_message("[TE OP-1] " + msg)

    def disconnect(self):
        # removing clip slots listeners
        self.rem_clip_slot_listeners()

        # removing value listener for track changed
        self.song().view.remove_selected_track_listener(
            self.selected_track_changed)

        # removing value listener for scene changed
        self.song().view.remove_selected_scene_listener(
            self.selected_scene_changed)

        # removing value listener for operation mode index
        self._operation_mode_selector.remove_mode_index_listener(
            self.mode_index_changed)

        # removing global transport assignments
        self._transport.set_punch_buttons(None, None)
        self._transport.set_loop_button(None)
        self._transport.set_overdub_button(None)
        self._transport.set_record_button(None)
        self._transport.set_play_button(None)
        self._transport.set_stop_button(None)
        self._transport.set_metronome_button(None)
        self._transport.set_tap_tempo_button(None)

        # removing global session assignments
        self._session.set_scene_bank_buttons(None, None)

        # removing misc listeners
        self.browser_toggle_button.remove_value_listener(
            self.browser_toggle_button_callback)
        self.mainview_toggle_button.remove_value_listener(
            self.mainview_toggle_button_callback)
        self.detailview_toggle_button.remove_value_listener(
            self.detailview_toggle_button_callback)
        self.clear_track_button.remove_value_listener(
            self.clear_track_button_callback)
        self.back_to_arranger_button.remove_value_listener(
            self.back_to_arranger_button_callback)

        # sending special ableton mode disable sequence
        self._send_midi(self.disable_sequence)

        # disconnecting control surface
        ControlSurface.disconnect(self)

        self.log("DISCONNECTED")
Пример #52
0
class BlockMod(MonOhm):
	__module__ = __name__
	__doc__ = " Monomodular controller script for Livid Block "


	def __init__(self, *a, **k):
		self._shift_button = None
		self._shift_pressed = 0
		self._shift_pressed_timer = 0
		self._shift_thresh = SHIFT_THRESH
		super(BlockMod, self).__init__(*a, **k)
		self._host_name = 'BlockMod'
		self._color_type = 'Monochrome'
		self._link_mixer = LINK_MIXER
		self._rgb = 1
		self._ohm = 127
		self._ohm_type = 'static'
		self._pad_translations = PAD_TRANSLATION
		self._mem = [4, 8, 12, 16]
		self._host._navbox_selected = 8
	

	"""script initialization methods"""
	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def _setup_controls(self):
		is_momentary = True
		self._fader = [None for index in range(8)]
		self._dial = [None for index in range(16)]
		self._button = [None for index in range(8)]
		self._menu = [None for index in range(6)]
		for index in range(2):
			self._fader[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, SLIDER_CC[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self)
		#for index in range(8):
		#	self._button[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, OHM_BUTTONS[index], 'Button_' + str(index), self)
		for index in range(8):
			self._dial[index] = MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, KNOB_CC[index], Live.MidiMap.MapMode.absolute, 'Dial_' + str(index), index + 8, self)
		for index in range(4):
			self._menu[index] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, FUNCTION_NOTES[index], 'Menu_' + str(index), self)	
		self._livid = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self)
		self._shift_l = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_L, 'Shift_Button_Left', self)
		self._shift_r = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, SHIFT_R, 'Shift_Button_Right', self)
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Matrix'
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		self._grid = [None for index in range(8)]
		for column in range(8):
			self._grid[column] = [None for index in range(8)]
			for row in range(8):
				self._grid[column][row] = MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, (column * 8) + row, 'Grid_' + str(column) + '_' + str(row), self)
		for row in range(5):
			button_row = []
			for column in range(7):
				button_row.append(self._grid[column][row])
			self._matrix.add_row(tuple(button_row)) 
		for row in range(8):
			button_row = []
			for column in range(8):
				button_row.append(self._grid[column][row])
			self._monomod.add_row(tuple(button_row))
		self._dummy_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 125)
		self._dummy_button.name = 'Dummy1'
		self._dummy_button2 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 126)
		self._dummy_button2.name = 'Dummy2'
		self._dummy_button3 = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 15, 127)
		self._dummy_button2.name = 'Dummy3'
	

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

	def _setup_crossfader(self):
		pass
	

	def _setup_modes(self):
		self._monomod_mode = MonomodModeComponent(self, self.monomod_mode_update)
		self._monomod_mode.name = 'Monomod_Mode'
		self.set_shift_button(self._livid)
		self._shift_mode = BlockModShiftModeComponent(self, self.shift_update) 
		self._shift_mode.name = 'Shift_Mode'
		self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
		self._l_function_mode = FunctionModeComponent(self, self.l_function_update)
		self._l_function_mode.name = 'Left_Function_Mode'
		self._r_function_mode = FunctionModeComponent(self, self.r_function_update)
		self._r_function_mode.name = 'Right_Function_Mode'
		self._m_function_mode = FunctionModeComponent(self, self.m_function_update)
		self._m_function_mode.name = 'Main_Function_Mode'
		self._function_modes = [self._l_function_mode, self._r_function_mode, self._m_function_mode]
	


	"""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:
			if (self._shift_pressed_timer + self._shift_thresh) > self._timer:
				if(self._host._active_client != None):
					if(self._host.is_enabled() != True):
						self._monomod_mode.set_mode(1)
					else:
						self._monomod_mode.set_mode(0)
			else:
				self._shift_pressed_timer = self._timer % 256
			if(self._cntrlr != None):
				self._cntrlr._monohm_shift(2)
		else:
			if(self._cntrlr != None):
				self._cntrlr._monohm_shift(0)
	

	"""shift/zoom methods"""
	def deassign_matrix(self):
		self._session_zoom.set_button_matrix(None)
		self._session_zoom2.set_button_matrix(None)
		self._session.set_stop_track_clip_buttons(None)
		self._session2.set_stop_track_clip_buttons(None)
		self._session_zoom_main.set_button_matrix(None)
		self._session_main.set_stop_track_clip_buttons(None)
		for column in range(4):
			self._mixer2.channel_strip(column).set_select_button(None)
			self._mixer2.return_strip(column).set_mute_button(None)
			self._mixer2.return_strip(column).set_solo_button(None)
			self._mixer2.return_strip(column).set_arm_button(None)
			self._mixer2.return_strip(column).set_crossfade_toggle(None)
			self._mixer2.return_strip(column).set_select_button(None)			#shouldn't this be somewhere else?
			self._mixer2.channel_strip(column).set_crossfade_toggle(None)
			self._mixer2.channel_strip(column).set_mute_button(None)
			self._mixer2.channel_strip(column).set_solo_button(None)
			self._mixer2.channel_strip(column).set_arm_button(None)
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(None)
				self._scene2[row].clip_slot(column).set_launch_button(None)
		for index in range(5):
			self._scene[index].set_launch_button(None)
			self._scene2[index].set_launch_button(None)
			self._scene_main[index].set_launch_button(None)
		self._session_zoom.set_nav_buttons(None, None, None, None)
		self._session_zoom2.set_nav_buttons(None, None, None, None)
		self._session_zoom_main.set_nav_buttons(None, None, None, None)
		self._session.set_track_bank_buttons(None, None)
		self._session.set_scene_bank_buttons(None, None)
		self._session2.set_track_bank_buttons(None, None)
		self._session2.set_scene_bank_buttons(None, None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
		for column in range(8):
			self._mixer.channel_strip(column).set_select_button(None)
			self._mixer.channel_strip(column).set_crossfade_toggle(None)
			self._mixer.channel_strip(column).set_mute_button(None)
			self._mixer.channel_strip(column).set_solo_button(None)
			self._mixer.channel_strip(column).set_arm_button(None)
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(None)
			for row in range(8):
				self._grid[column][row].set_channel(0)
				self._grid[column][row].release_parameter()
				self._grid[column][row].use_default_message()
				self._grid[column][row].set_enabled(True)
				self._grid[column][row].set_on_off_values(127, 0)
				self._grid[column][row].send_value(0, True)
		self._send_reset.set_buttons(tuple(None for index in range(4)))
	

	def zoom_off(self):
		for column in range(4):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene[row].clip_slot(column).set_launch_button(self._grid[column][row])
			if(self._r_function_mode._mode_index in range(0,3)):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.channel_strip(column).set_mute_button(self._grid[column + 4][5])
				self._grid[column + 4][6].set_on_value(ARM[self._rgb])
				self._mixer2.channel_strip(column).set_arm_button(self._grid[column + 4][6])
				for row in range(5):
					self._scene2[row].clip_slot(column).set_launch_button(self._grid[column + 4][row])
			elif(self._r_function_mode._mode_index is 3):
				self._grid[column + 4][5].set_on_value(MUTE[self._rgb])
				self._mixer2.return_strip(column).set_mute_button(self._grid[column + 4][5])
				for row in range(5):
					self._grid[column + 4][row].send_value(USER1_COLOR[self._rgb], True)
					self._grid[column + 4][row].set_channel(RIGHT_USER1_CHANNEL)
					self._grid[column + 4][row].set_identifier(RIGHT_USER1_MAP[column][row])
					self._grid[column + 4][row].set_enabled(False)	 #this has to happen for translate to work
				#self._session_zoom2.set_ignore_buttons(True)
		if(self._r_function_mode._mode_index is 0):
			for index in range(4):
				self._grid[index + 4][7].send_value(SEND_RESET[self._rgb], True)
			self._send_reset.set_buttons(tuple(self._grid[index + 4][7] for index in range(4)))
	

	def zoom_off_m(self):
		self.deassign_dials()
		for column in range(8):
			self._grid[column][5].set_on_value(MUTE[self._rgb])
			self._mixer.channel_strip(column).set_mute_button(self._grid[column][5])
			self._grid[column][6].set_on_value(ARM[self._rgb])
			self._mixer.channel_strip(column).set_arm_button(self._grid[column][6])
			for row in range(5):
				self._scene_main[row].clip_slot(column).set_launch_button(self._grid[column][row])
		#self._session_zoom.set_button_matrix(self._matrix)
	

	def zoom_left(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
			self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons2.append(self._grid[index + 4][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene[index].set_launch_button(self._grid[7][index])
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		self._session_zoom.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.assign_buttons(tuple(self._grid[index + 4][7] for index in range(4)), 4)
	

	def zoom_right(self):
		track_stop_buttons = []
		track_stop_buttons2 = []
		for index in range(4):
			self._grid[index][6].set_off_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_off_value(SCENE_LAUNCH[self._rgb])
			self._scene2[index].set_launch_button(self._grid[7][index])
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index + 4][6].set_off_value(TRACK_STOP[self._rgb])
				track_stop_buttons2.append(self._grid[index + 4][6])
			self._session2.set_stop_track_clip_buttons(tuple(track_stop_buttons2))
		self._session_zoom2.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.assign_buttons(tuple(self._grid[index][7] for index in range(4)), 0)
	

	def zoom_main(self):
		track_stop_buttons = []
		for index in range(8):
			self._grid[index][6].set_on_value(TRACK_STOP[self._rgb])
			track_stop_buttons.append(self._grid[index][6])
		for index in range(5):
			self._grid[7][index].set_on_value(SCENE_LAUNCH[self._rgb])
			self._scene_main[index].set_launch_button(self._grid[7][index])
		self._session_main.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session_zoom_main.set_button_matrix(self._matrix)
		self._grid[0][5].set_on_value(RECORD[self._rgb])
		self._transport.set_record_button(self._grid[0][5])
		self._grid[1][5].set_on_value(OVERDUB[self._rgb])
		self._transport.set_overdub_button(self._grid[1][5])
		self._grid[2][5].set_on_value(LOOP[self._rgb])
		self._transport.set_loop_button(self._grid[2][5])
		self._grid[3][5].set_on_value(STOP_ALL[self._rgb])	
		self._session.set_stop_all_clips_button(self._grid[3][5])
		for index in range(4):
			self._grid[index + 4][5].send_value(SEND_RESET[self._rgb], True)
		self._send_reset.set_buttons(tuple(self._grid[index + 4][5] for index in range(4)))
		for index in range(4):
			self._grid[index + 4][7].set_off_value(DEVICE_SELECT[self._rgb])
		self._device_selector.assign_buttons(tuple(self._grid[index + 4][7] for index in range(4)), 4)
	


	"""function mode callbacks"""
	def l_function_update(self):
		mode = self._l_function_mode._mode_index
		#if(self._l_function_mode.is_enabled() is False):
		#	self._l_function_mode.set_mode_buttons(None)
		if(self._l_function_mode.is_enabled() is True):
			if(len(self._l_function_mode._modes_buttons) is 0):
				for index in range(4):
					self._mixer.channel_strip(index).set_select_button(None)
				buttons = []
				for index in range(4):
					buttons.append(self._grid[index][7]) 
				self._l_function_mode.set_mode_buttons(tuple(buttons))
			if(self._shift_mode._mode_index is 2):
				for index in range(4):
					if(mode != index):
						self._grid[index][7].turn_off()
					else:
						self._grid[index][7].turn_on()
		if(mode is 0):
			self.assign_device_dials()
			self.show_message('Mixer Split:Dials Device Mode')
		elif(mode is 1):
			self.assign_send_dials()
			self.show_message('Mixer Split:Dials Send Mode')
		elif(mode is 2):
			self.assign_split_volume_dials()
			self.show_message('Mixer Split:Dials Volume Mode')
		elif(mode is 3):
			self.assign_user_dials()
			self.show_message('Mixer Split:Dials User Map Mode')
	

	def r_function_update(self):
		mode = self._r_function_mode._mode_index
		#if(self._r_function_mode.is_enabled() is False):
		#	self._r_function_mode.set_mode_buttons(None)
			#self._session2.set_show_highlight(False)
			#self._session._highlighting_callback(self._session._track_offset, self._session._scene_offset, 4, 5, 1)
		if(self._r_function_mode.is_enabled() is True):
			if(len(self._r_function_mode._modes_buttons) is 0):
				for index in range(4):
					self._mixer2.channel_strip(index).set_select_button(None)
				buttons = []
				for index in range(4):
					buttons.append(self._grid[index + 4][7]) 
				self._r_function_mode.set_mode_buttons(tuple(buttons))
			if(self._shift_mode._mode_index is 3):
				for index in range(4):
					if(mode != index):
						self._grid[index + 4][7].turn_off()
					else:
						self._grid[index + 4][7].turn_on()
		self._session2.set_offsets(int(self._mem[mode]), self._session2._scene_offset)
		self.show_message('Mixer Split: Track Offset' + str(RIGHT_MODE_OFFSETS[mode]))
	

	def m_function_update(self):
		mode = self._m_function_mode._mode_index
		#if(self._m_function_mode.is_enabled() is False):
		#	self._m_function_mode.set_mode_buttons(None)
			#self._session.set_show_highlight(False)
			#self._session2.set_show_highlight(False)
			#self._session_main._highlighting_callback(self._session_main._track_offset, self._session_main._scene_offset, 8, 5, 1)
		if(self._m_function_mode.is_enabled() is True):
			if(len(self._m_function_mode._modes_buttons) is 0):
				for index in range(8):
					self._mixer.channel_strip(index).set_select_button(None)
				buttons = []
				for index in range(4):
					buttons.append(self._grid[index][7]) 
				self._m_function_mode.set_mode_buttons(tuple(buttons))
			if(self._shift_mode._mode_index is 4):
				for index in range(4):
					if(mode != index):
						self._grid[index][7].turn_off()
					else:
						self._grid[index][7].turn_on()
		if(mode is 0):
			self.assign_device_dials()
			self.show_message('Mixer Linked:Dials Device Mode')
		elif(mode is 1):
			self.assign_send_dials()
			self.show_message('Mixer Linked:Dials Send Mode')
		elif(mode is 2):
			self.assign_volume_dials()
			self.show_message('Mixer Linked:Dials Volume Mode')
		elif(mode is 3):
			self.assign_user_dials()
			self.show_message('Mixer Linked:Dials User Map Mode')
	

	def shift_update(self):
		self._clutch_device_selection = True
		#self.allow_updates(False)
		#if(not self._in_build_midi_map):
		#	self.set_suppress_rebuild_requests(True)
		self.deassign_channel_select_buttons()
		self.deassign_matrix()
		self.deassign_menu()
		if(self._monomod_mode._mode_index is 0):		#if monomod is not on
			if(self._shift_mode._mode_index is 0):							#if no shift is pressed
				self._shift_mode._mode_toggle1.turn_off()
				self._shift_mode._mode_toggle2.turn_off()
				if(self.split_mixer() is False):
					self.set_split_mixer(True)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_channel_select_buttons()
				#self._recalculate_selected_channel()
				#self.assign_transport_to_menu()
				self.assign_session_nav_to_menu()
				self.l_function_update()
				self.r_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session)
				self._session._do_show_highlight()	
				#self._session.set_show_highlight(True)
			elif(self._shift_mode._mode_index is 1):						#if no shift is pressed, but mixer is linked
				self._shift_mode._mode_toggle1.turn_on()
				self._shift_mode._mode_toggle2.turn_on()
				if(self.split_mixer() is True):
					self.set_split_mixer(False)
				for zoom in self._zooms:
					zoom._on_zoom_value(0)
				self.zoom_off_m()
				self._device_selector.set_enabled(False)
				for mode in self._function_modes:
					mode.set_enabled(False)
				self.assign_main_channel_select_buttons()
				self.assign_session_main_nav_to_menu()
				self.m_function_update()
				self.assign_crossfader()
				self.set_highlighting_session_component(self._session_main)
				self._session_main._do_show_highlight()
			elif(self._shift_mode._mode_index > 1):						#if a shift is pressed
				self.assign_device_nav_to_menu()
				self.deassign_channel_select_buttons()
				if(self._shift_mode._mode_index is 2):					#if shift left
					self._shift_mode._mode_toggle1.turn_on()
					self.zoom_left()
					self._session_zoom._on_zoom_value(1)
					self._session.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._l_function_mode.set_enabled(True)
					self.set_highlighting_session_component(self._session)
					self._session._do_show_highlight()
				elif(self._shift_mode._mode_index is 3):				#if shift right
					self._shift_mode._mode_toggle2.turn_on()
					self.zoom_right()
					self._session_zoom2._on_zoom_value(1)
					self._session2.set_enabled(True)  #this is a workaround so that the stop buttons still function
					self._r_function_mode.set_enabled(True)
					self.assign_master_fader()
					if(self._r_function_mode._mode_index < 4):
						self.set_highlighting_session_component(self._session2)
						self._session2._do_show_highlight()
				elif(self._shift_mode._mode_index is 4):				#if either shift pressed while mixer is linked
					self._shift_mode._mode_toggle1.turn_on()
					self._shift_mode._mode_toggle2.turn_on()
					self.zoom_main()
					self._session_zoom_main._on_zoom_value(1)
					self._session_main.set_enabled(True) #this is a workaround so that the stop buttons still function
					self._m_function_mode.set_enabled(True)
					self.assign_master_fader()
					self.set_highlighting_session_component(self._session_main)
					self._session_main._do_show_highlight()
				self._device_selector.set_enabled(True)
		self.allow_updates(True)
		#self.set_suppress_rebuild_requests(False)
		self._clutch_device_selection = False
		if(self._shift_mode._mode_index < 2):
			self._monobridge._send('touch', 'off')
		else:
			self._monobridge._send('touch', 'on')
	

	def monomod_mode_update(self):
		if (self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._livid.turn_off()
			self._shift_mode.set_mode_toggle(self._shift_l, self._shift_r)
			self._shift_mode.update()
			#self._session._reassign_scenes()
			
		elif(self._monomod_mode._mode_index == 1):
			self._livid.turn_on()
			self.deassign_matrix()
			self.deassign_menu()
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			self._host._set_nav_buttons(self._menu[0:4])
			self._host._set_lock_button(self._shift_l)
			self._host._set_alt_button(self._shift_r)
			self._host._set_shift_button(self._livid)
			self._shift_mode.set_mode_toggle(None, None)
			self._host.set_enabled(True)
			self._shift_mode.update()
			#self.show_message('Monomod grid enabled')
	

	"""left control management methods"""
	def deassign_dials(self):
		for index in range(8):
			self._dial[index].use_default_message()
			self._dial[index].release_parameter()
			self._dial[index].set_enabled(True)
		if(self._device._parameter_controls != None):
			for control in self._device._parameter_controls:
				control.release_parameter()
			self._device._parameter_controls = None
		self._mixer.selected_strip().set_send_controls(None)
		self._mixer.selected_strip().set_volume_control(None)
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(None)
			self._mixer.channel_strip(track+4).set_volume_control(None)
			self._mixer2.channel_strip(track).set_volume_control(None)
			self._mixer2.return_strip(track).set_volume_control(None)
	

	def assign_device_dials(self):
		self._ohm_type = OHM_TYPE[0]
		self._ohm = OHM_VALUE[0]
		self.deassign_dials()
		self._device.set_enabled(True)
		device_param_controls = []
		for index in range(8):
			device_param_controls.append(self._dial[index])
		self._device.set_parameter_controls(tuple(device_param_controls))
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_send_dials(self):
		self._ohm_type = OHM_TYPE[1]
		self._ohm = OHM_VALUE[1]
		self.deassign_dials()
		dials = []
		for index in range(4):
			dials.append(self._dial[index])
		for index in range(4):
			if(self._mixer2.return_strip(index)):
				self._mixer2.return_strip(index).set_volume_control(self._dial[index + 4])
		self._mixer.selected_strip().set_send_controls(tuple(dials))
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(8):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_split_volume_dials(self):
		self._ohm_type = OHM_TYPE[2]
		self._ohm = OHM_VALUE[2]
		self.deassign_dials()
		for track in range(4):
			self._mixer.channel_strip(track).set_volume_control(self._dial[track])
			self._mixer2.channel_strip(track).set_volume_control(self._dial[track+4])
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	

	def assign_user_dials(self):
		self._ohm_type = OHM_TYPE[3]
		self._ohm = OHM_VALUE[3]
		self.deassign_dials()
		for index in range(8):
			self._dial[index].set_channel(L_USER_DIAL_CHAN)
			self._dial[index].set_identifier(L_USER_DIAL_MAP[index])
			self._dial[index].set_enabled(False)
		self._mixer.selected_strip().set_volume_control(self._fader[0])
	


	"""menu button management methods"""
	def deassign_menu(self):
		self._device.set_lock_button(None)
		self._device.set_on_off_button(None)
		self._device_navigator.set_device_nav_buttons(None, None)	
		self._device.set_bank_nav_buttons(None, None)
		self._transport.set_play_button(None)	
		self._transport.set_record_button(None) 
		self._transport.set_stop_button(None)
		self._transport.set_loop_button(None)	
		self._transport.set_overdub_button(None)	
		self._session.set_stop_all_clips_button(None)
		self._transport.set_play_button(None)	
		self._transport.set_stop_button(None)
		self._session_main.set_track_bank_buttons(None, None)
		self._session_main.set_scene_bank_buttons(None, None)
	

	def assign_device_nav_to_menu(self):
		self._device_navigator.set_device_nav_buttons(self._menu[2], self._menu[3]) 
		self._device.set_bank_nav_buttons(self._menu[0], self._menu[1])
	

	def assign_transport_to_menu(self):
		self._transport.set_play_button(self._menu[0])	
		self._transport.set_record_button(self._menu[2])
		self._transport.set_stop_button(self._menu[1])
		session.set_stop_all_clips_button(self._menu[3])
	

	def assign_session_nav_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_monomod_shift_to_menu(self):
		self._device_navigator.set_device_nav_buttons(self._menu[3], self._menu[2]) 
		self._device.set_bank_nav_buttons(self._menu[1], self._menu[0])
	

	def assign_session_bank_to_menu(self):
		self._session.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session2_bank_to_menu(self):
		self._session2.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session2.set_scene_bank_buttons(self._menu[1], self._menu[0])
	

	def assign_session_main_nav_to_menu(self):
		self._session_main.set_track_bank_buttons(self._menu[3], self._menu[2])
		self._session_main.set_scene_bank_buttons(self._menu[1], self._menu[0])
	


	"""channel selection management methods"""
	def deassign_channel_select_buttons(self):
		for index in range(8):
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(None)
			self._grid[index][7].release_parameter()
		for index in range(4):
			self._mixer2.channel_strip(index).set_select_button(None)
			self._mixer2.return_strip(index).set_select_button(None)
			self._mixer2.master_strip().set_select_button(None)
			self._grid[index + 4][7].release_parameter()
	

	def assign_channel_select_buttons(self):
		for index in range(4):
			#if(self._mixer.channel_strip(index)):
			self._grid[index][7].set_on_off_values(127, 0)
			self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
		if(self._r_function_mode._mode_index < 3):
			for index in range(4):
				self._grid[index][7].set_on_off_values(127, 0)
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])	
		else:
			for index in range(4):
				self._grid[index][7].set_on_off_values(1, 0)
				self._mixer2.return_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_return_select_buttons(self):
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0) 
			if(self._mixer.channel_strip(index)):
				self._grid[index + 4][7].set_on_value(1)
				self._mixer.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_l_channel_select_buttons(self):
		self._mixer.set_select_buttons(None, None)
		self._session.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_r_channel_select_buttons(self):
		self._mixer2.set_select_buttons(None, None)
		self._session2.set_select_buttons(None, None)
		for index in range(4):
			self._grid[index + 4][7].set_off_value(0)
			if(self._mixer2.channel_strip(index)):
				self._mixer2.channel_strip(index).set_select_button(self._grid[index + 4][7])
	

	def assign_main_channel_select_buttons(self):
		for index in range(8):
			self._grid[index][7].set_off_value(0)
			if(self._mixer.channel_strip(index)):
				self._grid[index][7].set_on_value(127)
				self._mixer.channel_strip(index).set_select_button(self._grid[index][7])
	

	def assign_master_fader(self):
		self._mixer.set_crossfader_control(None)
		self._mixer.master_strip().set_volume_control(self._fader[1])
	

	def assign_crossfader(self):
		self._mixer.master_strip().set_volume_control(None)
		self._mixer.set_crossfader_control(self._fader[1])
	


	"""called on timer"""
	def update_display(self):
		super(BlockMod, self).update_display()
		if(self._timer == 0):
			self._shift_pressed_timer = -12
	

	def strobe(self):
		if(self._ohm_type != 'static'):
			if(self._ohm_type is 'pulse'):
				self._ohm = int(math.fabs(((self._timer * 8) % 64) -32) +32)
			if(self._ohm_type is 'up'):
				self._ohm = int(((self._timer * 4) % 64) + 16)
			if(self._ohm_type is 'down'):
				self._ohm = int(math.fabs(int(((self._timer * 4) % 64) - 64)) + 16)
		self._send_midi(tuple([176, 63, int(self._ohm)]))
		self._send_midi(tuple([176, 31, int(self._ohm)]))	
	

	def handle_sysex(self, midi_bytes):
		pass
	

	def _on_session_offset_changes(self):
		if self._r_function_mode._mode_index in range(0,4):
			self._mem[int(self._r_function_mode._mode_index)] = self._session2.track_offset()
	



#	a