Пример #1
0
class MainSelectorComponent(ModeSelectorComponent):
    " CLASS THAT REASSIGNS THE BUTTON ON THE LAUNCHPAD TO DIFFERENT FUNCTIONS "

    " INIT "

    def __init__(self, matrix, top_buttons, side_buttons, config_button):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._session = SpecialSessionComponent(self, len(self.song().tracks),
                                                matrix.height(), side_buttons)
        self._session.name = "Session_Control"
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._all_buttons = []
        for button in (self._side_buttons + self._nav_buttons):
            self._all_buttons.append(button)
        self._sub_modes = SpecialMixerSelectorComponent(
            matrix, side_buttons, self._session)
        self._sub_modes.name = "Mixer_Modes"
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])
        # mixer-session hack
        self._buttons_for_mixer = []
        for button in (self._side_buttons[5:]):
            self._buttons_for_mixer.append(button)
        for scene_index in range(self._matrix.height()):
            for track_index in range(self._matrix.width()):
                if scene_index > SESSION_HEIGHT_FOR_MIXER:
                    self._buttons_for_mixer.append(
                        self._matrix.get_button(track_index, scene_index))

    " DISCONNECT "

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)
        self._session = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)
        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        self._buttons_for_mixer = None
        ModeSelectorComponent.disconnect(self)

    " GET SESSION COMPONENT "

    def session_component(self):
        return self._session

    " SET THE MODE BUTTONS "

    def set_modes_buttons(self, buttons):
        assert ((buttons == None)
                or (isinstance(buttons, tuple) or
                    (len(buttons) == self.number_of_modes())))
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)
        self._modes_buttons = []
        if (buttons != None):
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)
        self.set_mode(0)

    " GET AMOUNT OF MODES "

    def number_of_modes(self):
        return 4

    " CHANGE CALLBACK "

    def on_enabled_changed(self):
        self.update()

    " SET THE MODE "

    def set_mode(self, mode):
        assert (mode in range(self.number_of_modes()))
        if ((self._mode_index != mode) or (mode == 3) or True):
            self._mode_index = mode
            self.update()

    " UPDATE MODE BUTTONS "

    def _update_mode_buttons(self):
        for index in range(4):
            if (index == self._mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    " SET CHANNEL FOR THE CURRONT MODE "

    def channel_for_current_mode(self):
        #trying to keep
        if self._mode_index == 0:
            return 0
        elif self._mode_index == 1:
            new_channel = 4  #user 1
        elif self._mode_index == 2:
            new_channel = 5  #user 2
        elif self._mode_index == 3:
            new_channel = 6 + self._sub_modes.mode()  #mixer modes
        return new_channel

    " UPDATE THE SHIT "

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():
            self._update_mode_buttons()
            #update matrix and side buttons
            for scene_index in range(self._matrix.height()):
                #update scene button
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(self._matrix.width()):
                    #update matrix
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)
            for button in self._nav_buttons:
                button.set_enabled(True)
            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = (self._mode_index == 1)

            if (self._mode_index == 0):
                #session
                self._setup_mixer((not as_active))
                self._setup_session(as_active, as_enabled, False)
            elif (self._mode_index == 1):
                #user mode 1
                self._setup_mixer((not as_active))
                self._setup_session((not as_active), (not as_enabled), False)
                self._setup_user1(True, True, True)
            elif (self._mode_index == 2):
                #user mode 2
                self._setup_mixer((not as_active))
                self._setup_session((not as_active), (not as_enabled), False)
                self._setup_user2(release_buttons)
            elif (self._mode_index == 3):
                #mixer
                self._setup_session((as_active), as_enabled, True)
                self._setup_mixer(as_active)
            else:
                assert False
            self._session.set_allow_update(True)
            self._update_control_channels()

    " UPDATE THE CHANNELS OF THE BUTTONS IN THE USER MODES.. "

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        if self._mode_index == 3:
            # skip the upper part of the matrix and buttons
            for button in self._buttons_for_mixer:
                button.set_channel(new_channel)
                button.set_force_next_value()
        else:
            for button in self._all_buttons:
                button.set_channel(new_channel)
                button.set_force_next_value()

    " SETUP THE SESSION "

    def _setup_session(self, as_active, as_enabled, for_mixer):
        #log("setup_session (active: " + str(as_active) + ", enabled: " + str(as_enabled) + ", forMixer: " + str(for_mixer) + ")")
        assert isinstance(as_active, type(False))
        assert isinstance(as_enabled, type(False))
        assert isinstance(for_mixer, type(False))
        # --------------------------------------------------------------------- nav button color
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)
        # --------------------------------------------------------------------- matrix
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            if for_mixer:
                if scene_index <= SESSION_HEIGHT_FOR_MIXER:
                    scene_button = self._side_buttons[scene_index]
                    scene_button.set_on_off_values(127, GREEN_THIRD)
                    scene.set_launch_button(scene_button)
                else:
                    scene.set_launch_button(None)
            elif as_active and (not for_mixer):
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, GREEN_THIRD)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            # SLOT BUTTONS
            button_index = 0
            for track_index in range(len(self.song().tracks)):
                if self.song().tracks[track_index].is_foldable:
                    if button_index < GROUPS_CONSIDERED:
                        if for_mixer:
                            if scene_index <= SESSION_HEIGHT_FOR_MIXER:
                                button = self._matrix.get_button(
                                    button_index, scene_index)
                                button.set_on_off_values(127, LED_OFF)
                                scene.clip_slot(track_index).set_launch_button(
                                    button)
                            else:
                                scene.clip_slot(track_index).set_launch_button(
                                    None)
                        elif as_active and (not for_mixer):
                            button = self._matrix.get_button(
                                button_index, scene_index)
                            button.set_on_off_values(127, LED_OFF)
                            scene.clip_slot(track_index).set_launch_button(
                                button)
                        else:
                            scene.clip_slot(track_index).set_launch_button(
                                None)
                        button_index = button_index + 1
                else:
                    scene.clip_slot(track_index).set_launch_button(None)
        # --------------------------------------------------------------------- nav buttons
        if as_enabled or for_mixer:
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_scene_bank_buttons(None, None)

    " SETUP THE MIXER "

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        self._sub_modes.set_enabled(as_active)

    " SETUP USER 1 "

    def _setup_user1(self,
                     release_matrix=True,
                     release_side_buttons=True,
                     release_nav_buttons=True):
        for scene_index in range(8):
            if (release_side_buttons):
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene_button.turn_off()
                scene_button.set_enabled((not release_side_buttons))
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))
        for button in self._nav_buttons:
            if (release_nav_buttons):
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_nav_buttons))
        if release_matrix:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    " SETUP USER 2 "

    def _setup_user2(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled((not release_buttons))
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_buttons))
        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled((not release_buttons))
        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    " INIT THE SESSION "

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        # SCENES
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = ("Scene_" + str(scene_index))
            # SLOTS
            button_index = 0
            for track_index in range(len(self.song().tracks)):
                if button_index < GROUPS_CONSIDERED:
                    if self.song().tracks[track_index].is_foldable:
                        clip_slot = scene.clip_slot(track_index)
                        clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                        clip_slot.set_triggered_to_record_value(RED_BLINK)
                        clip_slot.set_stopped_value(AMBER_FULL)
                        clip_slot.set_started_value(GREEN_FULL)
                        clip_slot.set_recording_value(RED_FULL)
                        clip_slot.name = ((str(track_index) + "_Clip_Slot_") +
                                          str(scene_index))
                        self._all_buttons.append(
                            self._matrix.get_button(button_index, scene_index))
                        button_index = button_index + 1
Пример #2
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button, parent):
        assert isinstance(matrix, ButtonMatrixElement)
        assert (matrix.width() == 8) and (matrix.height() == 8)
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._parent = parent
        self._session = SpecialSessionComponent(matrix.width(), matrix.height())
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = "Session_Control"
        self._zooming.name = "Session_Overview"
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
        self._sub_modes.name = "Mixer_Modes"
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._stepseq = StepSequencerComponent(self, self._matrix, self._side_buttons, self._nav_buttons)
        self._quick_mix = None  # QuickMixerComponent(self._nav_buttons,self._side_buttons,self)
        self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self._mode_index = 0
        self._previous_mode_index = -1
        self._sub_mode_index = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_index[index] = 0
        self.set_mode_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def _update_mode(self):
        mode = self._modes_heap[-1][0]
        assert mode in range(self.number_of_modes())
        # self.log_message(str(mode))
        if self._mode_index == mode:
            if self._mode_index == 1:
                # user mode 1 and device controller
                self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index] + 1) % 2
                self.update()
            elif self._mode_index == 2:
                # user mode 2  and step sequencer
                self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index] + 1) % 3
                self.update()
            elif self._mode_index == 3:
                self.update()
            else:
                self._sub_mode_index[self._mode_index] = 0
            self._previous_mode_index = self._mode_index
        else:
            self._mode_index = mode
            self.update()

    def set_mode(self, mode):
        self._clean_heap()
        self._modes_heap = [(mode, None, None)]
        # if ((self._mode_index != mode) or (mode == 3) or True):
        # self._mode_index = mode
        # self._update_mode()
        # 	self.update()

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        for index in range(4):
            if self._sub_mode_index[index] == 0:
                self._modes_buttons[index].set_on_off_values(AMBER_FULL, AMBER_THIRD)
            if self._sub_mode_index[index] == 1:
                self._modes_buttons[index].set_on_off_values(GREEN_FULL, GREEN_THIRD)
            if self._sub_mode_index[index] == 2:
                self._modes_buttons[index].set_on_off_values(RED_FULL, RED_THIRD)

            if index == self._mode_index:
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def channel_for_current_mode(self):
        # trying to keep
        if self._mode_index == 0:
            return 0
        elif self._mode_index == 1:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 4  # user 1
            else:
                new_channel = 1  # device ctrl
        elif self._mode_index == 2:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 5  # user 2
            else:
                new_channel = 1 + self._sub_mode_index[self._mode_index]  # step seq
        elif self._mode_index == 3:  # mixer modes
            new_channel = 6 + self._sub_modes.mode()
            # if (new_channel > 0):
            # 	new_channel += 3
        return new_channel

    def update(self):
        assert self._modes_buttons != None
        if self.is_enabled():
            # for index in range(len(self._modes_buttons)):
            # 	self._modes_buttons[index].set_force_next_value()
            # 	if index == self._mode_index:
            # 		self._modes_buttons[index].turn_on()
            # 	else:
            # 		self._modes_buttons[index].turn_off()

            self._update_mode_buttons()

            # update matrix and side buttons
            for scene_index in range(8):
                # update scene button
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    # update matrix
                    self._matrix.get_button(track_index, scene_index).set_enabled(True)
            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = self._mode_index == 1
            if self._mode_index == 0:
                # session
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session(as_active, as_enabled)
            elif self._mode_index == 1:
                # user mode + device controller
                self._setup_mixer((not as_active))
                if self._sub_mode_index[self._mode_index] == 0:
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_device_controller((not as_active))
                    self._setup_session((not as_active), (as_enabled))
                    self._setup_user1(True, True, True)
                else:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_step_sequencer(not as_active, 0)
                    self._setup_device_controller(as_active)

            elif self._mode_index == 2:
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                if self._sub_mode_index[self._mode_index] == 0:
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_user2(release_buttons)
                else:
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer(as_active, self._sub_mode_index[self._mode_index])

            elif self._mode_index == 3:
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session((not as_active), as_enabled)
                self._setup_mixer(as_active)
            else:
                assert False

            self._previous_mode_index = self._mode_index

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()

            # Update the channels of the buttons in the user modes..

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

                # matrix
        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

                    # zoom
        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(
                self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]
            )
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

            # nav buttons
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_quick_mix(self, as_active):
        if self._quick_mix != None:
            if as_active:
                for button in range(8):
                    self._side_buttons[button].set_enabled(True)
                self._quick_mix._is_active = True
                self._quick_mix.set_enabled(True)
            else:
                self._quick_mix._is_active = False
                self._quick_mix.set_enabled(False)

    def _setup_step_sequencer(self, as_active, mode):
        if self._stepseq != None:
            if self._stepseq._is_active != as_active or self._stepseq._mode != mode:
                if as_active:
                    self._stepseq._mode = mode
                    self._stepseq._force_update = True
                    self._stepseq._is_active = True
                    self._stepseq.set_enabled(True)
                    self._stepseq._on_notes_changed()
                    self._stepseq.update_buttons()
                    self._config_button.send_value(32)
                else:
                    self._stepseq._mode = 1
                    self._stepseq._is_active = False
                    self._stepseq.set_enabled(False)

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                # for button in range(8):
                # 	self._side_buttons[button].set_enabled(True)
                self._device_controller._is_active = True
                self._device_controller.set_enabled(True)
                self._device_controller.update()
                self._config_button.send_value(32)
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if as_active and self._sub_modes.is_enabled():
            self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user1(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True):

        for scene_index in range(8):
            if release_side_buttons:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene_button.turn_off()
                scene_button.set_enabled((not release_side_buttons))

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))

        for button in self._nav_buttons:
            if release_nav_buttons:
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_nav_buttons))

        if release_matrix:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _setup_user2(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = "Scene_" + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index)
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    def log_message(self, message):
        self._parent.log_message(message)
Пример #3
0
class MainSelectorComponent(ModeSelectorComponent):
    __module__ = __name__
    __doc__ = ' Class that reassigns the button on the launchpad to different functions '

    def __init__(self, matrix, top_buttons, side_buttons, config_button, knobs,
                 sliders, script):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._script = script
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        for scene in self._session._scenes:
            for slot in scene._clip_slots:
                slot._triggered_to_play_value = 4
                slot._triggered_to_record_value = 3
                slot._started_value = 2
                slot._recording_value = 1
                slot._stopped_value = 127
        self._zooming = SessionZoomingComponent(self._session)
        self._zooming._stopped_value = 127
        self._zooming._playing_value = 2
        self._zooming._selected_value = 1
        self._matrix = matrix
        self._knobs = knobs
        self._sliders = sliders
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._shift_button = top_buttons[5]
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in (self._side_buttons + self._nav_buttons):
            self._all_buttons.append(button)
        self._shift_pressed = 0
        self._shift_pressed_timer = 0
        self._last_normal_mode = 0
        self._shift_button = None
        self.set_shift_button(top_buttons[6])
        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:6])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

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

    def _shift_value(self, value):
        self._shift_pressed = int(value != 0)
        if self._shift_pressed > 0:
            if (self._shift_pressed_timer + 5) > self._script._timer:
                if (self._script._host.is_enabled() != True):
                    self.set_mode(4)
                else:
                    self._script.log_message('here')
                    self.set_mode(self._last_normal_mode)
            else:
                self._shift_pressed_timer = self._script._timer % 256
        if (self._script._host.is_enabled() != True):
            if (self._mode_index == 1):
                if value > 0:
                    self._session.set_track_bank_buttons(None, None)
                    self._session.set_scene_bank_buttons(None, None)
                    self._sub_modes.set_modes_buttons(self._nav_buttons)
                    self._sub_modes.update()
                else:
                    self._sub_modes.set_modes_buttons(None)
                    self._session.set_track_bank_buttons(
                        self._nav_buttons[3], self._nav_buttons[2])
                    self._session.set_scene_bank_buttons(
                        self._nav_buttons[1], self._nav_buttons[0])
                    self._sub_modes.update()
            elif (self._mode_index == 0):
                self._setup_session(True, True)
                self._session.update()

    def set_modes_buttons(self, buttons):
        assert ((buttons == None)
                or (isinstance(buttons, tuple) or (len(buttons) == 2)))
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if (buttons != None):
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)
        self.set_mode(0)

    def _mode_value(self, value, sender):
        assert (len(self._modes_buttons) > 0)
        assert isinstance(value, int)
        assert isinstance(sender, ButtonElement)
        assert (self._modes_buttons.count(sender) == 1)
        if self._script._host.is_enabled() != True:
            if ((value is not 0) or (not sender.is_momentary())):
                if self._shift_pressed > 0:
                    if self._modes_buttons.index(sender) == 0:
                        self.set_mode(2)
                    if self._modes_buttons.index(sender) == 1:
                        self.set_mode(3)
                else:
                    self._last_normal_mode = int(
                        self._modes_buttons.index(sender))
                    self.set_mode(self._modes_buttons.index(sender))
        else:
            pass

    def number_of_modes(self):
        return 5

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        assert (mode in range(self.number_of_modes()))
        if ((self._mode_index != mode) or (mode == 1)):
            self._mode_index = mode
            self.update()

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            for scene_index in range(8):
                for track_index in range(8):
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)

            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = (self._mode_index == 1)
            if (self._mode_index < 4):
                self._script._host.set_enabled(False)
                self._script._host._set_button_matrix(None)
                self._script._host._set_alt_button(None)
                self._script._host._set_shift_button(None)
                self._script._host._set_nav_buttons(None)
                if (self._mode_index == 0):  #session
                    self._setup_mixer((not as_active))
                    self._setup_session(as_active, as_enabled)
                elif (self._mode_index == 1):  #mixer
                    self._setup_session((not as_active), as_enabled)
                    self._setup_mixer(as_active)
                elif (self._mode_index == 2):  #user1
                    self._setup_session((not as_active), (not as_enabled))
                    self._setup_mixer((not as_active))
                    self._setup_user(release_buttons)
                elif (self._mode_index == 3):  #user2
                    self._setup_session((not as_active), (not as_enabled))
                    self._setup_mixer((not as_active))
                    self._setup_user(release_buttons)
            elif (self._mode_index == 4):  #monomodular
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_user(release_buttons)
                self._script._host._set_button_matrix(self._matrix)
                self._script._host._set_shift_button(self._shift_button)
                self._script._host._set_lock_button(self._modes_buttons[0])
                self._script._host._set_alt_button(self._modes_buttons[1])
                self._script._host._set_nav_buttons(self._nav_buttons)
                self._script._host.set_enabled(True)
            else:
                assert False
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
            #self._script.request_rebuild_midi_map()

    def _update_control_channels(self):
        if self._mode_index < 4:
            new_channel = (self._mode_index + self._sub_modes.mode())
            if (new_channel > 0):
                new_channel += 3
        else:
            new_channel = 15
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(127, 0)
            else:
                button.set_on_off_values(127, 0)

        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active and (self._shift_pressed == 1):
                scene_button = self._matrix.get_button(7, scene_index)
                scene_button.set_on_off_values(127, 0)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(SHIFT[self._shift_pressed]):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, 0)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled((not release_buttons))
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_buttons))

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled((not release_buttons))

        self._config_button.send_value(32)
        if release_buttons:
            self._config_button.send_value(2)

    def _init_session(self):
        self._session.set_stop_track_clip_value(3)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(1)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(4)
                clip_slot.set_triggered_to_record_value(3)
                clip_slot.set_stopped_value(127)
                clip_slot.set_started_value(2)
                clip_slot.set_recording_value(1)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(127)
        self._zooming.set_selected_value(1)
        self._zooming.set_playing_value(2)
Пример #4
0
class JAMP_alpha(ControlSurface):
    __doc__ = " Script for JAMP_alpha in APC emulation mode "

    _active_instances = []

    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in JAMP_alpha._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._note_map = []
            self._ctrl_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()

    def disconnect(self):
        self._note_map = None
        self._ctrl_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)

    def _do_combine(self):
        if self not in JAMP_alpha._active_instances:
            JAMP_alpha._active_instances.append(self)
            JAMP_alpha._combine_active_instances()

    def _do_uncombine(self):
        if ((self in JAMP_alpha._active_instances)
                and JAMP_alpha._active_instances.remove(self)):
            self._session.unlink()
            JAMP_alpha._combine_active_instances()

    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)

    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT],
                                             self._note_map[SESSIONLEFT])
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN],
                                             self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN],
                                         self._note_map[SCENEUP])
        self._scene_launch_buttons = [
            self._note_map[SCENELAUNCH[index]] for index in range(4)
        ]
        self._track_stop_buttons = [
            self._note_map[TRACKSTOP[index]] for index in range(4)
        ]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(4):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(4):
                button = self._note_map[CLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP],
                                           self._note_map[ZOOMDOWN],
                                           self._note_map[ZOOMLEFT],
                                           self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT],
                                       self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(
            self._ctrl_map[MASTERVOLUME])
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]],
                                     self._ctrl_map[TRACKSENDB[track]],
                                     self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        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])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT],
                                          self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(
            self._note_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(
            self._note_map[DETAILVIEW])
        detail_view_toggler.set_device_nav_buttons(
            self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT])

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP],
                                    self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._note_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD],
                                   self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN],
                                    self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(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)

    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (
                        col,
                        row,
                        DRUM_PADS[row * 4 + col],
                        PADCHANNEL,
                    )
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))

    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL,
                                   note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)
        self._note_map.append(
            None)  #add None to the end of the list, selectable with [-1]
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
Пример #5
0
class Serato(ControlSurface):

    def __init__(self, c_instance):
        publish_in_cs_list = True
        ControlSurface.__init__(self, c_instance, not publish_in_cs_list)
        self._device_selection_follows_track_selection = True
        with self.component_guard():
            self._matrix = None
            self._session = None
            self._mixer = None
            self._device = None
            self._scene_launch_buttons = None
            self._track_arm_buttons = None
            self._track_solo_buttons = None
            self._track_mute_buttons = None
            self._track_stop_buttons = None
            self._track_select_buttons = None
            self._device_on_off_button = None
            self._shift_button = None
            self._serato_interface = PySCAClipControl()
            self._serato_interface.PySCA_InitializeClipControl()
            self._setup_session_control()
            self._setup_mixer_control()
            self._setup_device_control()
            self._session.set_mixer(self._mixer)
            self.set_highlighting_session_component(self._session)
        return

    def disconnect(self):
        ControlSurface.disconnect(self)
        self._serato_interface.PySCA_DeinitializeClipControl()
        self._serato_interface = None
        return

    def connect_script_instances(self, instanciated_scripts):
        """ Called by the Application as soon as all scripts are initialized.
            You can connect yourself to other running scripts here, as we do it
            connect the extension modules (MackieControlXTs).
        """
        for control_surface in self._control_surfaces():
            control_surface_session = control_surface.highlighting_session_component()
            if control_surface_session:
                self._session.sync_to(control_surface_session)
                self._on_track_list_changed()
                break

    def build_midi_map(self, midi_map_handle):
        pass

    def update_display(self):
        ControlSurface.update_display(self)
        while self._serato_interface.PySCA_HasIncomingEvent():
            new_event = self._serato_interface.PySCA_GetIncomingEvent()
            if not self._handle_session_event(new_event):
                if not self._handle_mixer_event(new_event):
                    if not self._handle_device_event(new_event):
                        print 'Unhandled Event: ' + str(new_event)

    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(NUM_TRACKS, NUM_SCENES)
        self._session.set_serato_interface(self._serato_interface)
        self._matrix = ButtonMatrixElement()
        self._scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_SCENES) ]
        self._track_stop_buttons = [ ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_TRACKS) ]
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0)
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        for scene_index in range(NUM_SCENES):
            scene = self._session.scene(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_index(scene_index)
            scene.set_serato_interface(self._serato_interface)
            for track_index in range(NUM_TRACKS):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0)
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_launch_button(button)
                clip_slot.set_serato_interface(self._serato_interface)

            self._matrix.add_row(tuple(button_row))

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(NUM_TRACKS)
        self._mixer.set_serato_interface(self._serato_interface)
        self._mixer.master_strip().set_serato_interface(self._serato_interface)
        self._track_arm_buttons = []
        self._track_solo_buttons = []
        self._track_mute_buttons = []
        self._track_select_buttons = []
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0)
        for track in range(NUM_TRACKS):
            strip = self._mixer.channel_strip(track)
            strip.set_serato_interface(self._serato_interface)
            self._track_arm_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            self._track_solo_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            self._track_mute_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            self._track_select_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            strip.set_arm_button(self._track_arm_buttons[-1])
            strip.set_solo_button(self._track_solo_buttons[-1])
            strip.set_mute_button(self._track_mute_buttons[-1])
            strip.set_select_button(self._track_select_buttons[-1])
            strip.set_shift_button(self._shift_button)

    def _setup_device_control(self):
        is_momentary = True
        self._device_on_off_button = ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)
        self._device = SpecialDeviceComponent()
        self._device.set_serato_interface(self._serato_interface)
        self._device.set_parameter_controls(tuple([ SliderElement(MIDI_CC_TYPE, 0, 0) for index in range(NUM_PARAMS) ]))
        self._device.set_on_off_button(self._device_on_off_button)
        self.set_device_component(self._device)

    def _handle_session_event(self, event):
        result = False
        if event.type in CLIP_EVENTS:
            value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventClipPlayedDown)
            track_index = event.key1 - 1
            scene_index = event.key2 - 1
            if track_index in range(NUM_TRACKS) and scene_index in range(NUM_SCENES):
                self._matrix.get_button(track_index, scene_index).receive_value(value)
            result = True
        elif event.type in SCENE_EVENTS:
            value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventScenePlayedDown)
            scene_index = event.key1 - 1
            if scene_index in range(NUM_SCENES):
                self._scene_launch_buttons[scene_index].receive_value(value)
            result = True
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixSizeChanged:
            new_width = event.key1
            new_height = event.key2
            self._session.set_size(new_width, new_height)
            result = True
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixOffsetChanged:
            x_increment = event.key1
            y_increment = event.key2
            self._session.move_by(x_increment, y_increment)
            result = True
        return result

    def _handle_mixer_event(self, event):
        result = True
        track_index = event.key1 - 1
        value = event.key2
        if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackMasterGainChange:
            self._mixer.master_strip().set_track_volume(fixed_value(value))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackStopped:
            self.song().stop_all_clips()
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackSelect:
            self.song().view.selected_track = self.song().master_track
        else:
            result = track_index in range(NUM_TRACKS) and self._handle_strip_event(event)
        return result

    def _handle_strip_event(self, event):
        result = True
        track_index = event.key1 - 1
        value = event.key2
        if value == 0:
            self._shift_button.receive_value(127)
        if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSolo:
            self._track_solo_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackRecord:
            self._track_arm_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackActive:
            self._track_mute_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackStopped:
            self._track_stop_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSelect:
            self._track_select_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackGainChange:
            self._mixer.channel_strip(track_index).set_track_volume(fixed_value(value))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendAChange:
            self._mixer.channel_strip(track_index).set_send(0, fixed_value(value))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendBChange:
            self._mixer.channel_strip(track_index).set_send(1, fixed_value(value))
        else:
            result = False
        self._shift_button.receive_value(0)
        return result

    def _handle_device_event(self, event):
        result = True
        if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceValueChanged:
            self._device.set_parameter_value(event.key1 - 1, fixed_value(event.key2))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceActivate:
            self._device_on_off_button.receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceFocusMove:
            self._move_device_focus(event.key1)
        else:
            result = False
        return result

    def _move_device_focus(self, increment):
        if not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain'):
            self.application().view.show_view('Detail')
            self.application().view.show_view('Detail/DeviceChain')
        else:
            modifier_pressed = True
            direction = Live.Application.Application.View.NavDirection.left
            if increment > 0:
                direction = Live.Application.Application.View.NavDirection.right
            self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed)
class MainSelectorComponent(ModeSelectorComponent):

	""" Class that reassigns the button on the launchpad to different functions """

	#def log(self, message):
	#	self._control_surface.log_message((' ' + message + ' ').center(50, '='))

	def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, control_surface):
		#verify matrix dimentions
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self) #super constructor
		
		#inject ControlSurface and OSD components (M4L)
		self._osd = osd
		self._control_surface = control_surface

		#initialize index variables
		self._mode_index = 0 #Inherited from parent
		self._main_mode_index = 0 #LP original modes
		self._sub_mode_list = [0, 0, 0, 0]
		for index in range(4):
			self._sub_mode_list[index] = 0
		self.set_mode_buttons(top_buttons[4:])
			
		if Settings.SESSION__STOP_BUTTONS:#session with bottom stop buttons
			clip_stop_buttons = [] 
			for column in range(8):
				clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1))
			self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self._control_surface, self)
		else:#no stop buttons
			self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self._control_surface, self)
			
		#initialize _session variables	
		self._session.set_osd(self._osd)
		self._session.name = 'Session_Control'
		
		#initialize _zooming variables	
		self._zooming = DeprecatedSessionZoomingComponent(self._session, enable_skinning = True)
		self._zooming.name = 'Session_Overview'
		self._zooming.set_empty_value("Default.Button.Off")
		
		self._matrix = matrix
		self._side_buttons = side_buttons#launch buttons
		self._nav_buttons = top_buttons[:4]#arrow buttons
		self._config_button = config_button#used to reset launchpad
		
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		#SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm)
		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, self._control_surface)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes._mixer.set_osd(self._osd)
		self._sub_modes.set_update_callback(self._update_control_channels)

		#User2 stepSequencer (Drum)
		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface)
		self._stepseq.set_osd(self._osd)
		
		#User2 stepSequencer (Melodic)
		self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface)
		self._stepseq2.set_osd(self._osd)
		
		#User1 Instrument controller (Scale)
		self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self._control_surface)
		self._instrument_controller.set_osd(self._osd)
		#self._instrument_controller = None
		
		#User1 Device controller (Fx or Instrument parameters)
		self._device_controller = DeviceComponent(control_surface = self._control_surface, matrix = self._matrix, side_buttons = self._side_buttons, top_buttons =  self._nav_buttons)
		self._device_controller.set_osd(self._osd)

		self._init_session()
		self._all_buttons = tuple(self._all_buttons)

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)

	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0] #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer) 

		assert mode in range(self.number_of_modes()) # 8 for this script
		if self._main_mode_index == mode:
			if self._main_mode_index == 1: #user mode 1 and device controller and instrument mode
				self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 2: #user mode 2  and step sequencer
				self._sub_mode_list[self._main_mode_index] = (self._sub_mode_list[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 3: #Mixer mode
				self.update()
			else: #Session mode
				self._sub_mode_list[self._main_mode_index] = 0
				self._mode_index = 0

		else:
			self._main_mode_index = mode
			self.update()

	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		# if ((self.__main_mode_index != mode) or (mode == 3) or True):
		# 	self._main_mode_index = mode
		# 	self._update_mode()
		# 	self.update()

	def number_of_modes(self):
		return 1 + 3 + 3 + 1

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		self._modes_buttons[0].set_on_off_values("Mode.Session.On","Mode.Session.Off")
		self._modes_buttons[3].set_on_off_values("Mode.Mixer.On","Mode.Mixer.Off")
		mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]])
		mode2 = self.getSkinName(Settings.USER_MODES[3 + self._sub_mode_list[2]])
		self._modes_buttons[1].set_on_off_values("Mode."+mode1+".On","Mode."+mode1+".Off")
		self._modes_buttons[2].set_on_off_values("Mode."+mode2+".On","Mode."+mode2+".Off")
		
		for index in range(4):
			if (index == self._main_mode_index):
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()
		
	def getSkinName(self, user2Mode):
		if user2Mode=="instrument":
			user2Mode = "Note"
		if user2Mode=="device":
			user2Mode = "Device"
		if user2Mode=="user 1":
			user2Mode = "User"
		if user2Mode=="user 2":
			user2Mode = "User2"
		if user2Mode=="drum stepseq":
			user2Mode = "StepSequencer"
		if user2Mode=="melodic stepseq":
			user2Mode = "StepSequencer2"
		return user2Mode
		
	def channel_for_current_mode(self):
		# in this code, midi channels start at 0.
		# so channels range from 0 - 15.
		# mapping to 1-16 in the real world

		if self._main_mode_index == 0:
			new_channel = 0  # session

		elif self._main_mode_index == 1:
			if self._sub_mode_list[self._main_mode_index] == 0:
				new_channel = 11  # instrument controller
				# instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
				if self._instrument_controller != None:
					self._instrument_controller.base_channel = new_channel
			elif self._sub_mode_list[self._main_mode_index] == 1:
				new_channel = 3  # device controller
			elif self._sub_mode_list[self._main_mode_index] == 2:
				new_channel = 4  # plain user mode 1

		elif self._main_mode_index == 2:
			if self._sub_mode_list[self._main_mode_index] == 0:
				new_channel = 1  # step seq
			elif self._sub_mode_list[self._main_mode_index] == 1:
				new_channel = 2  # melodic step seq
			elif self._sub_mode_list[self._main_mode_index] == 2:
				new_channel = 5  # plain user mode 2

		elif self._main_mode_index == 3:  # mixer modes
			# mixer uses base channel 7 and the 4 next ones.
			new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

		return new_channel

				
	
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40) #Set LP double buffering mode (investigate this)
			self._config_button.send_value(1) #Set LP X-Y layout grid mapping mode

			if self._main_mode_index == 0:
				# session
				self._control_surface.show_message("SESSION MODE" )
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				self._mode_index = 0

			elif self._main_mode_index == 1 or self._main_mode_index == 2:
				self._setup_sub_mode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_list[self._main_mode_index] ] )

			elif self._main_mode_index == 3:
				# mixer
				self._control_surface.show_message("MIXER MODE")
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
				self._mode_index = 3
			else:
				assert False

			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
		
	def _setup_sub_mode(self, mode):
		as_active = True
		as_enabled = True
		if mode == "instrument":
			self._control_surface.show_message("INSTRUMENT MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._update_control_channels()
			self._setup_instrument_controller(as_active)
			self._mode_index = 4
		elif mode == "melodic stepseq":
			self._control_surface.show_message("MELODIC SEQUENCER MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(as_active)
			self._update_control_channels()
			self._mode_index = 7
		elif mode == "user 1":
			self._control_surface.show_message("USER 1 MODE" )
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_user_mode(True, True, False, True)
			self._update_control_channels()
			self._mode_index = 1
			self._osd.clear()
			self._osd.mode = "User 1"
			self._osd.update()
		elif mode == "drum stepseq":
			self._control_surface.show_message("DRUM SEQUENCER MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_step_sequencer(as_active)
			self._update_control_channels()
			self._mode_index = 6
		elif mode == "device":
			self._control_surface.show_message("DEVICE CONTROLLER MODE")
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(as_active)
			self._update_control_channels()
			self._mode_index = 5
		elif mode == "user 2":
			self._control_surface.show_message("USER 2 MODE" )
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_user_mode(False, False, False, False)
			self._update_control_channels()
			self._mode_index = 2
			self._osd.clear()
			self._osd.mode = "User 2"
			self._osd.update()
		
	def _setup_session(self, as_active, as_navigation_enabled):
		assert isinstance(as_active, type(False))#assert is boolean
		for button in self._nav_buttons:
			if as_navigation_enabled:
				button.set_on_off_values("Mode.Session.On", "Mode.Session.Off")
			else:
				button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")

		# matrix
		self._activate_matrix(True)
		for scene_index in range(self._session._num_scenes):#iterate over scenes
			scene = self._session.scene(scene_index)
			if as_active:#set scene launch buttons
				scene_button = self._side_buttons[scene_index]
				scene_button.set_enabled(as_active)
				scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)  
				
			for track_index in range(self._session._num_tracks):#iterate over tracks of a scene -> clip slots
				if as_active:#set clip slot launch button
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
					button.set_enabled(as_active)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		if as_active:#Set up stop clip buttons and stop all clips button
			if self._session._stop_clip_buttons != None:
				for button in self._session._stop_clip_buttons:
					button.set_enabled(as_active)
				#	button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled")
				self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons)

				self._side_buttons[self._session._num_scenes].set_enabled(as_active)
				self._side_buttons[self._session._num_scenes].set_on_off_values("Session.StopClip", "DefaultButton.Disabled")
				self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes])
			else:
				self._session.set_stop_track_clip_buttons(None)
				self._session.set_stop_all_clips_button(None)
		else:
			self._session.set_stop_track_clip_buttons(None)
			self._session.set_stop_all_clips_button(None)
				
		if as_active:# zoom
			self._zooming.set_zoom_button(self._modes_buttons[0])# Set Session button as zoom button, wrong behavior???
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		if as_navigation_enabled: # nav buttons (track/scene)
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, as_active):
		if self._instrument_controller != None:
			if as_active:
				self._activate_matrix(False) #Disable matrix buttons (clip slots)
				self._activate_scene_buttons(True)#Enable side buttons
				self._activate_navigation_buttons(True)#Enable nav buttons
			else:
				for scene_index in range(8):#Restore all matrix buttons and scene launch buttons
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message() # Reset to original channel
					scene_button.force_next_send() #Flush
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()# Reset to original channel
						button.force_next_send()#Flush
			self._instrument_controller.set_enabled(as_active)#Enable/disable instrument controller

	def _setup_device_controller(self, as_active):
		if self._device_controller != None:
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)

	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True):
		# user1 -> All True but release_nav_buttons / user2 -> All false 
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))#User2 enabled

			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
				button.turn_off()
				button.set_enabled((not release_matrix))#User2 enabled

		for button in self._nav_buttons:
			button.set_on_off_values("DefaultButton.Disabled", "DefaultButton.Disabled")
			button.turn_off()
			button.set_enabled((not release_nav_buttons)) #User1 & User2 enabled

		if drum_rack_mode:#User1 enabled
			self._config_button.send_value(2)#Set LP drum rack layout grid mapping mode
		self._config_button.send_value(32)#Send enable flashing led config message to LP
				
	def _setup_step_sequencer(self, as_active):
		if(self._stepseq != None):
			#if(self._stepseq.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq.set_enabled(True)
			else:
				self._stepseq.set_enabled(False)

	def _setup_step_sequencer2(self, as_active):
		if(self._stepseq2 != None):
			#if(self._stepseq2.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq2.set_enabled(True)
			else:
				self._stepseq2.set_enabled(False)

	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):# go back to default mode
				self._sub_modes.set_mode(-1)
			else:
				self._sub_modes.release_controls()

		self._sub_modes.set_enabled(as_active)

	def _init_session(self):
		#self._session.set_stop_clip_value("Session.StopClip")
		#self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop")
		
		session_height = self._matrix.height()
		if self._session._stop_clip_buttons != None:
			session_height = self._matrix.height()-1
	
		for scene_index in range(session_height):
		#	scene = self._session.scene(scene_index)
		#	scene.set_triggered_value("Session.SceneTriggered")
		#	scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
		#		clip_slot = scene.clip_slot(track_index)
		#		clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay")
		#		clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord")
		#		clip_slot.set_stopped_value("Session.ClipStopped")
		#		clip_slot.set_started_value("Session.ClipStarted")
		#		clip_slot.set_recording_value("Session.ClipRecording")
		#		clip_slot.set_record_button_value("Session.RecordButton")
		#		clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		#self._zooming.set_stopped_value("Zooming.Stopped")
		#self._zooming.set_selected_value("Zooming.Selected")
		#self._zooming.set_playing_value("Zooming.Playing")

	def _activate_navigation_buttons(self, active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self, active):
		for button in self._side_buttons:
			button.set_enabled(active)

	def _activate_matrix(self, active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)

	def log_message(self, msg):
		self._control_surface.log_message(msg)

	# Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.force_next_send()
Пример #7
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def __init__(self, matrix, top_buttons, side_buttons, config_button,
                 parent):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._parent = parent
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._stepseq = StepSequencerComponent(self, self._matrix,
                                               self._side_buttons,
                                               self._nav_buttons)
        self._quick_mix = None  #QuickMixerComponent(self._nav_buttons,self._side_buttons,self)
        self._device_controller = DeviceControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons, self)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self._previous_mode_index = -1
        self._sub_mode_index = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_index[index] = 0
        self.set_mode_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_mode(self, mode):
        assert mode in range(self.number_of_modes())
        if ((self._mode_index != mode) or (mode == 3) or True):
            self._mode_index = mode
            self.update()

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        if self._mode_index == self._previous_mode_index:
            if self._mode_index == 1:
                #user mode 1 and device controller
                self._sub_mode_index[self._mode_index] = (
                    self._sub_mode_index[self._mode_index] + 1) % 2
            elif self._mode_index == 2:
                #user mode 2  and step sequencer
                self._sub_mode_index[self._mode_index] = (
                    self._sub_mode_index[self._mode_index] + 1) % 3
            else:
                self._sub_mode_index[self._mode_index] = 0

        for index in range(4):
            if (self._sub_mode_index[index] == 0):
                self._modes_buttons[index].set_on_off_values(
                    AMBER_FULL, AMBER_THIRD)
            if (self._sub_mode_index[index] == 1):
                self._modes_buttons[index].set_on_off_values(
                    GREEN_FULL, GREEN_THIRD)
            if (self._sub_mode_index[index] == 2):
                self._modes_buttons[index].set_on_off_values(
                    RED_FULL, RED_THIRD)

            if (index == self._mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def channel_for_current_mode(self):
        #trying to keep
        if self._mode_index == 0:
            return 0
        elif self._mode_index == 1:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 4  #user 1
            else:
                new_channel = 1  #device ctrl
        elif self._mode_index == 2:
            if self._sub_mode_index[self._mode_index] == 0:
                new_channel = 5  #user 2
            else:
                new_channel = 1 + self._sub_mode_index[
                    self._mode_index]  #step seq
        elif self._mode_index == 3:  #mixer modes
            new_channel = 6 + self._sub_modes.mode()
        #if (new_channel > 0):
        #	new_channel += 3
        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():
            #for index in range(len(self._modes_buttons)):
            #	self._modes_buttons[index].set_force_next_value()
            #	if index == self._mode_index:
            #		self._modes_buttons[index].turn_on()
            #	else:
            #		self._modes_buttons[index].turn_off()

            self._update_mode_buttons()

            #update matrix and side buttons
            for scene_index in range(8):
                #update scene button
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    #update matrix
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)
            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = (self._mode_index == 1)
            if (self._mode_index == 0):
                #session
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session(as_active, as_enabled)
            elif (self._mode_index == 1):
                #user mode + device controller
                self._setup_mixer((not as_active))
                if (self._sub_mode_index[self._mode_index] == 0):
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_device_controller((not as_active))
                    self._setup_session((not as_active), (as_enabled))
                    self._setup_user1(True, True, True)
                else:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_step_sequencer(not as_active, 0)
                    self._setup_device_controller(as_active)

            elif (self._mode_index == 2):
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_device_controller((not as_active))
                if (self._sub_mode_index[self._mode_index] == 0):
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer((not as_active), 0)
                    self._setup_user2(release_buttons)
                else:
                    self._setup_device_controller((not as_active))
                    self._setup_step_sequencer(
                        as_active, self._sub_mode_index[self._mode_index])

            elif (self._mode_index == 3):
                self._setup_step_sequencer((not as_active), 0)
                self._setup_device_controller((not as_active))
                self._setup_session((not as_active), as_enabled)
                self._setup_mixer(as_active)
            else:
                assert False

            self._previous_mode_index = self._mode_index

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()

    #Update the channels of the buttons in the user modes..
    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        #matrix
        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        #zoom
        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

        #nav buttons
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_quick_mix(self, as_active):
        if self._quick_mix != None:
            if as_active:
                for button in range(8):
                    self._side_buttons[button].set_enabled(True)
                self._quick_mix._is_active = True
                self._quick_mix.set_enabled(True)
            else:
                self._quick_mix._is_active = False
                self._quick_mix.set_enabled(False)

    def _setup_step_sequencer(self, as_active, mode):
        if (self._stepseq != None):
            if (self._stepseq._is_active != as_active
                    or self._stepseq._mode != mode):
                if as_active:
                    self._stepseq._mode = mode
                    self._stepseq._force_update = True
                    self._stepseq._is_active = True
                    self._stepseq.set_enabled(True)
                    self._stepseq._on_notes_changed()
                    self._config_button.send_value(32)
                else:
                    self._stepseq._mode = 1
                    self._stepseq._is_active = False
                    self._stepseq.set_enabled(False)

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                #for button in range(8):
                #	self._side_buttons[button].set_enabled(True)
                self._device_controller._is_active = True
                self._device_controller.set_enabled(True)
                self._device_controller.update()
                self._config_button.send_value(32)
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if (as_active and self._sub_modes.is_enabled()):
            self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user1(self,
                     release_matrix=True,
                     release_side_buttons=True,
                     release_nav_buttons=True):

        for scene_index in range(8):
            if (release_side_buttons):
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene_button.turn_off()
                scene_button.set_enabled((not release_side_buttons))

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))

        for button in self._nav_buttons:
            if (release_nav_buttons):
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_nav_buttons))

        if release_matrix:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _setup_user2(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    def log_message(self, message):
        self._parent.log_message(message)
Пример #8
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def log(self, message):
        self._parent.log_message((' ' + message + ' ').center(50, '='))

    def __init__(self, matrix, top_buttons, side_buttons, config_button, osd,
                 parent):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._osd = osd
        self._parent = parent
        self._mode_index = 0
        self._previous_mode_index = -1
        self._main_mode_index = 0
        self._sub_mode_index = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_index[index] = 0
        self.set_mode_buttons(top_buttons[4:])

        if Settings.SESSION__STOP_BUTTONS:
            #session with bottom stop buttons
            clip_stop_buttons = []
            for column in range(8):
                clip_stop_buttons.append(
                    matrix.get_button(column,
                                      matrix.height() - 1))
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height() - 1,
                                                    clip_stop_buttons, self)
        else:
            #no stop buttons
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height(), None,
                                                    self)

        self._session.set_osd(self._osd)
        self._session.name = 'Session_Control'

        self._zooming = DeprecatedSessionZoomingComponent(self._session)
        self._zooming.name = 'Session_Overview'
        self._zooming.set_empty_value(LED_OFF)

        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button

        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes._mixer.set_osd(self._osd)
        self._sub_modes.set_update_callback(self._update_control_channels)

        self._stepseq = StepSequencerComponent(self._matrix,
                                               self._side_buttons,
                                               self._nav_buttons, self)
        self._stepseq.set_osd(self._osd)

        self._stepseq2 = StepSequencerComponent2(self._matrix,
                                                 self._side_buttons,
                                                 self._nav_buttons, self)
        self._stepseq2.set_osd(self._osd)

        self._instrument_controller = InstrumentControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons, self)
        self._instrument_controller.set_osd(self._osd)

        self._device_controller = DeviceControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons, self)
        self._device_controller.set_osd(self._osd)

        self._init_session()
        self._all_buttons = tuple(self._all_buttons)

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def _update_mode(self):
        mode = self._modes_heap[-1][0]
        assert mode in range(self.number_of_modes())
        if self._main_mode_index == mode:
            if self._main_mode_index == 1:
                # user mode 1 and device controller and instrument mode
                self._sub_mode_index[self._main_mode_index] = (
                    self._sub_mode_index[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 2:
                # user mode 2  and step sequencer
                self._sub_mode_index[self._main_mode_index] = (
                    self._sub_mode_index[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 3:
                self.update()
            else:
                self._sub_mode_index[self._main_mode_index] = 0
                self._mode_index = 0

            self._previous_mode_index = self._main_mode_index
        else:
            self._main_mode_index = mode
            self.update()

    def set_mode(self, mode):
        self._clean_heap()
        self._modes_heap = [(mode, None, None)]
        # if ((self.__main_mode_index != mode) or (mode == 3) or True):
        # 	self._main_mode_index = mode
        # 	self._update_mode()
        # 	self.update()

    def number_of_modes(self):
        return 1 + 3 + 3 + 1

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        for index in range(4):
            if (self._sub_mode_index[index] == 0):
                self._modes_buttons[index].set_on_off_values(
                    AMBER_FULL, AMBER_THIRD)
            if (self._sub_mode_index[index] == 1):
                self._modes_buttons[index].set_on_off_values(
                    GREEN_FULL, GREEN_THIRD)
            if (self._sub_mode_index[index] == 2):
                self._modes_buttons[index].set_on_off_values(
                    RED_FULL, RED_THIRD)

            if (index == self._main_mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def channel_for_current_mode(self):
        # in this code, midi channels start at 0.
        # so channels range from 0 - 15.
        # mapping to 1-16 in the real world

        if self._main_mode_index == 0:
            new_channel = 0  # session

        elif self._main_mode_index == 1:
            if self._sub_mode_index[self._main_mode_index] == 0:
                new_channel = 11  # instrument controller
                # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
                if self._instrument_controller != None:
                    self._instrument_controller.base_channel = new_channel
            elif self._sub_mode_index[self._main_mode_index] == 1:
                new_channel = 3  # device controller
            elif self._sub_mode_index[self._main_mode_index] == 2:
                new_channel = 4  # plain user mode 1

        elif self._main_mode_index == 2:
            if self._sub_mode_index[self._main_mode_index] == 0:
                new_channel = 1  # step seq
            elif self._sub_mode_index[self._main_mode_index] == 1:
                new_channel = 2  # melodic step seq
            elif self._sub_mode_index[self._main_mode_index] == 2:
                new_channel = 5  # plain user mode 2

        elif self._main_mode_index == 3:  # mixer modes
            # mixer uses base channel 7 and the 4 next ones.
            new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            self._update_mode_buttons()

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)

            if self._main_mode_index == 0:
                # session
                self._setup_mixer(not as_active)
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(as_active, as_enabled)
                self._update_control_channels()
                self._mode_index = 0

            elif self._main_mode_index == 1 or self._main_mode_index == 2:
                self._setup_usermode(Settings.USER_MODES[
                    (self._main_mode_index - 1) * 3 +
                    self._sub_mode_index[self._main_mode_index]])
                #if self._sub_mode_index[self._main_mode_index] == 0:
                #	self._setup_usermode(Settings.USER_MODES[0])
                #elif self._sub_mode_index[self._main_mode_index] == 1:
                #	self._setup_usermode(Settings.USER_MODES[1])
                #else:
                #	self._setup_usermode(Settings.USER_MODES[2])
            #elif self._main_mode_index == 2:
            #	if self._sub_mode_index[self._main_mode_index] == 0:
            #		self._setup_usermode(Settings.USER_MODES[3])
            #	elif self._sub_mode_index[self._main_mode_index] == 1:
            #		self._setup_usermode(Setting.USER_MODES[4])
            #	else:
            #		self._setup_usermode(Settings.USER_MODES[5])

            elif self._main_mode_index == 3:
                # mixer
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
                self._update_control_channels()
                self._mode_index = 3
            else:
                assert False
            self._previous_mode_index = self._main_mode_index

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            #self.log_message("main selector update")
            #for line in traceback.format_stack():
            #	self.log_message(line.strip())

    def _setup_usermode(self, mode):
        as_active = True
        as_enabled = True
        if mode == "instrument":
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._update_control_channels()
            self._setup_instrument_controller(as_active)
            self._mode_index = 4
        elif mode == "melodic stepseq":
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(as_active)
            self._update_control_channels()
            self._mode_index = 7
        elif mode == "user 1":
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_user_mode(True, True, False, True)
            self._update_control_channels()
            self._mode_index = 1
            self._osd.clear()
            self._osd.mode = "User 1"
            self._osd.update()
        elif mode == "drum stepseq":
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_step_sequencer(as_active)
            self._update_control_channels()
            self._mode_index = 6
        elif mode == "device":
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(as_active)
            self._update_control_channels()
            self._mode_index = 5
        elif mode == "user 2":
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_user_mode(False, False, False, False)
            self._update_control_channels()
            self._mode_index = 2
            self._osd.clear()
            self._osd.mode = "User 2"
            self._osd.update()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        # matrix
        self._activate_matrix(True)
        for scene_index in range(self._session._num_scenes):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_enabled(as_active)
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(self._session._num_tracks):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    button.set_enabled(as_active)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            if self._session._stop_clip_buttons != None:
                for button in self._session._stop_clip_buttons:
                    button.set_enabled(as_active)
                    button.set_on_off_values(AMBER_THIRD, LED_OFF)
                self._session.set_stop_track_clip_buttons(
                    self._session._stop_clip_buttons)

                self._side_buttons[self._session._num_scenes].set_enabled(
                    as_active)
                self._side_buttons[
                    self._session._num_scenes].set_on_off_values(
                        AMBER_THIRD, LED_OFF)
                self._session.set_stop_all_clips_button(
                    self._side_buttons[self._session._num_scenes])
            else:
                self._session.set_stop_track_clip_buttons(None)
                self._session.set_stop_all_clips_button(None)
        else:
            self._session.set_stop_track_clip_buttons(None)
            self._session.set_stop_all_clips_button(None)

        # zoom
        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

        # nav buttons
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_instrument_controller(self, enabled):
        if self._instrument_controller != None:
            if enabled:
                self._activate_matrix(False)
                self._activate_scene_buttons(True)
                self._activate_navigation_buttons(True)
            else:
                for scene_index in range(8):
                    scene_button = self._side_buttons[scene_index]
                    scene_button.use_default_message()
                    scene_button.force_next_send()
                    for track_index in range(8):
                        button = self._matrix.get_button(
                            track_index, scene_index)
                        button.use_default_message()
                        button.force_next_send()
            self._instrument_controller.set_enabled(enabled)

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._device_controller._is_active = True
                self._config_button.send_value(32)
                self._device_controller.set_enabled(True)
                self._device_controller.update()
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_user_mode(self,
                         release_matrix=True,
                         release_side_buttons=True,
                         release_nav_buttons=True,
                         drum_rack_mode=True):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.force_next_send()
            scene_button.turn_off()
            scene_button.set_enabled((not release_side_buttons))

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled((not release_matrix))

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled((not release_nav_buttons))

        if drum_rack_mode:
            self._config_button.send_value(2)
        self._config_button.send_value(32)

    def _setup_step_sequencer(self, as_active):
        if (self._stepseq != None):
            #if(self._stepseq.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq.set_enabled(True)
            else:
                self._stepseq.set_enabled(False)

    def _setup_step_sequencer2(self, as_active):
        if (self._stepseq2 != None):
            #if(self._stepseq2.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq2.set_enabled(True)
            else:
                self._stepseq2.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if as_active:
            self._activate_navigation_buttons(True)
            self._activate_scene_buttons(True)
            self._activate_matrix(True)
            if (self._sub_modes.is_enabled()):
                # go back to default mode
                self._sub_modes.set_mode(-1)
        else:
            self._sub_modes.release_controls()

        self._sub_modes.set_enabled(as_active)

    def _init_session(self):
        major = self._parent._live_major_version
        minor = self._parent._live_minor_version
        bugfix = self._parent._live_bugfix_version
        if (major >= 9 and minor > 1) or (major >= 9 and minor >= 1
                                          and bugfix >= 2):
            # api changed in 9.1.2
            self._session.set_stop_clip_value(AMBER_THIRD)
            self._session.set_stop_clip_triggered_value(AMBER_BLINK)
        else:
            # api for 9.1.1 below
            self._session.set_stop_track_clip_value(AMBER_BLINK)

        session_height = self._matrix.height()
        if self._session._stop_clip_buttons != None:
            session_height = self._matrix.height() - 1

        for scene_index in range(session_height):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.set_record_button_value(RED_THIRD)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    def _activate_navigation_buttons(self, active):
        for button in self._nav_buttons:
            button.set_enabled(active)

    def _activate_scene_buttons(self, active):
        for button in self._side_buttons:
            button.set_enabled(active)

    def _activate_matrix(self, active):
        for scene_index in range(8):
            for track_index in range(8):
                self._matrix.get_button(track_index,
                                        scene_index).set_enabled(active)

    def log_message(self, msg):
        self._parent.log_message(msg)

    # Update the channels of the buttons in the user modes..
    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()
Пример #9
0
class MF3D_Color_Clip(ControlSurface):
    __doc__ = " Script for Mad Zach's Weekly soundpacks "

    _active_instances = []

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= MIDI Fighter Mad Zach Soundpack log opened =--------------"
        )  # Writes message into Live's main log file. This is a ControlSurface method.
        self.set_suppress_rebuild_requests(True)
        self._session = None
        self._session_zoom = None
        self._last_tr_off = 0
        self._last_sc_off = 0
        self._scenedir = 1  # direction of scene movement
        self._last_scenedir = 1
        self._setup_session_control()
        self.set_suppress_rebuild_requests(False)

    def disconnect(self):
        self._session = None
        self._session_zoom = None
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= MIDI Fighter Mad Zach Soundpack log closed =--------------"
        )  # Writes message into Live's main log file. This is a ControlSurface method.
        ControlSurface.disconnect(self)

    def _setup_session_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(
            self._set_button(BUTTONCHANNEL + 1, SESSIONRIGHT),
            self._set_button(BUTTONCHANNEL + 1, SESSIONLEFT))
        self._session.set_scene_bank_buttons(
            self._set_button(BUTTONCHANNEL + 1, SESSIONDOWN),
            self._set_button(BUTTONCHANNEL + 1, SESSIONUP))
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(
            self._set_button(BUTTONCHANNEL + 1, ZOOMUP),
            self._set_button(BUTTONCHANNEL + 1, ZOOMDOWN),
            self._set_button(BUTTONCHANNEL + 1, ZOOMLEFT),
            self._set_button(BUTTONCHANNEL + 1, ZOOMRIGHT))
        tracks = self.getslots()  #get clip slots to access clip colors
        for scene_index in range(4):
            scene_off = self._session._scene_offset
            scene = self._session.scene(scene_index + scene_off)
            scene.name = 'Scene_' + str(scene_index + scene_off)
            button_row = []
            for track_index in range(4):
                button = self._set_button(
                    BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index],
                    GREEN, OFF)
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index + scene_off)
                clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index +
                                        scene_off]  #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval = self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    self.log_message("Clip:  tr: " + str(track_index) +
                                     " clip: " + str(scene_index + scene_off) +
                                     " has color: " +
                                     str(self.int_to_rgb(c.clip.color)) +
                                     " va " + str(cval))
                    clip_slot.set_stopped_value(cval)
##                clip_slot.set_triggered_to_launch_value(1)
                clip_slot.set_triggered_to_play_value(PLAYTRIG_COL)
                clip_slot.set_started_value(TRIGD_COL)
                clip_slot.set_triggered_to_record_value(RECTRIG_COL)
                clip_slot.set_recording_value(RECD_COL)

    def int_to_rgb(self, rgbint):
        return (rgbint / 256 / 256 % 256, rgbint / 256 % 256, rgbint % 256)

    def getslots(self):
        tracks = self.song().visible_tracks

        clipSlots = []
        for track in tracks:
            clipSlots.append(track.clip_slots)
        return clipSlots

    def _set_button(self, _channel, _note, _on_color=118, _off_color=0):
        _button = None
        if not _note is -1:
            _button = ConfigurableButtonElement(True, MESSAGETYPE, _channel,
                                                _note, _on_color, _off_color)
        return _button

    def _set_colors(self, scene_dir):
        tracks = self.getslots()  #get clip slots to access clip colors
        scene_off = self._session.scene_offset()
        track_off = self._session.track_offset()
        for scene_index in range(4):
            sc = scene_index
            #self._session._reassign_scenes()
            scene = self._session.scene(sc)
            self.log_message("scene index :" + str(scene_index) +
                             " scene offset " + str(scene_off))
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            for track_index in range(4):
                #button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF)
                #button_row.append(button)
                tr = track_index
                clip_slot = scene.clip_slot(tr)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                #clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index + scene_off +
                                        scene_dir]  #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval = self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    clip_slot.set_stopped_value(cval)
                    self.log_message("Clip:  scene: " +
                                     str(scene_index + scene_off) +
                                     " track: " + str(track_index) +
                                     " has color: " +
                                     str(self.int_to_rgb(c.clip.color)) +
                                     " va " + str(cval))

    def update_display(self):
        ControlSurface.update_display(self)
        scene_off = self._session.scene_offset()
        track_off = self._session.track_offset()
        if (scene_off != self._last_sc_off):
            self.log_message("moved : " + str(self._session._track_offset) +
                             " " + str(self._session._scene_offset))
            if (scene_off > self._last_sc_off):
                if self._scenedir is not self._last_scenedir:
                    self._scenedir = -1
                else:
                    self._scenedir = 1
            elif (scene_off < self._last_sc_off):
                if self._scenedir is not self._last_scenedir:
                    self._scenedir = 1
                else:
                    self._scenedir = -1
            #else:
            #    self._scenedir=0
            self._last_tr_off = track_off
            self._last_sc_off = scene_off
            self._last_scenedir = self._scenedir
        self._set_colors(self._scenedir)

    def _get_MF3D_color(self, colors):
        red = colors[0]
        green = colors[1]
        blue = colors[2]
        color_table = ((255, 0, 0, RED), (125, 0, 0, LOWRED), (255, 127, 0,
                                                               ORANGE),
                       (127, 64, 0, LOWORANGE), (255, 255, 0, YELLOW),
                       (127, 127, 0, LOWYELLOW), (127, 255, 0, CHARTREUSSE),
                       (64, 127, 0, LOWCHARTREUSSE), (0, 255, 0, GREEN),
                       (0, 127, 0, LOWGREEN), (0, 255, 255, CYAN),
                       (0, 127, 127, LOWCYAN), (0, 0, 255, BLUE),
                       (0, 0, 127, LOWBLUE), (0, 255, 127,
                                              PURPLE), (0, 127, 64, LOWPURPLE),
                       (0, 255, 255, PINK), (0, 127, 127,
                                             LOWPINK), (255, 255, 255, WHITE))
        min_dist = 9999999
        color_node = (0, 0, 0, 119)
        for index in range(len(color_table)):
            if (min_dist > self._get_distance(colors, color_table[index])):
                min_dist = self._get_distance(colors, color_table[index])
                #self.log_message("colors " +  str(color_node) + " and " + str(color_table[index]))
                color_node = color_table[index]
        #self.log_message("red " + str(red) + " green " + str(green) + " blue " + str(blue) + " distance to" + str(color_node[3]) + " :: " + str(self._get_distance(colors,color_node)))
        return color_node[3]

    def _get_distance(self, color1, color2):
        r1 = color1[0]
        g1 = color1[1]
        b1 = color1[2]
        r2 = color2[0]
        g2 = color2[1]
        b2 = color2[2]
        #self.log_message("got " + str(color1) + " and " + str(color2))
        return (abs((r1 - r2)) + abs((g1 - g2)) + abs((b1 - b2)))
class MainSelectorComponent(ModeSelectorComponent):
	""" Class that reassigns the buttons on the Spark to different functions """

	def __init__(self, launch_buttons, mode_buttons, pads, transport_buttons, select_button, translate_button, mute_button, solo_button, tempo_control, volume_control, param_controls, copy_button, erase_button, rewind_button, forward_button, browser_control, browser_button, pattern_leds, track_leds, divide_control, move_control, parent):
		"verifies that the buttons given are compatible with the selector component"
		assert isinstance(launch_buttons, tuple)
		assert (len(launch_buttons) == 16)
		assert isinstance(mode_buttons, tuple)
		assert (len(mode_buttons) == 4)
		assert isinstance(pads, tuple)
		assert (len(pads) == 8)
		assert (len(transport_buttons) == 4)
		assert (len(param_controls) == 3)
		ModeSelectorComponent.__init__(self)

		"the parent atribute allows us to control the control surface component"
		"it can be used for example to get the currently selected track"
		self._parent = parent

		"definition of all the components we will map buttons with"
		self._session = SpecialSessionComponent(8, 16)
		self._session.name = 'Session_Control'
		self._mixer = SpecialMixerComponent(8)
		self._mixer.name = 'Mixer_Control'
		self._transport = SpecialTransportComponent(self)
		self._transport.name = 'Transport_Control'
		self._device = DeviceComponent()
		self._device.name = 'Device_Control'

		"definition of all the buttons that will be used"
		self._launch_buttons = launch_buttons
		self._mode_buttons = mode_buttons
		self._pads = pads
		self._all_buttons = []
		self._select_button = select_button
		self._translate_button = translate_button
		self._mute_button = mute_button
		self._solo_button = solo_button
		self._transport_buttons = transport_buttons
		self._copy_button = copy_button
		self._erase_button = erase_button
		self._rewind_button = rewind_button
		self._forward_button = forward_button
		self._browser_control = browser_control
		self._browser_button = browser_button
		self._divide_control = divide_control
		self._move_control = move_control
		self._track_leds = track_leds
		self._pattern_leds = pattern_leds

		"definition of all the controls that will be used"
		self._tempo_control = tempo_control
		self._volume_control = volume_control
		self._param_controls = param_controls

		for button in self._launch_buttons + self._mode_buttons + self._pads + self._transport_buttons + self._track_leds + self._pattern_leds:
			self._all_buttons.append(button)
		self._all_buttons.append(self._select_button)
		self._all_buttons.append(self._translate_button)
		self._all_buttons.append(self._mute_button)
		self._all_buttons.append(self._solo_button)
		self._all_buttons.append(self._copy_button)
		self._all_buttons.append(self._erase_button)
		self._all_buttons.append(self._rewind_button)
		self._all_buttons.append(self._forward_button)

		self._stepseq = StepSequencerComponent(self, self._launch_buttons,self._pads, self._translate_button, self._select_button, self._mute_button, self._solo_button, tuple(self._transport_buttons), forward_button, rewind_button, pattern_leds)
		self._translation_selector = TranslationSelectorComponent(tuple(self._launch_buttons), tuple(self._pads), self._translate_button, self)

		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self._mode_index=0
		self._previous_mode_index=-1
		self.set_mode_buttons(mode_buttons)
		self._parent = parent
		self._selected_track_index=0
		self._previous_track_index=0
		self._parent.set_device_component(self._device)
		for button in self._all_buttons:
			button.send_value(0,True)

	def disconnect(self):
		for button in self._mode_buttons:
			button.remove_value_listener(self._mode_value)
		for button in self._all_buttons:
			button.send_value(0,True)

		self._session = None
		self._mixer = None
		self._transport = None
		self._launch_buttons = None
		self._mode_buttons = None
		self._pads = None
		self._transport_buttons = None
		ModeSelectorComponent.disconnect(self)

	def _update_mode(self):
		"""check if the mode selected is a new mode and if so update the controls"""
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._mode_index==mode or (mode == 2 and not self.song().view.selected_track.has_midi_input):
			self._previous_mode_index=self._mode_index
		else:
			self._mode_index = mode
			for button in self._all_buttons:
				button.send_value(0,True)
			self.update()
	
	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]

	def number_of_modes(self):
		return 4

	def _update_mode_buttons(self):
		"""lights up the mode buttons if selected"""
		for index in range(4):
			if (index == self._mode_index):	
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()

	def update(self):
		"""main method of the class that calls the assignation methods corresponding to the current mode"""
		"""it is called when the mode changes and when the selected track changes"""
		assert (self._modes_buttons != None)
		"links the session to the mixer, so that when change the selected track the session also changes position"
		self._session.set_mixer(self._mixer)
		if self.is_enabled():
			self._update_mode_buttons()
			self._translation_selector.update()
			
			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)#we dont want the controlls to change while we are updating the assignations

			if (self._mode_index == 0):
				"A: Transport mode"
				"we activate the transport buttons and tha launch scenes buttons"
				#self._parent.log_message("Launching mode")
				self._setup_step_sequencer(not as_active)
				self._setup_launch_clips(not as_active,not as_enabled)
				self._setup_track_controls(not as_active)
				self._setup_device_buttons(not as_active)
				self._set_scale_control(not as_active)
				self._setup_transport_buttons(as_active)
				self._setup_launch_scenes(as_active, as_enabled)
				self._setup_master_controls(as_active)
				self._set_browser_control(as_active)
				self._set_browser_button(as_active)
				self._setup_select_buttons(as_active)

			elif (self._mode_index == 1):
				"B: Mixer mode"
				"we activate the track selection, arm, and mute buttons and the launch clips buttons"
				#self._parent.log_message("Launching clips mode")
				self._setup_step_sequencer(not as_active)
				self._setup_launch_scenes(not as_active, not as_enabled)
				self._setup_master_controls(not as_active)
				self._setup_device_buttons(not as_active)
				self._set_scale_control(not as_active)
				self._setup_transport_buttons(as_active)
				self._setup_launch_clips(as_active, as_enabled)
				self._setup_track_controls(as_active)
				self._setup_select_buttons(as_active)
				self._set_browser_control(as_active)
				self._set_browser_button(as_active)

			elif (self._mode_index == 2):
				"C: Step sequencer mode"
				self._setup_launch_scenes(not as_active, not as_enabled)
				self._setup_launch_clips(not as_active,not as_enabled)
				self._setup_track_controls(not as_active)
				self._setup_master_controls(not as_active)
				self._setup_select_buttons(not as_active)
				self._setup_device_buttons(not as_active)
				self._setup_transport_buttons(not as_active)
				self._set_scale_control(not as_active)
				self._setup_step_sequencer(as_active)
				self._set_browser_control(as_active)
				self._set_browser_button(as_active)

			else:
				"D: Instrument mode"
				"the keyboard now control the selected midi instrument"
				self._setup_step_sequencer(not as_active)
				self._setup_launch_clips(not as_active,not as_enabled)
				self._setup_launch_scenes(not as_active, not as_enabled)
				self._setup_track_controls(not as_active)
				self._setup_master_controls(not as_active)
				self._setup_select_buttons(not as_active)
				self._set_browser_control(as_active)
				self._set_browser_button(as_active)
				self._setup_device_buttons(as_active)
				self._setup_transport_buttons(as_active)
				self._set_scale_control(as_active)

			self._update_session_translation()
			self._session.set_allow_update(True)
			self._previous_mode_index=self._mode_index

			#self._parent.log_message("Updated")
			

	
	def _setup_launch_scenes(self, as_active, as_enabled):
		"if as_active, we'll assignate the keyboard notes to the launch scene buttons"
		assert isinstance(as_active, type(False))

		#launch_buttons
		for scene_index in range(16):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._launch_buttons[scene_index]
				scene_button.turn_off()
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)

	def _setup_launch_clips(self, as_active, as_enabled):
		"if as_active, we'll assignate the keyboard notes to the launch clip buttons"
		assert isinstance(as_active, type(False))

		#launch_buttons
		for scene_index in range(16):
			scene = self._session.scene(scene_index)
			for track_index in range(8):
				if as_active and track_index==self._selected_track_index:
					clip_button = self._launch_buttons[scene_index]
					clip_button.turn_off()
					scene.clip_slot(track_index).set_launch_button(clip_button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

	def _setup_select_buttons(self, as_active):
		"if as_active, we'll assign the pads to track selection and track control buttons"
		"pads 15 and 16 will shift and arm tha selected track"
		for index in range(8):
			select_button = self._pads[index]
			if as_active:
				if self._selected_track_index == index: 
					"we only assign the arm and mute buttons of the selected track"
					#self._parent.log_message("set arm on "+str(index))
					self._mixer.channel_strip(index).set_arm_button(select_button)
					self._mixer.channel_strip(index).set_mute_button(self._mute_button)
					self._mixer.channel_strip(index).set_solo_button(self._solo_button)
					self._mixer.channel_strip(index).set_select_button(None)
					self._mixer.channel_strip(index).set_shift_button(self._select_button)
					self._track_leds[index].send_value(127,True)
				else:
					self._mixer.channel_strip(index).set_arm_button(None)
					self._mixer.channel_strip(index).set_select_button(select_button)
					self._mixer.channel_strip(index).set_mute_button(None)
					self._mixer.channel_strip(index).set_solo_button(None)
					self._mixer.channel_strip(index).set_shift_button(None)
					self._track_leds[index].send_value(0,True)
			else:
				self._mixer.channel_strip(index).set_select_button(None)
				self._mixer.channel_strip(index).set_arm_button(None)
				self._mixer.channel_strip(index).set_mute_button(None)
				self._mixer.channel_strip(index).set_mute_button(None)
				self._mixer.channel_strip(index).set_solo_button(None)
				self._track_leds[index].turn_off()

	def _setup_transport_buttons(self, as_active):
		"if as_active, we'll assign the pads to the transport buttons"
		if as_active:
			self._transport.set_play_button(self._transport_buttons[2])
			self._transport.set_stop_button(self._transport_buttons[1])
			self._transport.set_record_button(self._transport_buttons[0])
			self._transport.set_loop_button(self._transport_buttons[3])
			self._transport.set_tempo_encoder(self._tempo_control)
			self._transport.set_undo_button(self._erase_button)
			self._transport.set_redo_button(self._copy_button)
		else:
			self._transport.set_play_button(None)
			self._transport.set_stop_button(None)
			self._transport.set_record_button(None)
			self._transport.set_loop_button(None)
			self._transport.set_tempo_encoder(None)
			self._transport.set_undo_button(None)
			self._transport.set_redo_button(None)

	def _setup_master_controls(self, as_active):
		"if as_active, we'll assign the control knobs to the master track parameters"
		if as_active:
			self._mixer.master_strip().set_volume_control(self._volume_control)
			self._mixer.master_strip().set_pan_control(self._param_controls[0])
			self._mixer.set_prehear_volume_control(self._param_controls[1])
			self._mixer.set_crossfader_control(self._param_controls[2])
			self._transport.set_seek_buttons(self._forward_button,self._rewind_button)
		else:
			self._mixer.master_strip().set_volume_control(None)
			self._mixer.master_strip().set_pan_control(None)
			self._mixer.set_prehear_volume_control(None)
			self._mixer.set_crossfader_control(None)
			self._transport.set_seek_buttons(None,None)

	def _setup_track_controls(self, as_active):
		"if as_active, we'll assign the control knobs to the master track parameters"
		if as_active:
			self._parent.log_message(self._previous_track_index)
			self._mixer.channel_strip(self._previous_track_index).set_volume_control(None)
			self._mixer.channel_strip(self._previous_track_index).set_pan_control(None)
			self._mixer.channel_strip(self._previous_track_index).set_send_controls(None)
			self._parent.log_message(self._selected_track_index)
			self._mixer.channel_strip(self._selected_track_index).set_volume_control(self._volume_control)
			self._mixer.channel_strip(self._selected_track_index).set_pan_control(self._param_controls[0])
			self._mixer.channel_strip(self._selected_track_index).set_send_controls(self._param_controls[1:])
		else:
			self._mixer.channel_strip(self._selected_track_index).set_volume_control(None)
			self._mixer.channel_strip(self._selected_track_index).set_pan_control(None)
			self._mixer.channel_strip(self._selected_track_index).set_send_controls(None)


		
	def _setup_device_buttons(self, as_active):
		"if as_active, we'll assign the pads to the device selection and activation buttons"
		if as_active:
			self._device.set_parameter_controls(self._param_controls)
			self._device.set_bank_nav_buttons(self._rewind_button, self._forward_button)
		else:
			self._device.set_parameter_controls(None)
			self._device.set_bank_nav_buttons(None, None)


	def _init_session(self):
		for scene_index in range(len(self._launch_buttons)):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(127)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(8):
				"TODO: this still doesn't light the launch clip buttons when supposed to..."
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(127)
				clip_slot.set_triggered_to_record_value(127)
				clip_slot.set_stopped_value(0)
				clip_slot.set_started_value(127)
				clip_slot.set_recording_value(127)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)

	def _mode_value(self, value, sender):
		"method called each time the value of the mode selection changed"
		"it's been momentary overriden to avoid dysfunctionnement in the framework method"
		new_mode = self._modes_buttons.index(sender)
		if sender.is_momentary():
			#self._parent.log_message(sender.message_identifier())
			if value > 0:
				#self._parent.log_message("value = "+str(value))
				mode_observer = MomentaryModeObserver()
				mode_observer.set_mode_details(new_mode, self._controls_for_mode(new_mode), self._get_public_mode_index)
				self._modes_heap.append((new_mode, sender, mode_observer))
				self._update_mode()
			elif self._modes_heap[-1][1] == sender and not self._modes_heap[-1][2].is_mode_momentary():
				#self._parent.log_message("sender trouve")
				self.set_mode(new_mode)
			else:
				#TODO: comprendre comment le framework est sense fonctionner et remplacer supprimer cet modif du framework
				self.set_mode(new_mode)
				self._update_mode()
		else:
			#self._parent.log_message("boutton pas trouve")
			self.set_mode(new_mode)

	def _setup_step_sequencer(self, as_active):
		if(self._stepseq!=None):
				if as_active: 
					self._stepseq._force_update = True
					self._stepseq._is_active = True
					self._stepseq.set_enabled(True)
					self._stepseq._on_notes_changed()
					self._stepseq._update_seq_buttons()
				else:
					self._stepseq._is_active = False
					self._stepseq.set_enabled(False)

	def _set_browser_control(self, as_active):
		self._browser_control.remove_value_listener(self._browser_control_value)
		if as_active:
			self._browser_control.add_value_listener(self._browser_control_value)



	def _browser_control_value(self, value):
		if value != 64:
			all_scenes = self.song().scenes
			selected_scene = self.song().view.selected_scene
			selected_scene_index = list(all_scenes).index(selected_scene)
			new_selected_scene_index = max(0, min(selected_scene_index + (value-64), len(list(all_scenes))-1) )
			self.song().view.selected_scene = all_scenes[new_selected_scene_index]
			session_offset = self._session.scene_offset()
			if new_selected_scene_index > session_offset + 15:
				self._session.set_offsets(self._session.track_offset(), new_selected_scene_index - 15)
			if new_selected_scene_index < session_offset:
				self._session.set_offsets(self._session.track_offset(), new_selected_scene_index)

	def _set_browser_button(self, as_active):
		self._browser_button.remove_value_listener(self._browser_button_value)
		if as_active:
			self._browser_button.add_value_listener(self._browser_button_value)

	def _browser_button_value(self, value):
		if value != 0:
			if self._mode_index == 2:
				self.song().view.highlighted_clip_slot.fire()
			else:
				self.song().view.selected_scene.fire_as_selected()



	def _set_scale_control(self, as_active):
		self._divide_control.remove_value_listener(self._translation_selector._scale_index_value)
		self._move_control.remove_value_listener(self._translation_selector._scale_offset_value)
		if as_active:
			self._divide_control.add_value_listener(self._translation_selector._scale_index_value)
			self._move_control.add_value_listener(self._translation_selector._scale_offset_value)

	def _update_session_translation(self):
		if self._mode_index == 0 or self._mode_index == 1:
			if self._translation_selector.mode():
				self._session.set_offsets(8,self._session.scene_offset())
			else:
				self._session.set_offsets(0,self._session.scene_offset())

	def on_selected_track_changed(self):
		all_tracks = ((self.song().tracks + self.song().return_tracks))
		selected_track = self.song().view.selected_track
		self._previous_track_index = self._selected_track_index
		self._selected_track_index = list(all_tracks).index(selected_track)
		self.update()
Пример #11
0
class MainSelectorComponent(ModeSelectorComponent):
	" CLASS THAT REASSIGNS THE BUTTON ON THE LAUNCHPAD TO DIFFERENT FUNCTIONS "

	" INIT "
	def __init__(self, matrix, top_buttons, side_buttons, config_button):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._session = SpecialSessionComponent(self, len(self.song().tracks), matrix.height(), side_buttons)
		self._session.name = "Session_Control"
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._all_buttons = []
		for button in (self._side_buttons + self._nav_buttons):
			self._all_buttons.append(button)
		self._sub_modes = SpecialMixerSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.name = "Mixer_Modes"
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self.set_modes_buttons(top_buttons[4:])
		# mixer-session hack
		self._buttons_for_mixer = []
		for button in (self._side_buttons[5:]):
			self._buttons_for_mixer.append(button)
		for scene_index in range(self._matrix.height()):
			for track_index in range(self._matrix.width()):
				if scene_index > SESSION_HEIGHT_FOR_MIXER:
					self._buttons_for_mixer.append(self._matrix.get_button(track_index, scene_index))

	" DISCONNECT "
	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)
		self._session = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)
		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		self._buttons_for_mixer = None
		ModeSelectorComponent.disconnect(self)
		
	" GET SESSION COMPONENT "
	def session_component(self):
		return self._session

	" SET THE MODE BUTTONS "
	def set_modes_buttons(self, buttons):
		assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == self.number_of_modes())))
		identify_sender = True
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)
		self._modes_buttons = []
		if (buttons != None):
			for button in buttons:
				assert isinstance(button, ButtonElement)
				self._modes_buttons.append(button)
				button.add_value_listener(self._mode_value, identify_sender)
		self.set_mode(0)

	" GET AMOUNT OF MODES "
	def number_of_modes(self):
		return 4

	" CHANGE CALLBACK "
	def on_enabled_changed(self):
		self.update()

	" SET THE MODE "
	def set_mode(self, mode):
		assert (mode in range(self.number_of_modes()))
		if ((self._mode_index != mode) or (mode == 3) or True):
			self._mode_index = mode
			self.update()

	" UPDATE MODE BUTTONS "
	def _update_mode_buttons(self):
		for index in range(4):
			if (index == self._mode_index):	
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()

	" SET CHANNEL FOR THE CURRONT MODE "
	def channel_for_current_mode(self):
		#trying to keep 
		if self._mode_index==0:
			return 0
		elif self._mode_index==1:
			new_channel=4#user 1
		elif self._mode_index==2:	
			new_channel=5#user 2		
		elif self._mode_index==3:
			new_channel = 6 + self._sub_modes.mode() #mixer modes
		return new_channel

	" UPDATE THE SHIT "
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():		
			self._update_mode_buttons()			
			#update matrix and side buttons
			for scene_index in range(self._matrix.height()):
				#update scene button
				self._side_buttons[scene_index].set_enabled(True)
				for track_index in range(self._matrix.width()):
					#update matrix
					self._matrix.get_button(track_index, scene_index).set_enabled(True)
			for button in self._nav_buttons:
				button.set_enabled(True)
			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)			
			release_buttons = (self._mode_index == 1)
			
			if (self._mode_index == 0):
				#session
				self._setup_mixer((not as_active))
				self._setup_session(as_active, as_enabled, False)
			elif (self._mode_index == 1):
				#user mode 1
				self._setup_mixer((not as_active))
				self._setup_session((not as_active), (not as_enabled), False)
				self._setup_user1(True,True,True)				
			elif (self._mode_index == 2):
				#user mode 2
				self._setup_mixer((not as_active))
				self._setup_session((not as_active), (not as_enabled), False)				
				self._setup_user2(release_buttons)						
			elif (self._mode_index == 3):
				#mixer
				self._setup_session((as_active), as_enabled, True)
				self._setup_mixer(as_active)
			else:
				assert False				
			self._session.set_allow_update(True)
			self._update_control_channels()

	" UPDATE THE CHANNELS OF THE BUTTONS IN THE USER MODES.. "
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		if self._mode_index == 3:
			# skip the upper part of the matrix and buttons
			for button in self._buttons_for_mixer:
				button.set_channel(new_channel)
				button.set_force_next_value()
		else:
			for button in self._all_buttons:
				button.set_channel(new_channel)
				button.set_force_next_value()
			
	" SETUP THE SESSION "
	def _setup_session(self, as_active, as_enabled, for_mixer):
		#log("setup_session (active: " + str(as_active) + ", enabled: " + str(as_enabled) + ", forMixer: " + str(for_mixer) + ")")
		assert isinstance(as_active, type(False))
		assert isinstance(as_enabled, type(False))
		assert isinstance(for_mixer, type(False))
		# --------------------------------------------------------------------- nav button color
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)
		# --------------------------------------------------------------------- matrix
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)				
			if for_mixer:
				if scene_index <= SESSION_HEIGHT_FOR_MIXER:
					scene_button = self._side_buttons[scene_index]
					scene_button.set_on_off_values(127, GREEN_THIRD)
					scene.set_launch_button(scene_button)
				else:
					scene.set_launch_button(None)
			elif as_active and (not for_mixer):				
				scene_button = self._side_buttons[scene_index]
				scene_button.set_on_off_values(127, GREEN_THIRD)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)				
			# SLOT BUTTONS
			button_index = 0
			for track_index in range(len(self.song().tracks)):
				if self.song().tracks[track_index].is_foldable:
					if button_index < GROUPS_CONSIDERED:				
						if for_mixer:
							if scene_index <= SESSION_HEIGHT_FOR_MIXER:
								button = self._matrix.get_button(button_index, scene_index)
								button.set_on_off_values(127, LED_OFF)
								scene.clip_slot(track_index).set_launch_button(button)
							else:
								scene.clip_slot(track_index).set_launch_button(None)
						elif as_active and (not for_mixer):
							button = self._matrix.get_button(button_index, scene_index)
							button.set_on_off_values(127, LED_OFF)
							scene.clip_slot(track_index).set_launch_button(button)
						else:
							scene.clip_slot(track_index).set_launch_button(None)
						button_index = button_index + 1
				else:
					scene.clip_slot(track_index).set_launch_button(None)						
		# --------------------------------------------------------------------- nav buttons
		if as_enabled or for_mixer:
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_scene_bank_buttons(None, None)

	" SETUP THE MIXER "
	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		self._sub_modes.set_enabled(as_active)

	" SETUP USER 1 "
	def _setup_user1(self, release_matrix=True,release_side_buttons =True,release_nav_buttons = True):	
		for scene_index in range(8):
			if(release_side_buttons):
				scene_button = self._side_buttons[scene_index]
				scene_button.set_on_off_values(127, LED_OFF)
				scene_button.turn_off()
				scene_button.set_enabled((not release_side_buttons))				
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_matrix))
		for button in self._nav_buttons:
			if(release_nav_buttons):
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_nav_buttons))
		if release_matrix:
			self._config_button.send_value(2)
		self._config_button.send_value(32, force_send=True)

	" SETUP USER 2 "
	def _setup_user2(self, release_buttons):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.turn_off()
			scene_button.set_enabled((not release_buttons))
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_buttons))
		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_buttons))
		if release_buttons:
			self._config_button.send_value(2)
		self._config_button.send_value(32, force_send=True)

	" INIT THE SESSION "
	def _init_session(self):
		self._session.set_stop_track_clip_value(AMBER_BLINK)
		# SCENES
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			scene.name = ("Scene_" + str(scene_index))
			# SLOTS
			button_index = 0
			for track_index in range(len(self.song().tracks)):
				if button_index < GROUPS_CONSIDERED:
					if self.song().tracks[track_index].is_foldable:
						clip_slot = scene.clip_slot(track_index)
						clip_slot.set_triggered_to_play_value(GREEN_BLINK)
						clip_slot.set_triggered_to_record_value(RED_BLINK)
						clip_slot.set_stopped_value(AMBER_FULL)
						clip_slot.set_started_value(GREEN_FULL)
						clip_slot.set_recording_value(RED_FULL)
						clip_slot.name = ((str(track_index) + "_Clip_Slot_") + str(scene_index))
						self._all_buttons.append(self._matrix.get_button(button_index, scene_index))
						button_index = button_index + 1
Пример #12
0
class X1MK2(ControlSurface):
    __doc__ = " Script for Traktor X1MK2 in APC emulation mode "

    _active_instances = []
    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in X1MK2._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()
    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._color_skin = make_rgb_skin()
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._to_notify = []
            self._clip_map = []
            self._note_map = []
            self._ctrl_map = []
            self._enc_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)

            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()


    def disconnect(self):
        self._clip_map = None
        self._note_map = None
        self._ctrl_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)


    def _do_combine(self):
        if self not in X1MK2._active_instances:
            X1MK2._active_instances.append(self)
            X1MK2._combine_active_instances()


    def _do_uncombine(self):
        if ((self in X1MK2._active_instances) and X1MK2._active_instances.remove(self)):
            self._session.unlink()
            X1MK2._combine_active_instances()


    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)


    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(SESSION_WIDTH, SESSION_HEIGHT, self.log_message, enable_skinning = True)
        self._session.set_rgb_mode(color_palette = CLIP_COLOR_TABLE(self.log_message), color_table = None, clip_slots_only = True)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT])
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP])
        self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ]
        self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(SESSION_WIDTH)]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(SESSION_HEIGHT):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(SESSION_WIDTH):
                button = self._clip_map[CLIPNOTEMAP[scene_index][track_index]]
                button.num_delayed_messages = 3
                delete_button = self._note_map[DELETECLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_launch_button(button)
                self._to_notify.append(clip_slot)
                clip_slot.set_delete_button(delete_button)
# #                 clip_slot.set_triggered_to_play_value(CLIP_TRG_PLAY[self._rgb])    #set its triggered to play color
# #                 clip_slot.set_triggered_to_record_value(CLIP_TRG_REC[self._rgb])#set its triggered to record color
# #                 clip_slot.set_stopped_value(CLIP_STOP[self._rgb])                #set its stop color
#                 clip_slot.set_started_value(13)            #set its started color
#                 clip_slot.set_recording_value(11)        #set its recording value
                self.log_message('Clip %s:%s' % (clip_slot.name, clip_slot._launch_button_value.subject.message_identifier()))
        #self._session_zoom = SpecialZoomingComponent(self._session)
        #self._session_zoom.name = 'Session_Overview'
        #self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        
        #Setup mixer using the VCM600's MixerComponent which includes EQ and Filter components for tracks
        self._mixer = MixerComponent(SESSION_WIDTH, self)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME])
        for track in range(SESSION_WIDTH):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            
            #Setup EQs using the VCM600s TrackEQComponent
            eq = self._mixer.track_eq(track) 
            eq.name = 'Mixer_EQ_' + str(track)   
            eq.set_gain_controls(tuple([self._enc_map[EQGAINS[track][0]],self._enc_map[EQGAINS[track][1]],self._enc_map[EQGAINS[track][2]]])) #set the encoders for eq gains
            eq.set_cut_buttons(tuple([self._note_map[EQCUTS[track][0]],self._note_map[EQCUTS[track][1]],self._note_map[EQCUTS[track][2]]]))
            eq.set_enabled(True)
           
            #setup filters using VCM600s TrackFilterComponent
            filter = self._mixer.track_filter(track)
            filter.name = 'Mixer_Filter_' + str(track)     
            filter.set_filter_controls(self._enc_map[FILTERS[track][0]],self._enc_map[FILTERS[track][1]])
            filter.set_device_on_off(self._note_map[FILTER_ON[track]],self.log_message)    
            filter.set_enabled(True)
#             for index in range(len(filter._track.devices)):
#                 device = filter._track.devices[-1 * (index + 1)]
#                 self.log_message('Device %s: %s / %s' % (index, device.class_name, device.name))
#            
            fx1 = self._mixer.track_fx1(track)
            fx1.name = 'Mixer_FX1_' + str(track)
            fx1.set_on_off_button(self._note_map[FX1_ON[track]])
            fx1.set_enabled(True)
            
            fx2 = self._mixer.track_fx2(track)
            fx2.set_on_off_button(self._note_map[FX2_ON[track]])
            fx2.set_enabled = True
            
            #Set strip buttons       
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)
            
            

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        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])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)
 
        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW])
        detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] )
 
        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._note_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6


    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(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)
#         self.log_message('Track %s' % track)
#         self.log_message('EQ Track %s' % self._mixer.track_eq(track.)._track)
#         self.log_message('EQ Track Devices' % self._mixer.track_eq(0)._device.class_name)
#              
       
    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,)
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))


    def _load_MIDI_map(self):
        is_momentary = True
        rgb_skin = make_rgb_skin()
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note,)
            button.name = 'Button Note_' + str(note)
            button.is_rgb = True
            self._note_map.append(button)
        self._note_map.append(None) #add None to the end of the list, selectable with [-1]
        
        for note in range(128):
            clip_button = ColorButtonElement(self.log_message,is_momentary, MESSAGETYPE, BUTTONCHANNEL, note, skin = rgb_skin)
            clip_button.name = 'Clip Note_' + str(note)
            button.num_delayed_messages = 3
            self._clip_map.append(clip_button)
        self._clip_map.append(None) #add None
        
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for i in range(128):
                self._ctrl_map.append(None)
                self._enc_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
            
            for enc in range(128):
                encoder = EncoderElement(MIDI_CC_TYPE, SLIDERCHANNEL, enc, Live.MidiMap.MapMode.absolute)
                encoder.name = "Encoder_" + str(enc)
                self._enc_map.append(encoder)
            self._enc_map.append(None)
            
        self.log_message('Note Map: %s' % self._note_map)
        self.log_message('Ctrl Map: %s' % self._ctrl_map)
        self.log_message('Enc Map: %s' % self._enc_map)

    def notify(self):
        for component in self._to_notify:
            component.update() 
            
    def update_display(self):
        with self.component_guard():
            with self._is_sending_scheduled_messages():
                self._task_group.update(0.1)
            self.notify()
Пример #13
0
class MainSelectorComponent(ModeSelectorComponent):
	__module__ = __name__
	__doc__ = ' Class that reassigns the button on the launchpad to different functions '

	def __init__(self, matrix, top_buttons, side_buttons, config_button, knobs, sliders, script):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._script = script
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		for scene in self._session._scenes:
			for slot in scene._clip_slots:
				slot._triggered_to_play_value = 4
				slot._triggered_to_record_value = 3
				slot._started_value = 2
				slot._recording_value = 1
				slot._stopped_value = 127
		self._zooming = SessionZoomingComponent(self._session)
		self._zooming._stopped_value = 127
		self._zooming._playing_value = 2
		self._zooming._selected_value = 1
		self._matrix = matrix
		self._knobs = knobs
		self._sliders = sliders
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._shift_button = top_buttons[5]
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in (self._side_buttons + self._nav_buttons):
			self._all_buttons.append(button)
		self._shift_pressed = 0
		self._shift_pressed_timer = 0
		self._last_normal_mode = 0
		self._shift_button = None
		self.set_shift_button(top_buttons[6])
		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self.set_modes_buttons(top_buttons[4:6])



	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)



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

	def _shift_value(self, value):
		self._shift_pressed = int(value != 0)
		if self._shift_pressed > 0:
			if (self._shift_pressed_timer + 5) > self._script._timer:
				if(self._script._host.is_enabled() != True):
					self.set_mode(4)
				else:
					self._script.log_message('here')
					self.set_mode(self._last_normal_mode)	
			else:
				self._shift_pressed_timer = self._script._timer % 256
		if(self._script._host.is_enabled() != True):
			if(self._mode_index == 1):
				if value > 0:
					self._session.set_track_bank_buttons(None, None)
					self._session.set_scene_bank_buttons(None, None)
					self._sub_modes.set_modes_buttons(self._nav_buttons)
					self._sub_modes.update()
				else:
					self._sub_modes.set_modes_buttons(None)
					self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
					self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
					self._sub_modes.update()
			elif(self._mode_index == 0):
					self._setup_session(True, True)
					self._session.update()
		
	

	def set_modes_buttons(self, buttons):
		assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == 2)))
		identify_sender = True
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._modes_buttons = []
		if (buttons != None):
			for button in buttons:
				assert isinstance(button, ButtonElement)
				self._modes_buttons.append(button)
				button.add_value_listener(self._mode_value, identify_sender)
		self.set_mode(0)

	def _mode_value(self, value, sender):
		assert (len(self._modes_buttons) > 0)
		assert isinstance(value, int)
		assert isinstance(sender, ButtonElement)
		assert (self._modes_buttons.count(sender) == 1)
		if self._script._host.is_enabled() != True:
			if ((value is not 0) or (not sender.is_momentary())):
				if self._shift_pressed > 0:
					if self._modes_buttons.index(sender) == 0:
						self.set_mode(2)
					if self._modes_buttons.index(sender) == 1:
						self.set_mode(3)
				else:
					self._last_normal_mode = int(self._modes_buttons.index(sender))
					self.set_mode(self._modes_buttons.index(sender))
		else:
			pass
				
			

	def number_of_modes(self):
		return 5



	def on_enabled_changed(self):
		self.update()



	def set_mode(self, mode):
		assert (mode in range(self.number_of_modes()))
		if ((self._mode_index != mode) or (mode == 1)):
			self._mode_index = mode
			self.update()



	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			for scene_index in range(8):
				for track_index in range(8):
					self._matrix.get_button(track_index, scene_index).set_enabled(True)


			for button in self._nav_buttons:
				button.set_enabled(True)

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			release_buttons = (self._mode_index == 1)
			if (self._mode_index < 4):
				self._script._host.set_enabled(False)
				self._script._host._set_button_matrix(None)
				self._script._host._set_alt_button(None)
				self._script._host._set_shift_button(None)
				self._script._host._set_nav_buttons(None)
				if (self._mode_index == 0):				#session
					self._setup_mixer((not as_active))
					self._setup_session(as_active, as_enabled)
				elif (self._mode_index == 1):			#mixer
					self._setup_session((not as_active), as_enabled)
					self._setup_mixer(as_active)
				elif (self._mode_index == 2):			#user1
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
				elif (self._mode_index == 3):			#user2
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
			elif (self._mode_index == 4):				#monomodular
				self._setup_session((not as_active), (not as_enabled))
				self._setup_mixer((not as_active))
				self._setup_user(release_buttons)
				self._script._host._set_button_matrix(self._matrix)
				self._script._host._set_shift_button(self._shift_button)
				self._script._host._set_lock_button(self._modes_buttons[0])
				self._script._host._set_alt_button(self._modes_buttons[1])
				self._script._host._set_nav_buttons(self._nav_buttons)
				self._script._host.set_enabled(True)
			else:
				assert False
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
			self._update_control_channels()
			#self._script.request_rebuild_midi_map()



	def _update_control_channels(self):
		if self._mode_index < 4:
			new_channel = (self._mode_index + self._sub_modes.mode())
			if (new_channel > 0):
				new_channel += 3
		else:
			new_channel = 15
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()




	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(127, 0)
			else:
				button.set_on_off_values(127, 0)

		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active and (self._shift_pressed == 1):
				scene_button = self._matrix.get_button(7, scene_index)
				scene_button.set_on_off_values(127, 0)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(SHIFT[self._shift_pressed]):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, 0)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)


		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)




	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		self._sub_modes.set_enabled(as_active)




	def _setup_user(self, release_buttons):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.turn_off()
			scene_button.set_enabled((not release_buttons))
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_buttons))


		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_buttons))

		self._config_button.send_value(32)
		if release_buttons:
			self._config_button.send_value(2)



	def _init_session(self):
		self._session.set_stop_track_clip_value(3)
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(1)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(4)
				clip_slot.set_triggered_to_record_value(3)
				clip_slot.set_stopped_value(127)
				clip_slot.set_started_value(2)
				clip_slot.set_recording_value(1)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))


		self._zooming.set_stopped_value(127)
		self._zooming.set_selected_value(1)
		self._zooming.set_playing_value(2)
Пример #14
0
class Midi_Fighter_Twister(ControlSurface):
    __doc__ = " Script for Midi_Fighter_Twister in APC emulation mode "

    _active_instances = []

    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in Midi_Fighter_Twister._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._note_map = []
            self._ctrl_map = []
            self._shift_encoder_map = []
            self._shift_bank_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()

    def disconnect(self):
        self._note_map = None
        self._ctrl_map = None
        self._shift_encoder_map = None
        self._shift_bank_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        self._device = None
        ControlSurface.disconnect(self)

    def _do_combine(self):
        if self not in Midi_Fighter_Twister._active_instances:
            Midi_Fighter_Twister._active_instances.append(self)
            Midi_Fighter_Twister._combine_active_instances()

    def _do_uncombine(self):
        if ((self in Midi_Fighter_Twister._active_instances)
                and Midi_Fighter_Twister._active_instances.remove(self)):
            self._session.unlink()
            Midi_Fighter_Twister._combine_active_instances()

    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)

    def _setup_session_control(self):
        is_momentary = True
        # sessionRight = ButtonElement(is_momentary, 1, 3, 11)
        # sessionLeft = ButtonElement(is_momentary, 1, 3, 8)
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(
            self._shift_bank_map[SESSIONRIGHT],
            self._shift_bank_map[SESSIONLEFT])
        # self._session.set_track_bank_buttons(sessionRight, sessionLeft)
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN],
                                             self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN],
                                         self._note_map[SCENEUP])
        self._scene_launch_buttons = [
            self._note_map[SCENELAUNCH[index]] for index in range(4)
        ]
        self._track_stop_buttons = [
            self._note_map[TRACKSTOP[index]] for index in range(4)
        ]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(4):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(4):
                button = self._note_map[CLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP],
                                           self._note_map[ZOOMDOWN],
                                           self._note_map[ZOOMLEFT],
                                           self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        MasterVol = ButtonElement(is_momentary, 1, 4, 3)
        self._mixer = SpecialMixerComponent(4)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT],
                                       self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(
            self._shift_encoder_map[MASTERVOLUME])
        for track in range(4):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]],
                                     self._ctrl_map[TRACKSENDB[track]],
                                     self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)

# have right side btns act as device next/prev & toggle on/off?

    def _setup_device_and_transport_control(self):
        is_momentary = True
        # self._device = DeviceComponent()
        # self._device.name = 'Device_Component'
        # uses BestBankDeviceComponent as pseudo for Device_Component
        self._device = BestBankDeviceComponent(
            device_selection_follows_track_selection=True)
        self._device.name = u'Device_Component'
        # device_bank_buttons = []
        device_param_controls = []
        # Accounts for mappings on top two rows of MFT
        for index in range(16):  # handles all 16 encoder knobs
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
        for index in range(4):  # 1st row, shift encoder hold
            device_param_controls.append(
                self._shift_encoder_map[PARAMCONTROL[index]])
        for index in range(6):  # 2nd row & left-half of 3rd row, CC hold
            device_param_controls.append(self._note_map[PARAMCONTROL[index +
                                                                     4]])
        #  Accounts for mappings on third row of MFT
        # for index in range(4):
        #     device_param_controls.append(self._shift_encoder_map[PARAMCONTROL[index + 8]])
        #     device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        # if None not in device_bank_buttons:
        #     self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._shift_bank_map[DEVICEONOFF])
        # self._device.set_bank_nav_buttons(self._shift_bank_map[DEVICEBANKNAVLEFT], self._shift_bank_map[DEVICEBANKNAVRIGHT])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT],
                                          self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(
            self._shift_bank_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(
            self._shift_bank_map[DETAILVIEW])
        # detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] )
        detail_view_toggler.set_device_nav_buttons(
            self._shift_bank_map[DEVICENAVLEFT],
            self._shift_bank_map[DEVICENAVRIGHT])

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP],
                                    self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._shift_bank_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD],
                                   self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN],
                                    self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        # From Axiom_AIR_25_49_61.py line 202
        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)

        # BEGIN update(self) FROM EncoderModeSelector.py
        #
        # todo: Move this block to a file where 'self._ctrl_map[PARAMCONTROL[index]]'
        # is accessible (MFT see line 164 for example)
        # if self.is_enabled():
        #     self._device.set_allow_update(False)
        # self._mixer.set_allow_update(False)
        # self._device.set_parameter_controls(())
        # self._mixer.set_send_controls(())
        # for index in range(len(self._encoders)):
        # strip = self._mixer.channel_strip(index)
        # encoder = self._encoders[index]
        # strip.set_volume_control(None)
        # strip.set_pan_control(None)
        # encoder.release_parameter()
        # if self._mode_index == 0:
        # strip.set_volume_control(encoder)
        #     encoder.set_on_off_values(AMB_FULL, LED_OFF)
        # elif self._mode_index == 1:
        #     strip.set_pan_control(encoder)
        #     encoder.set_on_off_values(RED_FULL, LED_OFF)
        # elif self._mode_index == 2:
        #     encoder.set_on_off_values(GRN_FULL, LED_OFF)
        # elif self._mode_index == 3:
        #     encoder.set_on_off_values(RED_FULL, LED_OFF)

        # if self._mode_index == 0:
        #     self._modes_buttons[0].send_value(AMB_FULL, True)
        #     self._modes_buttons[1].send_value(LED_OFF, True)
        # elif self._mode_index == 1:
        #     self._modes_buttons[0].send_value(RED_FULL, True)
        #     self._modes_buttons[1].send_value(LED_OFF, True)
        # elif self._mode_index == 2:
        #     self._modes_buttons[0].send_value(GRN_FULL, True)
        #     self._modes_buttons[1].send_value(LED_OFF, True)
        #     self._mixer.set_send_controls(self._encoders)
        # elif self._mode_index == 3:
        #     self._modes_buttons[0].send_value(LED_OFF, True)
        #     self._modes_buttons[1].send_value(RED_FULL, True)
        # self._device.set_parameter_controls(self._encoders)
        # self._device.set_allow_update(True)
        #
        # END update(self) FROM EncoderModeSelector.py

    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (
                        col,
                        row,
                        DRUM_PADS[row * 4 + col],
                        PADCHANNEL,
                    )
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))

    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL,
                                   note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)  # CC Hold, CC Toggle
            shift_bank_button = ButtonElement(is_momentary, MESSAGETYPE,
                                              SHIFTBANKCHANNEL, note)
            shift_bank_button.name = 'Note_' + str(note)
            self._shift_bank_map.append(shift_bank_button)  # Shift Bank
            shift_encoder = ButtonElement(is_momentary, 1, ENCODERSHIFTCHANNEL,
                                          note)
            shift_encoder.name = 'Note_' + str(note)
            self._shift_encoder_map.append(shift_encoder)  # Shift Encoder Hold
        self._note_map.append(
            None)  #add None to the end of the list, selectable with [-1]
        self._shift_encoder_map.append(None)
        self._shift_bank_map.append(None)
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)  # Standard Encoder
            self._ctrl_map.append(None)
Пример #15
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button):
        raise isinstance(matrix, ButtonMatrixElement) or AssertionError
        raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
        raise isinstance(top_buttons, tuple) or AssertionError
        raise len(top_buttons) == 8 or AssertionError
        raise isinstance(side_buttons, tuple) or AssertionError
        raise len(side_buttons) == 8 or AssertionError
        raise isinstance(config_button, ButtonElement) or AssertionError
        ModeSelectorComponent.__init__(self)
        self._session = SpecialSessionComponent(matrix.width(), matrix.height())
        self._zooming = DeprecatedSessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)
        return

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        raise buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes() or AssertionError
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                raise isinstance(button, ButtonElement) or AssertionError
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)
        return

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        if not mode in range(self.number_of_modes()):
            raise AssertionError
            self._mode_index = (self._mode_index != mode or mode == 3) and mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        super(MainSelectorComponent, self).update()
        if not self._modes_buttons != None:
            raise AssertionError
            if self.is_enabled():
                for index in range(len(self._modes_buttons)):
                    self._modes_buttons[index].set_force_next_value()
                    if index == self._mode_index:
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()

                for scene_index in range(8):
                    self._side_buttons[scene_index].set_enabled(True)
                    for track_index in range(8):
                        self._matrix.get_button(track_index, scene_index).set_enabled(True)

                for button in self._nav_buttons:
                    button.set_enabled(True)

                as_active = True
                as_enabled = True
                self._session.set_allow_update(False)
                self._zooming.set_allow_update(False)
                self._config_button.send_value(40)
                self._config_button.send_value(1)
                release_buttons = self._mode_index == 1
                self._mode_index == 0 and self._setup_mixer(not as_active)
                self._setup_session(as_active, as_enabled)
            elif self._mode_index == 1:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 2:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 3:
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
            else:
                raise False or AssertionError
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
        return

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            for button in self._nav_buttons:
                if as_enabled:
                    button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
                else:
                    button.set_on_off_values(127, LED_OFF)

            for scene_index in range(8):
                scene = self._session.scene(scene_index)
                if as_active:
                    scene_button = self._side_buttons[scene_index]
                    scene_button.set_on_off_values(127, LED_OFF)
                    scene.set_launch_button(scene_button)
                else:
                    scene.set_launch_button(None)
                for track_index in range(8):
                    if as_active:
                        button = self._matrix.get_button(track_index, scene_index)
                        button.set_on_off_values(127, LED_OFF)
                        scene.clip_slot(track_index).set_launch_button(button)
                    else:
                        scene.clip_slot(track_index).set_launch_button(None)

            if as_active:
                self._zooming.set_zoom_button(self._modes_buttons[0])
                self._zooming.set_button_matrix(self._matrix)
                self._zooming.set_scene_bank_buttons(self._side_buttons)
                self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
                self._zooming.update()
            else:
                self._zooming.set_zoom_button(None)
                self._zooming.set_button_matrix(None)
                self._zooming.set_scene_bank_buttons(None)
                self._zooming.set_nav_buttons(None, None, None, None)
            as_enabled and self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
        return

    def _setup_mixer(self, as_active):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            as_active and self._sub_modes.is_enabled() and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force=True)

    def _init_session(self):
        self._session.set_stop_clip_value(AMBER_THIRD)
        self._session.set_stop_clip_triggered_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)
Пример #16
0
class KontrolF1(ControlSurface):
    __module__ = __name__
    __doc__ = " Script for Native Instruments Traktor Kontrol F1 Controller "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.set_suppress_rebuild_requests(True)
        self._suppress_send_midi = True
        self._suppress_session_highlight = True

        self._suggested_input_port = 'Traktor Kontrol F1'
        self._suggested_output_port = 'Traktor Kontrol F1'

        self._blink_state = False

        self._matrix = ButtonMatrixElement()
        for row in range(HEIGHT):
            button_row = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 2, ((row * HEIGHT) + column)) for column in range(WIDTH) ]
            self._matrix.add_row(tuple(button_row))

        self._nav_buttons  = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, NAV_ENCODER),
                               ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, TOGGLE_LEFT_DOWN) ]
        self._scene_buttons = [ ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, SCENE_LAUNCH[index]) for index in range(HEIGHT) ]
        
        self._stop_buttons = []
        for index in range(WIDTH):
            self._stop_buttons.append(ConfigurableButtonElement(c_instance, True, MIDI_CC_TYPE, 0, STOP_LAUNCH[index]))
        
        self._session = SpecialSessionComponent(self._matrix.width(), self._matrix.height())

        self._all_buttons = []
        for button in (self._scene_buttons + self._nav_buttons + self._stop_buttons):
            self._all_buttons.append(button)

        for scene_index in range(self._matrix.height()):
            for track_index in range(self._matrix.width()):
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))
        self._all_buttons = tuple(self._all_buttons)



        self._suppress_session_highlight = False
        self.set_suppress_rebuild_requests(False)
        self._suppress_send_midi = False
        self.set_enabled(True)
        self.update()
        self._set_session_highlight(0,0,WIDTH,HEIGHT,True)

    def disconnect(self):
        self._suppress_send_midi = True

        self._session = None
        for button in self._all_buttons:
            button.set_on_off_values(127, 0)

        self._matrix = None
        self._stop_buttons = None
        self._scene_buttons = None
        self._nav_buttons = None

        ControlSurface.disconnect(self)
        self._suppress_send_midi = False

    def update_display(self):
        tracks = self.song().visible_tracks
        number_tracks = len(tracks)

        if self._blink_state:
            self._blink_state = False
        else:
            self._blink_state = True

        for track in range(WIDTH):
            to = track + self._session._track_offset
            if (to < number_tracks):
                for y in range(HEIGHT):
                    ys = self._session._scene_offset+y
                    yx = (y*4)+track
                    slot = tracks[to].clip_slots[ys]
                    if (slot.controls_other_clips) or (slot.has_clip):
                        if slot.is_triggered:
                            if self._blink_state:
                                self._send_midi(tuple([178,yx,40]))
                            else:
                                self._send_midi(tuple([178,yx,127]))
               


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

    def _send_midi(self, midi_bytes):
        if (not self._suppress_send_midi):
            ControlSurface._send_midi(self, midi_bytes)

    def _update_hardware(self):
        pass

    def _send_challenge(self):
        pass

    def _config_value(self, value):
        assert (value in range(128))

    def _set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks):
        ControlSurface._set_session_highlight(self, track_offset, scene_offset, width, height, include_return_tracks)

    def _install_forwarding(self, control):
        result = ControlSurface._install_forwarding(self, control)
        return result

    def _translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel):
        ControlSurface._translate_message(self, type, from_identifier, from_channel, to_identifier, to_channel)


    def on_enabled_changed(self):
        self.update()

    def update(self):
        for scene_index in range(HEIGHT):
            self._scene_buttons[scene_index].set_enabled(True)
            self._stop_buttons[scene_index].set_enabled(True)
            for track_index in range(WIDTH):
                self._matrix.get_button(track_index, scene_index).set_enabled(True)


        for button in self._nav_buttons:
            button.set_enabled(True)

        self._session.set_allow_update(False)


        for scene_index in range(HEIGHT):
            scene = self._session.scene(scene_index)
            scene.set_launch_button(self._scene_buttons[scene_index])
            for track_index in range(WIDTH):
                scene.clip_slot(track_index).set_launch_button(self._matrix.get_button(track_index, scene_index))

        #self.log_message(str(tuple(self._stop_buttons)))
        self._session.set_stop_track_clip_buttons(tuple(self._stop_buttons))
        self._session.set_track_bank_buttons(self._nav_buttons[1], self._nav_buttons[1])
        self._session.set_scene_bank_buttons(self._nav_buttons[0], self._nav_buttons[0])
        self._session.set_allow_update(True)
Пример #17
0
class Orsi(ControlSurface):
    __doc__ = " Script for FCB1010 in APC emulation mode "

    _active_instances = []

    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in Orsi._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()

    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self._note_map_scenes = []
            self._note_map_buttons = []
            self._ctrl_map_sliders = []
            self._note_map_trk_stop_buttons = []
            self._note_map_trk_sel_buttons = []
            self._note_map_trk_mute_buttons = []
            self._note_map_trk_solo_buttons = []
            self._note_map_trk_rec_buttons = []
            self._ctrl_map_trk_volume = []
            self._ctrl_map_trk_pan = []
            self._ctrl_map_senda = []
            self._ctrl_map_sendb = []
            self._ctrl_map_sendc = []
            self._note_map_bank_buttons = []
            self._ctrl_map_parameter = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()

    def disconnect(self):
        self._note_map_scenes = None
        self._note_map_buttons = None
        self._ctrl_map_sliders = None
        self._note_map_trk_stop_buttons = None
        self._note_map_trk_sel_buttons = None
        self._note_map_trk_mute_buttons = None
        self._note_map_trk_solo_buttons = None
        self._note_map_trk_rec_buttons = None
        self._ctrl_map_trk_volume = None
        self._ctrl_map_trk_pan = None
        self._ctrl_map_senda = None
        self._ctrl_map_sendb = None
        self._ctrl_map_sendc = None
        self._note_map_bank_buttons = None
        self._ctrl_map_parameter = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)

    def _do_combine(self):
        if self not in Orsi._active_instances:
            Orsi._active_instances.append(self)
            Orsi._combine_active_instances()

    def _do_uncombine(self):
        if ((self in Orsi._active_instances)
                and Orsi._active_instances.remove(self)):
            self._session.unlink()
            Orsi._combine_active_instances()

    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)

    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(TRACK_NUMBER, MATRIX_DEPTH)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map_buttons[25],
                                             self._note_map_buttons[24])
        self._session.set_scene_bank_buttons(self._note_map_buttons[27],
                                             self._note_map_buttons[26])
        self._session.set_select_buttons(self._note_map_buttons[34],
                                         self._note_map_buttons[35])
        self._scene_launch_buttons = [
            self._note_map_scenes[index] for index in range(MATRIX_DEPTH)
        ]
        self._track_stop_buttons = [
            self._note_map_trk_stop_buttons[index]
            for index in range(TRACK_NUMBER)
        ]
        self._session.set_stop_all_clips_button(self._note_map_buttons[38])
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            self._note_map_buttons[36])
        self._session.set_slot_launch_button(self._note_map_buttons[37])
        for scene_index in range(MATRIX_DEPTH):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(TRACK_NUMBER):
                if (CLIPNOTEMAP[scene_index][track_index] == -1):
                    button = None
                else:
                    button = ButtonElement(
                        is_momentary,
                        CLIPNOTEMAP_TYPE[scene_index][track_index],
                        CLIPNOTEMAP_CH[scene_index][track_index],
                        CLIPNOTEMAP[scene_index][track_index])
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map_buttons[28],
                                           self._note_map_buttons[29],
                                           self._note_map_buttons[30],
                                           self._note_map_buttons[31])

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(TRACK_NUMBER)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(
            self._note_map_buttons[39])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map_buttons[33],
                                       self._note_map_buttons[32])
        self._mixer.set_crossfader_control(self._ctrl_map_sliders[2])
        self._mixer.set_prehear_volume_control(self._ctrl_map_sliders[1])
        self._mixer.master_strip().set_volume_control(
            self._ctrl_map_sliders[0])
        for track in range(TRACK_NUMBER):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map_trk_rec_buttons[track])
            strip.set_solo_button(self._note_map_trk_solo_buttons[track])
            strip.set_mute_button(self._note_map_trk_mute_buttons[track])
            strip.set_select_button(self._note_map_trk_sel_buttons[track])
            strip.set_volume_control(self._ctrl_map_trk_volume[track])
            strip.set_pan_control(self._ctrl_map_trk_pan[track])
            strip.set_send_controls(
                (self._ctrl_map_senda[track], self._ctrl_map_sendb[track],
                 self._ctrl_map_sendc[track]))
            strip.set_invert_mute_feedback(True)

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(PARAMS_NUMBER):
            device_param_controls.append(self._ctrl_map_parameter[index])
        for index in range(BANKS_NUMBER):
            device_bank_buttons.append(self._note_map_bank_buttons[index])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        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_buttons[17])
        self._device.set_bank_nav_buttons(self._note_map_buttons[20],
                                          self._note_map_buttons[21])
        self._device.set_lock_button(self._note_map_buttons[16])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(
            self._note_map_buttons[15])
        detail_view_toggler.set_detail_toggle_button(
            self._note_map_buttons[14])
        detail_view_toggler.set_device_nav_buttons(self._note_map_buttons[18],
                                                   self._note_map_buttons[19])

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map_buttons[0])
        transport.set_stop_button(self._note_map_buttons[1])
        transport.set_record_button(self._note_map_buttons[2])
        transport.set_nudge_buttons(self._note_map_buttons[4],
                                    self._note_map_buttons[5])
        transport.set_undo_button(self._note_map_buttons[6])
        transport.set_redo_button(self._note_map_buttons[7])
        transport.set_tap_tempo_button(self._note_map_buttons[3])
        transport.set_quant_toggle_button(self._note_map_buttons[13])
        transport.set_overdub_button(self._note_map_buttons[11])
        transport.set_metronome_button(self._note_map_buttons[12])
        transport.set_tempo_control(self._ctrl_map_sliders[3])
        transport.set_loop_button(self._note_map_buttons[8])
        transport.set_seek_buttons(self._note_map_buttons[22],
                                   self._note_map_buttons[23])
        transport.set_punch_buttons(self._note_map_buttons[9],
                                    self._note_map_buttons[10])

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(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)

    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(PAD_Y_NUMBER):
                for col in range(PAD_X_NUMBER):
                    pad = (
                        col,
                        row,
                        DRUM_PADS[row * 4 + col],
                        PADCHANNEL,
                    )
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))

    def _load_MIDI_map(self):
        is_momentary = True
        # SCENELAUNCH Buttons
        for scene_id in range(MATRIX_DEPTH):
            if (SCENELAUNCH[scene_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary,
                                       SCENELAUNCH_TYPE[scene_id],
                                       SCENELAUNCH_CH[scene_id],
                                       SCENELAUNCH[scene_id])
                button.name = 'Scene_' + str(scene_id)
            self._note_map_scenes.append(button)
        # BUTTON_VECTOR Buttons
        for button_id in range(NUMBER_BUTTONS):
            if (BUTTON_VECTOR[button_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary,
                                       BUTTON_VECTOR_TYPE[button_id],
                                       BUTTON_VECTOR_CH[button_id],
                                       BUTTON_VECTOR[button_id])
                button.name = 'Global_Button_' + str(button_id)
            self._note_map_buttons.append(button)
        # SLIDER_VECTOR Sliders
        for slider_id in range(NUMBER_SLIDERS):
            if (SLIDER_VECTOR[slider_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE,
                                        SLIDER_VECTOR_CH[slider_id],
                                        SLIDER_VECTOR[slider_id])
                control.name = 'Global_Slider_' + str(slider_id)
            self._ctrl_map_sliders.append(control)
        # TRACKSTOP Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSTOP[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSTOP_TYPE[track_id],
                                       TRACKSTOP_CH[track_id],
                                       TRACKSTOP[track_id])
                button.name = 'Trk_Stop_Button_' + str(track_id)
            self._note_map_trk_stop_buttons.append(button)
        # TRACKSEL Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSEL[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSEL_TYPE[track_id],
                                       TRACKSEL_CH[track_id],
                                       TRACKSEL[track_id])
                button.name = 'Trk_Sel_Button_' + str(track_id)
            self._note_map_trk_sel_buttons.append(button)
        # TRACKMUTE Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKMUTE[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKMUTE_TYPE[track_id],
                                       TRACKMUTE_CH[track_id],
                                       TRACKMUTE[track_id])
                button.name = 'Trk_Mute_Button_' + str(track_id)
            self._note_map_trk_mute_buttons.append(button)
        # TRACKSOLO Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSOLO[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSOLO_TYPE[track_id],
                                       TRACKSOLO_CH[track_id],
                                       TRACKSOLO[track_id])
                button.name = 'Trk_Solo_Button_' + str(track_id)
            self._note_map_trk_solo_buttons.append(button)
        # TRACKREC Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKREC[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKREC_TYPE[track_id],
                                       TRACKREC_CH[track_id],
                                       TRACKREC[track_id])
                button.name = 'Trk_Rec_Button_' + str(track_id)
            self._note_map_trk_rec_buttons.append(button)
        # TRACKVOL Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKVOL[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKVOL_CH[track_id],
                                        TRACKVOL[track_id])
                control.name = 'Trk_Vol_Slider_' + str(track_id)
            self._ctrl_map_trk_volume.append(control)
        # TRACKPAN Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKPAN[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKPAN_CH[track_id],
                                        TRACKPAN[track_id])
                control.name = 'Trk_Pan_Slider_' + str(track_id)
            self._ctrl_map_trk_pan.append(control)
        # TRACKSENDA Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDA[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDA_CH[track_id],
                                        TRACKSENDA[track_id])
                control.name = 'Trk_SendA_Slider_' + str(track_id)
            self._ctrl_map_senda.append(control)
        # TRACKSENDB Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDB[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDB_CH[track_id],
                                        TRACKSENDB[track_id])
                control.name = 'Trk_SendB_Slider_' + str(track_id)
            self._ctrl_map_sendb.append(control)
        # TRACKSENDC Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDC[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDC_CH[track_id],
                                        TRACKSENDC[track_id])
                control.name = 'Trk_SendC_Slider_' + str(track_id)
            self._ctrl_map_sendc.append(control)
        # DEVICEBANK Buttons
        for bank_id in range(BANKS_NUMBER):
            if (DEVICEBANK[bank_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, DEVICEBANK_TYPE[bank_id],
                                       DEVICEBANK_CH[bank_id],
                                       DEVICEBANK[bank_id])
                button.name = 'Bank_Button_' + str(bank_id)
            self._note_map_bank_buttons.append(button)
        # PARAMCONTROL Sliders
        for param_id in range(PARAMS_NUMBER):
            if (PARAMCONTROL[param_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE,
                                        PARAMCONTROL_CH[param_id],
                                        PARAMCONTROL[param_id])
                control.name = 'Slider_Param_' + str(param_id)
            self._ctrl_map_parameter.append(control)
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def __init__(self, matrix, top_buttons, side_buttons, config_button,
                 script):
        assert isinstance(matrix, ButtonMatrixElement)
        assert matrix.width() == 8 and matrix.height() == 8
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._script = script
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        for scene in self._session._scenes:
            for slot in scene._clip_slots:
                slot._triggered_to_play_value = 24
                slot._triggered_to_record_value = 27
                slot._started_value = 7
                slot._recording_value = 9
                slot._stopped_value = 8
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._zooming._stopped_value = 9
        self._zooming._playing_value = 7
        self._zooming._selected_value = 8
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        assert buttons == None or isinstance(
            buttons, tuple) or len(buttons) == self.number_of_modes()
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)

    def number_of_modes(self):
        return 5

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        assert (mode in range(self.number_of_modes()))
        if ((self._mode_index != mode) or (mode == 3)):
            self._mode_index = mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            #for index in range(len(self._modes_buttons)):
            #	self._modes_buttons[index].set_force_next_value()
            #	if index == self._mode_index:
            #		self._modes_buttons[index].turn_on()
            #	else:
            #		self._modes_buttons[index].turn_off()

            for scene_index in range(8):
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    self._matrix.get_button(track_index,
                                            scene_index).set_enabled(True)

            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = self._mode_index == 1
            if (self._mode_index < 4):
                self._script._host._set_key_buttons(None)
                self._script._host.set_enabled(False)
                self._script._host._set_button_matrix(None)
                self._script._host._set_alt_button(None)
                self._script._host._set_shift_button(None)
                self._script._host._set_nav_buttons(None)
                for button in self._modes_buttons:
                    button.set_on_off_values(5, 0)

                if self._mode_index == 0:
                    self._setup_mixer(not as_active)
                    self._setup_session(as_active, as_enabled)
                elif self._mode_index == 1:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 2:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 3:
                    self._setup_session(not as_active, as_enabled)
                    self._setup_mixer(as_active)
            elif (self._mode_index == 4):
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_user(release_buttons)
                self._script._host._set_button_matrix(self._matrix)
                self._script._host._set_key_buttons(self._side_buttons)
                self._script._host._set_shift_button(self._modes_buttons[0])
                self._script._host._set_lock_button(self._modes_buttons[1])
                self._script._host._set_alt_button(self._modes_buttons[2])
                self._modes_buttons[3].send_value(9)
                self._script._host._set_nav_buttons(self._nav_buttons)
                self._script._host.set_enabled(True)
            else:
                assert False
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
            if (self._mode_index < 4):
                for index in range(len(self._modes_buttons)):
                    if (index == self._mode_index):
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()
            #self._script.request_rebuild_midi_map()
            self._script.schedule_message(1, self._session.update)

    def _update_control_channels(self):
        if self._mode_index < 4:
            new_channel = self.channel_for_current_mode()
        else:
            new_channel = 15
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
            #self._session.set_show_highlight(True)			#Needs to be replaced with L9 equivalent
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            #self._session.set_show_highlight(False)		#Needs to be replaced with L9 equivalent

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        as_active and self._sub_modes.is_enabled(
        ) and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force_send=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    """Mono Overrides and Additions"""

    def _mode_value(self, value, sender):
        assert (len(self._modes_buttons) > 0)
        assert isinstance(value, int)
        assert isinstance(sender, ButtonElement)
        assert (self._modes_buttons.count(sender) == 1)
        if self._script._host.is_enabled() != True:
            if ((value is not 0) or (not sender.is_momentary())):
                if ((self._modes_buttons[1]._last_received_value > 0) and
                    (self._modes_buttons.index(sender) == 2)) or (
                        (self._modes_buttons[2]._last_received_value > 0) and
                        (self._modes_buttons.index(sender) == 1)):
                    if (self._script._host._active_client != None):
                        self.set_mode(4)
                    else:
                        self._script.show_message(
                            'Monomodular Script not inserted')
                else:
                    self.set_mode(self._modes_buttons.index(sender))
        else:
            if self._modes_buttons.index(sender) == 3 and value > 0:
                self.set_mode(0)
Пример #19
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    def __init__(self, matrix, top_buttons, side_buttons, config_button, script):
        assert isinstance(matrix, ButtonMatrixElement)
        assert matrix.width() == 8 and matrix.height() == 8
        assert isinstance(top_buttons, tuple)
        assert len(top_buttons) == 8
        assert isinstance(side_buttons, tuple)
        assert len(side_buttons) == 8
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)
        self._script = script
        self._session = SpecialSessionComponent(matrix.width(), matrix.height())
        """for scene in self._session._scenes:
			for slot in scene._clip_slots:
				slot._triggered_to_play_value = 24
				slot._triggered_to_record_value = 27
				slot._started_value = 7
				slot._recording_value = 9
				slot._stopped_value = 8"""
        self._zooming = SessionZoomingComponent(self._session)
        self._session.name = "Session_Control"
        self._zooming.name = "Session_Overview"
        """self._zooming._stopped_value = 9
		self._zooming._playing_value = 7
		self._zooming._selected_value = 8"""
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
        self._sub_modes.name = "Mixer_Modes"
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])
        if START_IN_MOD is True:
            self._set_protected_mode_index(4)

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        assert buttons == None or isinstance(buttons, tuple) or len(buttons) == self.number_of_modes()
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                assert isinstance(button, ButtonElement)
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)

    def number_of_modes(self):
        return 5

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        assert mode in range(self.number_of_modes())
        if (self._mode_index != mode) or (mode == 3):
            self._mode_index = mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        assert self._modes_buttons != None
        if self.is_enabled():

            # for index in range(len(self._modes_buttons)):
            # 	self._modes_buttons[index].set_force_next_value()
            # 	if index == self._mode_index:
            # 		self._modes_buttons[index].turn_on()
            # 	else:
            # 		self._modes_buttons[index].turn_off()

            for scene_index in range(8):
                self._side_buttons[scene_index].set_enabled(True)
                for track_index in range(8):
                    self._matrix.get_button(track_index, scene_index).set_enabled(True)

            for button in self._nav_buttons:
                button.set_enabled(True)

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(40)
            self._config_button.send_value(1)
            release_buttons = self._mode_index == 1
            if self._mode_index < 4:
                self._script._suppress_session_highlight = False
                self._session.set_show_highlight(True)
                # self._script.set_highlighting_session_component(self.session_component())
                self._script._host._set_key_buttons(None)
                self._script._host.set_enabled(False)
                self._script._host._set_button_matrix(None)
                self._script._host._set_alt_button(None)
                self._script._host._set_shift_button(None)
                self._script._host._set_nav_buttons(None)
                for button in self._modes_buttons:
                    button.set_on_off_values(127, 4)

                if self._mode_index == 0:
                    self._setup_mixer(not as_active)
                    self._setup_session(as_active, as_enabled)
                elif self._mode_index == 1:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 2:
                    self._setup_session(not as_active, not as_enabled)
                    self._setup_mixer(not as_active)
                    self._setup_user(release_buttons)
                elif self._mode_index == 3:
                    self._setup_session(not as_active, as_enabled)
                    self._setup_mixer(as_active)
            elif self._mode_index == 4:
                # self._script.set_highlighting_session_component(None)
                self._session.set_show_highlight(False)
                self._script._suppress_session_highlight = True
                self._setup_session((not as_active), (not as_enabled))
                self._setup_mixer((not as_active))
                self._setup_user(release_buttons)
                self._script._host._set_button_matrix(self._matrix)
                self._script._host._set_key_buttons(self._side_buttons)
                self._script._host._set_shift_button(self._modes_buttons[0])
                self._script._host._set_lock_button(self._modes_buttons[1])
                self._script._host._set_alt_button(self._modes_buttons[2])
                self._modes_buttons[3].send_value(9)
                self._script._host._set_nav_buttons(self._nav_buttons)
                self._script._host.set_enabled(True)
            else:
                assert False
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()
            if self._mode_index < 4:
                for index in range(len(self._modes_buttons)):
                    if index == self._mode_index:
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()
                        # self._script.request_rebuild_midi_map()
            self._script.schedule_message(1, self._session.update)

    def _update_control_channels(self):
        if self._mode_index < 4:
            new_channel = self.channel_for_current_mode()
        else:
            new_channel = 15
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        assert isinstance(as_active, type(False))
        for button in self._nav_buttons:
            if as_enabled:
                button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
            else:
                button.set_on_off_values(127, LED_OFF)

        for scene_index in range(8):
            scene = self._session.scene(scene_index)
            if as_active:
                scene_button = self._side_buttons[scene_index]
                scene_button.set_on_off_values(127, LED_OFF)
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)
            for track_index in range(8):
                if as_active:
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values(127, LED_OFF)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:
            self._zooming.set_zoom_button(self._modes_buttons[0])
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(
                self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3]
            )
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)
        if as_enabled:
            self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
            # self._session.set_show_highlight(True)			#Needs to be replaced with L9 equivalent
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            # self._session.set_show_highlight(False)		#Needs to be replaced with L9 equivalent

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        as_active and self._sub_modes.is_enabled() and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force=True)

    def _init_session(self):
        self._session.set_stop_track_clip_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = "Scene_" + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index)
                self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)

    """Mono Overrides and Additions"""

    def _mode_value(self, value, sender):
        assert len(self._modes_buttons) > 0
        assert isinstance(value, int)
        assert isinstance(sender, ButtonElement)
        assert self._modes_buttons.count(sender) == 1
        if self._script._host.is_enabled() != True:
            if (value is not 0) or (not sender.is_momentary()):
                if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or (
                    (self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1)
                ):
                    if self._script._host._active_client != None:
                        self.set_mode(4)
                    else:
                        self._script.show_message("Monomodular Script not inserted")
                else:
                    self.set_mode(self._modes_buttons.index(sender))
        else:
            if self._modes_buttons.index(sender) == 3 and value > 0:
                self.set_mode(0)
Пример #20
0
class FCB1020(ControlSurface):
    __doc__ = " Script for FCB1010 in APC emulation mode "

    _active_instances = []
    def _combine_active_instances():
        track_offset = 0
        scene_offset = 0
        for instance in FCB1020._active_instances:
            instance._activate_combination_mode(track_offset, scene_offset)
            track_offset += instance._session.width()
    _combine_active_instances = staticmethod(_combine_active_instances)

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self.set_suppress_rebuild_requests(True)
        with self.component_guard():
            self._note_map = []
            self._ctrl_map = []
            self._load_MIDI_map()
            self._session = None
            self._session_zoom = None
            self._mixer = None
            self._setup_session_control()
            self._setup_mixer_control()
            self._session.set_mixer(self._mixer)
            self._setup_device_and_transport_control()
            self.set_highlighting_session_component(self._session)
            #self.set_suppress_rebuild_requests(False)
        self._pads = []
        self._load_pad_translations()
        self._do_combine()


    def disconnect(self):
        self._note_map = None
        self._ctrl_map = None
        self._pads = None
        self._do_uncombine()
        self._shift_button = None
        self._session = None
        self._session_zoom = None
        self._mixer = None
        ControlSurface.disconnect(self)


    def _do_combine(self):
        if self not in FCB1020._active_instances:
            FCB1020._active_instances.append(self)
            FCB1020._combine_active_instances()


    def _do_uncombine(self):
        if ((self in FCB1020._active_instances) and FCB1020._active_instances.remove(self)):
            self._session.unlink()
            FCB1020._combine_active_instances()


    def _activate_combination_mode(self, track_offset, scene_offset):
        if TRACK_OFFSET != -1:
            track_offset = TRACK_OFFSET
        if SCENE_OFFSET != -1:
            scene_offset = SCENE_OFFSET
        self._session.link_with_track_offset(track_offset, scene_offset)


    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._note_map[SESSIONRIGHT], self._note_map[SESSIONLEFT])
        self._session.set_scene_bank_buttons(self._note_map[SESSIONDOWN], self._note_map[SESSIONUP])
        self._session.set_select_buttons(self._note_map[SCENEDN], self._note_map[SCENEUP])
        self._scene_launch_buttons = [self._note_map[SCENELAUNCH[index]] for index in range(5) ]
        self._track_stop_buttons = [self._note_map[TRACKSTOP[index]] for index in range(8) ]
        self._session.set_stop_all_clips_button(self._note_map[STOPALLCLIPS])
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(self._note_map[SELSCENELAUNCH])
        self._session.set_slot_launch_button(self._note_map[SELCLIPLAUNCH])
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = self._note_map[CLIPNOTEMAP[scene_index][track_index]]
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_launch_button(button)
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._note_map[ZOOMUP], self._note_map[ZOOMDOWN], self._note_map[ZOOMLEFT], self._note_map[ZOOMRIGHT])

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_select_button(self._note_map[MASTERSEL])
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.set_select_buttons(self._note_map[TRACKRIGHT], self._note_map[TRACKLEFT])
        self._mixer.set_crossfader_control(self._ctrl_map[CROSSFADER])
        self._mixer.set_prehear_volume_control(self._ctrl_map[CUELEVEL])
        self._mixer.master_strip().set_volume_control(self._ctrl_map[MASTERVOLUME])
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            strip.set_arm_button(self._note_map[TRACKREC[track]])
            strip.set_solo_button(self._note_map[TRACKSOLO[track]])
            strip.set_mute_button(self._note_map[TRACKMUTE[track]])
            strip.set_select_button(self._note_map[TRACKSEL[track]])
            strip.set_volume_control(self._ctrl_map[TRACKVOL[track]])
            strip.set_pan_control(self._ctrl_map[TRACKPAN[track]])
            strip.set_send_controls((self._ctrl_map[TRACKSENDA[track]], self._ctrl_map[TRACKSENDB[track]], self._ctrl_map[TRACKSENDC[track]]))
            strip.set_invert_mute_feedback(True)


    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        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])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_device_clip_toggle_button(self._note_map[CLIPTRACKVIEW])
        detail_view_toggler.set_detail_toggle_button(self._note_map[DETAILVIEW])
        detail_view_toggler.set_device_nav_buttons(self._note_map[DEVICENAVLEFT], self._note_map[DEVICENAVRIGHT] )

        transport = SpecialTransportComponent()
        transport.name = 'Transport'
        transport.set_play_button(self._note_map[PLAY])
        transport.set_stop_button(self._note_map[STOP])
        transport.set_record_button(self._note_map[REC])
        transport.set_nudge_buttons(self._note_map[NUDGEUP], self._note_map[NUDGEDOWN])
        transport.set_undo_button(self._note_map[UNDO])
        transport.set_redo_button(self._note_map[REDO])
        transport.set_tap_tempo_button(self._note_map[TAPTEMPO])
        transport.set_quant_toggle_button(self._note_map[RECQUANT])
        transport.set_overdub_button(self._note_map[OVERDUB])
        transport.set_metronome_button(self._note_map[METRONOME])
        transport.set_tempo_control(self._ctrl_map[TEMPOCONTROL])
        transport.set_loop_button(self._note_map[LOOP])
        transport.set_seek_buttons(self._note_map[SEEKFWD], self._note_map[SEEKRWD])
        transport.set_punch_buttons(self._note_map[PUNCHIN], self._note_map[PUNCHOUT])
        ##transport.set_song_position_control(self._ctrl_map[SONGPOSITION]) #still not implemented as of Live 8.1.6


    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(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)


    def _load_pad_translations(self):
        if -1 not in DRUM_PADS:
            pad = []
            for row in range(4):
                for col in range(4):
                    pad = (col, row, DRUM_PADS[row*4 + col], PADCHANNEL,)
                    self._pads.append(pad)
            self.set_pad_translations(tuple(self._pads))


    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)
        self._note_map.append(None) #add None to the end of the list, selectable with [-1]
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
Пример #21
0
class Serato(ControlSurface):

    def __init__(self, c_instance):
        publish_in_cs_list = True
        ControlSurface.__init__(self, c_instance, not publish_in_cs_list)
        self._device_selection_follows_track_selection = True
        with self.component_guard():
            self._matrix = None
            self._session = None
            self._mixer = None
            self._device = None
            self._scene_launch_buttons = None
            self._track_arm_buttons = None
            self._track_solo_buttons = None
            self._track_mute_buttons = None
            self._track_stop_buttons = None
            self._track_select_buttons = None
            self._device_on_off_button = None
            self._shift_button = None
            self._serato_interface = PySCAClipControl()
            self._serato_interface.PySCA_InitializeClipControl()
            self._setup_session_control()
            self._setup_mixer_control()
            self._setup_device_control()
            self._session.set_mixer(self._mixer)
            self.set_highlighting_session_component(self._session)

    def disconnect(self):
        ControlSurface.disconnect(self)
        self._serato_interface.PySCA_DeinitializeClipControl()
        self._serato_interface = None

    def connect_script_instances(self, instanciated_scripts):
        """ Called by the Application as soon as all scripts are initialized.
            You can connect yourself to other running scripts here, as we do it
            connect the extension modules (MackieControlXTs).
        """
        for control_surface in self._control_surfaces():
            control_surface_session = control_surface.highlighting_session_component()
            if control_surface_session:
                self._session.sync_to(control_surface_session)
                self._on_track_list_changed()
                break

    def build_midi_map(self, midi_map_handle):
        pass

    def update_display(self):
        ControlSurface.update_display(self)
        while self._serato_interface.PySCA_HasIncomingEvent():
            new_event = self._serato_interface.PySCA_GetIncomingEvent()
            if not self._handle_session_event(new_event):
                if not self._handle_mixer_event(new_event):
                    if not self._handle_device_event(new_event):
                        print 'Unhandled Event: ' + str(new_event)

    def _setup_session_control(self):
        is_momentary = True
        self._session = SpecialSessionComponent(NUM_TRACKS, NUM_SCENES)
        self._session.set_serato_interface(self._serato_interface)
        self._matrix = ButtonMatrixElement()
        self._scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_SCENES) ]
        self._track_stop_buttons = [ ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0) for index in range(NUM_TRACKS) ]
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0)
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        for scene_index in range(NUM_SCENES):
            scene = self._session.scene(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_index(scene_index)
            scene.set_serato_interface(self._serato_interface)
            for track_index in range(NUM_TRACKS):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0)
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_launch_button(button)
                clip_slot.set_serato_interface(self._serato_interface)

            self._matrix.add_row(tuple(button_row))

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(NUM_TRACKS)
        self._mixer.set_serato_interface(self._serato_interface)
        self._mixer.master_strip().set_serato_interface(self._serato_interface)
        self._track_arm_buttons = []
        self._track_solo_buttons = []
        self._track_mute_buttons = []
        self._track_select_buttons = []
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 0)
        for track in range(NUM_TRACKS):
            strip = self._mixer.channel_strip(track)
            strip.set_serato_interface(self._serato_interface)
            self._track_arm_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            self._track_solo_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            self._track_mute_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            self._track_select_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0))
            strip.set_arm_button(self._track_arm_buttons[-1])
            strip.set_solo_button(self._track_solo_buttons[-1])
            strip.set_mute_button(self._track_mute_buttons[-1])
            strip.set_select_button(self._track_select_buttons[-1])
            strip.set_shift_button(self._shift_button)

    def _setup_device_control(self):
        is_momentary = True
        self._device_on_off_button = ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 0)
        self._device = SpecialDeviceComponent()
        self._device.set_serato_interface(self._serato_interface)
        self._device.set_parameter_controls(tuple([ SliderElement(MIDI_CC_TYPE, 0, 0) for index in range(NUM_PARAMS) ]))
        self._device.set_on_off_button(self._device_on_off_button)
        self.set_device_component(self._device)

    def _handle_session_event(self, event):
        result = False
        if event.type in CLIP_EVENTS:
            value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventClipPlayedDown)
            track_index = event.key1 - 1
            scene_index = event.key2 - 1
            if track_index in range(NUM_TRACKS) and scene_index in range(NUM_SCENES):
                self._matrix.get_button(track_index, scene_index).receive_value(value)
            result = True
        elif event.type in SCENE_EVENTS:
            value = 127 * int(event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventScenePlayedDown)
            scene_index = event.key1 - 1
            if scene_index in range(NUM_SCENES):
                self._scene_launch_buttons[scene_index].receive_value(value)
            result = True
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixSizeChanged:
            new_width = event.key1
            new_height = event.key2
            self._session.set_size(new_width, new_height)
            result = True
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlMatrixOffsetChanged:
            x_increment = event.key1
            y_increment = event.key2
            self._session.move_by(x_increment, y_increment)
            result = True
        return result

    def _handle_mixer_event(self, event):
        result = True
        track_index = event.key1 - 1
        value = event.key2
        if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackMasterGainChange:
            self._mixer.master_strip().set_track_volume(fixed_value(value))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackStopped:
            self.song().stop_all_clips()
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventMasterTrackSelect:
            self.song().view.selected_track = self.song().master_track
        else:
            result = track_index in range(NUM_TRACKS) and self._handle_strip_event(event)
        return result

    def _handle_strip_event(self, event):
        result = True
        track_index = event.key1 - 1
        value = event.key2
        if value == 0:
            self._shift_button.receive_value(127)
        if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSolo:
            self._track_solo_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackRecord:
            self._track_arm_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackActive:
            self._track_mute_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackStopped:
            self._track_stop_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSelect:
            self._track_select_buttons[track_index].receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackGainChange:
            self._mixer.channel_strip(track_index).set_track_volume(fixed_value(value))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendAChange:
            self._mixer.channel_strip(track_index).set_send(0, fixed_value(value))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventTrackSendBChange:
            self._mixer.channel_strip(track_index).set_send(1, fixed_value(value))
        else:
            result = False
        self._shift_button.receive_value(0)
        return result

    def _handle_device_event(self, event):
        result = True
        if event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceValueChanged:
            self._device.set_parameter_value(event.key1 - 1, fixed_value(event.key2))
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceActivate:
            self._device_on_off_button.receive_value(127)
        elif event.type == libInterprocessCommsAPIPython.kAbletonClipControlEventDeviceFocusMove:
            self._move_device_focus(event.key1)
        else:
            result = False
        return result

    def _move_device_focus(self, increment):
        if not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain'):
            self.application().view.show_view('Detail')
            self.application().view.show_view('Detail/DeviceChain')
        else:
            modifier_pressed = True
            direction = Live.Application.Application.View.NavDirection.left
            if increment > 0:
                direction = Live.Application.Application.View.NavDirection.right
            self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed)
Пример #22
0
class MainSelectorComponent(ModeSelectorComponent):
	__module__ = __name__
	__doc__ = ' Class that reassigns the button on the launchpad to different functions '

	def __init__(self, matrix, top_buttons, side_buttons, config_button, script):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._script = script
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		for scene in self._session._scenes:
			for slot in scene._clip_slots:
				slot._triggered_to_play_value = 24
				slot._triggered_to_record_value = 27
				slot._started_value = 7
				slot._recording_value = 9
				slot._stopped_value = 8
		self._zooming = SessionZoomingComponent(self._session)
		self._zooming._stopped_value = 9
		self._zooming._playing_value = 7
		self._zooming._selected_value = 8
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in (self._side_buttons + self._nav_buttons):
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self.set_modes_buttons(top_buttons[4:])



	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)



	def set_modes_buttons(self, buttons):
		assert ((buttons == None) or (isinstance(buttons, tuple) or (len(buttons) == self.number_of_modes() + 1)))
		identify_sender = True
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._modes_buttons = []
		if (buttons != None):
			for button in buttons:
				assert isinstance(button, ButtonElement)
				self._modes_buttons.append(button)
				button.add_value_listener(self._mode_value, identify_sender)
		self.set_mode(0)

	def _mode_value(self, value, sender):
		assert (len(self._modes_buttons) > 0)
		assert isinstance(value, int)
		assert isinstance(sender, ButtonElement)
		assert (self._modes_buttons.count(sender) == 1)
		if self._script._host.is_enabled() != True:
			if ((value is not 0) or (not sender.is_momentary())):
				if ((self._modes_buttons[1]._last_received_value > 0) and (self._modes_buttons.index(sender) == 2)) or ((self._modes_buttons[2]._last_received_value > 0) and (self._modes_buttons.index(sender) == 1)):
					if(self._script._host._active_client != None):
						self.set_mode(4)
					else:
						self._script.show_message('Monomodular Script not inserted')
				else:
					self.set_mode(self._modes_buttons.index(sender))
		else:
			if self._modes_buttons.index(sender) == 3 and value > 0:
				self.set_mode(0)
				
			

	def number_of_modes(self):
		return 5



	def on_enabled_changed(self):
		self.update()



	def set_mode(self, mode):
		assert (mode in range(self.number_of_modes()))
		if ((self._mode_index != mode) or (mode == 3)):
			self._mode_index = mode
			self.update()



	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			for scene_index in range(8):
				self._side_buttons[scene_index].set_enabled(True)
				for track_index in range(8):
					self._matrix.get_button(track_index, scene_index).set_enabled(True)


			for button in self._nav_buttons:
				button.set_enabled(True)

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			release_buttons = (self._mode_index == 1)
			if (self._mode_index < 4):
				self._script._host._set_key_buttons(None)
				self._script._host.set_enabled(False)
				self._script._host._set_button_matrix(None)
				self._script._host._set_alt_button(None)
				self._script._host._set_shift_button(None)
				self._script._host._set_nav_buttons(None)
				for button in self._modes_buttons:
					button.set_on_off_values(5, 0)
				if (self._mode_index == 0):
					self._setup_mixer((not as_active))
					self._setup_session(as_active, as_enabled)
				elif (self._mode_index == 1):
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
				elif (self._mode_index == 2):
					self._setup_session((not as_active), (not as_enabled))
					self._setup_mixer((not as_active))
					self._setup_user(release_buttons)
				elif (self._mode_index == 3):
					self._setup_session((not as_active), as_enabled)
					self._setup_mixer(as_active)
			elif (self._mode_index == 4):
				self._setup_session((not as_active), (not as_enabled))
				self._setup_mixer((not as_active))
				self._setup_user(release_buttons)
				self._script._host._set_button_matrix(self._matrix)
				self._script._host._set_key_buttons(self._side_buttons)
				self._script._host._set_shift_button(self._modes_buttons[0])
				self._script._host._set_lock_button(self._modes_buttons[1])
				self._script._host._set_alt_button(self._modes_buttons[2])
				self._modes_buttons[3].send_value(9)
				self._script._host._set_nav_buttons(self._nav_buttons)
				self._script._host.set_enabled(True)
			else:
				assert False
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
			self._update_control_channels()
			if(self._mode_index < 4):
				for index in range(len(self._modes_buttons)):
					if (index == self._mode_index):
						self._modes_buttons[index].turn_on()
					else:
						self._modes_buttons[index].turn_off()	
			#self._script.request_rebuild_midi_map()
			self._script.schedule_message(1, self._session.update)



	def _update_control_channels(self):
		if self._mode_index < 4:
			new_channel = (self._mode_index + self._sub_modes.mode())
			if (new_channel > 0):
				new_channel += 3
		else:
			new_channel = 15
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()




	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)

		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._side_buttons[scene_index]
				scene_button.set_on_off_values(127, LED_OFF)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(8):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, LED_OFF)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)


		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
			self._session.set_show_highlight(True)
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			self._session.set_show_highlight(False)



	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		self._sub_modes.set_enabled(as_active)




	def _setup_user(self, release_buttons):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.turn_off()
			scene_button.set_enabled((not release_buttons))
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_buttons))


		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_buttons))

		self._config_button.send_value(32)
		if release_buttons:
			self._config_button.send_value(2)



	def _init_session(self):
		self._session.set_stop_track_clip_value(AMBER_BLINK)
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(GREEN_BLINK)
				clip_slot.set_triggered_to_record_value(RED_BLINK)
				clip_slot.set_stopped_value(AMBER_FULL)
				clip_slot.set_started_value(GREEN_FULL)
				clip_slot.set_recording_value(RED_FULL)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))


		self._zooming.set_stopped_value(RED_FULL)
		self._zooming.set_selected_value(AMBER_FULL)
		self._zooming.set_playing_value(GREEN_FULL)
class MainSelectorComponent(ModeSelectorComponent):
	""" Class that reassigns the button on the launchpad to different functions """

	def __init__(self, matrix, top_buttons, side_buttons, config_button, parent):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._parent = parent
		self._compact = False
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		self._zooming = SessionZoomingComponent(self._session)
		self._session.name = 'Session_Control'
		self._zooming.name = 'Session_Overview'
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons,self)
		self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self._mode_index=0
		self._previous_mode_index=-1
		self._sub_mode_index=[0,0,0,0]
		for index in range(4):
			self._sub_mode_index[index]=0
		self.set_mode_buttons(top_buttons[4:])

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)

	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._mode_index==mode:
			if self._mode_index==1:
				#user mode 1 and device controller and instrument mode
				self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index]+1)%3
				self.update()
			elif self._mode_index==2:
				#user mode 2  and step sequencer
				self._sub_mode_index[self._mode_index] = (self._sub_mode_index[self._mode_index]+1)%2
				self.update()
			elif self._mode_index==3:
				self.update()
			else:
				self._sub_mode_index[self._mode_index] = 0
			self._previous_mode_index=self._mode_index	
		else:
			self._mode_index = mode
			self.update()
	
	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		#if ((self._mode_index != mode) or (mode == 3) or True):
		#self._mode_index = mode
			#self._update_mode()
		#	self.update()
	
	def number_of_modes(self):
		return 4

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		for index in range(4):
			if(self._sub_mode_index[index]==0):
				self._modes_buttons[index].set_on_off_values(AMBER_FULL,AMBER_THIRD)
			if(self._sub_mode_index[index]==1):
				self._modes_buttons[index].set_on_off_values(GREEN_FULL,GREEN_THIRD)
			if(self._sub_mode_index[index]==2):
				self._modes_buttons[index].set_on_off_values(RED_FULL,RED_THIRD)
				
			if (index == self._mode_index):	
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()


	def channel_for_current_mode(self):
		if self._compact:
		
			if self._mode_index==0:
				new_channel =  2 #session 

			elif self._mode_index==1:
				if self._sub_mode_index[self._mode_index]==0:
					new_channel = 2 #instrument controller 11,12,13,14
					if self._instrument_controller != None:
						self._instrument_controller.base_channel = new_channel
				elif self._sub_mode_index[self._mode_index]==1:
					new_channel = 2 #device controler
				else : 
					new_channel = 0 #plain user mode 1

			elif self._mode_index==2:
				if self._sub_mode_index[self._mode_index]==0:	
					new_channel = 1 #user 2
				else:
					new_channel = 2 + self._sub_mode_index[self._mode_index] #step seq 2,3

			elif self._mode_index==3: #mixer modes
				new_channel = 2 + self._sub_modes.mode() # 2,3,4,5,6
				
		else:
			
			if self._mode_index==0:
				new_channel =  0 #session 

			elif self._mode_index==1:
				if self._sub_mode_index[self._mode_index]==0:
					new_channel = 11 #instrument controller 11,12,13,14
					if self._instrument_controller != None:
						self._instrument_controller.base_channel = new_channel
				elif self._sub_mode_index[self._mode_index]==1:
					new_channel = 3 #device controler
				else : 
					new_channel = 4 #plain user mode 1

			elif self._mode_index==2:
				if self._sub_mode_index[self._mode_index]==0:	
					new_channel = 5 #user 2
				else:
					new_channel = 1 + self._sub_mode_index[self._mode_index] #step seq 1,2

			elif self._mode_index==3: #mixer modes
				new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10
		return new_channel

	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()
			
			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			
			if (self._mode_index == 0):
				#session
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				
			elif (self._mode_index == 1):
				self._setup_session(not as_active, not as_enabled)
				self._setup_step_sequencer(not as_active)
				self._setup_mixer(not as_active)
				#user mode + device controller + instrument controller
				if (self._sub_mode_index[self._mode_index]==0):
					self._setup_device_controller(not as_active)
					self._update_control_channels()
					self._setup_instrument_controller(as_active)
				elif (self._sub_mode_index[self._mode_index]==1):
					self._setup_instrument_controller(not as_active)
					self._setup_device_controller(as_active)
					self._update_control_channels()
				else:
					self._setup_device_controller(not as_active)
					self._setup_instrument_controller(not as_active)
					self._setup_user_mode(True, True, False, True)
					self._update_control_channels()
			elif (self._mode_index == 2):
				self._setup_session(not as_active, not as_enabled)
				self._setup_instrument_controller(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_mixer(not as_active)
				if (self._sub_mode_index[self._mode_index]==0):
					self._setup_step_sequencer(not as_active)
					self._setup_user_mode(False, False, False, False)
				else:
					self._setup_step_sequencer(as_active, self._sub_mode_index[self._mode_index])
				self._update_control_channels()
			elif (self._mode_index == 3):
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
			else:
				assert False
			
			self._previous_mode_index=self._mode_index
			
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
				
				

	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)

		#matrix
		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active:
				self._activate_matrix(True)
				scene_button = self._side_buttons[scene_index]
				scene_button.set_on_off_values(127, LED_OFF)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(8):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, LED_OFF)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		#zoom
		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		#nav buttons
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, enabled):
		if self._instrument_controller != None:
			if enabled:
				self._activate_matrix(False)
				self._activate_scene_buttons(True)
				self._activate_navigation_buttons(True)
			else:
				for scene_index in range(8):
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message()
					scene_button.force_next_send()
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()
						button.force_next_send()
			self._instrument_controller.set_enabled(enabled)
		

	def _setup_device_controller(self, as_active):
		if self._device_controller!=None:
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
 				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
 			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)



				
	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons = True, drum_rack_mode = True):
	
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))
				
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_matrix))

		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_nav_buttons))

		if drum_rack_mode:
			self._config_button.send_value(2)
		self._config_button.send_value(32)



	def _setup_step_sequencer(self, as_active, mode=0):
		if(self._stepseq!=None):
			if(self._stepseq.is_enabled()!=as_active or self._stepseq._mode!=mode):
				if as_active: 
					self._activate_scene_buttons(True)
					self._activate_matrix(True)
					self._activate_navigation_buttons(True)
					self._config_button.send_value(32)
					self._stepseq.set_enabled(True)
				else:
					self._stepseq.set_enabled(False)


	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):
				#go back to default mode
				self._sub_modes.set_mode(-1)
		self._sub_modes.set_enabled(as_active)
		


	def _init_session(self):
		self._session.set_stop_track_clip_value(AMBER_BLINK)
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(GREEN_BLINK)
				clip_slot.set_triggered_to_record_value(RED_BLINK)
				clip_slot.set_stopped_value(AMBER_FULL)
				clip_slot.set_started_value(GREEN_FULL)
				clip_slot.set_recording_value(RED_FULL)
				clip_slot.set_record_button_value(RED_THIRD)
				clip_slot.set_clip_palette(CLIP_COLOR_TABLE)
				#clip_slot.set_clip_rgb_table(RGB_COLOR_TABLE)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		self._zooming.set_stopped_value(RED_FULL)
		self._zooming.set_selected_value(AMBER_FULL)
		self._zooming.set_playing_value(GREEN_FULL)



	def _activate_navigation_buttons(self,active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self,active):
		for button in self._side_buttons:
			button.set_enabled(active)
			
	def _activate_matrix(self,active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)
				
	def log_message(self, msg):
		self._parent.log_message(msg)
		
	#Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()
Пример #24
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """
    def __init__(self, matrix, top_buttons, side_buttons, config_button):
        raise isinstance(matrix, ButtonMatrixElement) or AssertionError
        raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
        raise isinstance(top_buttons, tuple) or AssertionError
        raise len(top_buttons) == 8 or AssertionError
        raise isinstance(side_buttons, tuple) or AssertionError
        raise len(side_buttons) == 8 or AssertionError
        raise isinstance(config_button, ButtonElement) or AssertionError
        ModeSelectorComponent.__init__(self)
        self._session = SpecialSessionComponent(matrix.width(),
                                                matrix.height())
        self._zooming = DeprecatedSessionZoomingComponent(self._session)
        self._session.name = 'Session_Control'
        self._zooming.name = 'Session_Overview'
        self._matrix = matrix
        self._side_buttons = side_buttons
        self._nav_buttons = top_buttons[:4]
        self._config_button = config_button
        self._zooming.set_empty_value(LED_OFF)
        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes.set_update_callback(self._update_control_channels)
        self._init_session()
        self._all_buttons = tuple(self._all_buttons)
        self.set_modes_buttons(top_buttons[4:])

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values(127, LED_OFF)

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def set_modes_buttons(self, buttons):
        raise buttons == None or isinstance(
            buttons,
            tuple) or len(buttons) == self.number_of_modes() or AssertionError
        identify_sender = True
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._modes_buttons = []
        if buttons != None:
            for button in buttons:
                raise isinstance(button, ButtonElement) or AssertionError
                self._modes_buttons.append(button)
                button.add_value_listener(self._mode_value, identify_sender)

        self.set_mode(0)

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        self.update()

    def set_mode(self, mode):
        if not mode in range(self.number_of_modes()):
            raise AssertionError
            self._mode_index = (self._mode_index != mode or mode == 3) and mode
            self.update()

    def channel_for_current_mode(self):
        new_channel = self._mode_index + self._sub_modes.mode()
        if new_channel > 0:
            new_channel += 3
        return new_channel

    def update(self):
        super(MainSelectorComponent, self).update()
        if not self._modes_buttons != None:
            raise AssertionError
            if self.is_enabled():
                for index in range(len(self._modes_buttons)):
                    self._modes_buttons[index].set_force_next_value()
                    if index == self._mode_index:
                        self._modes_buttons[index].turn_on()
                    else:
                        self._modes_buttons[index].turn_off()

                for scene_index in range(8):
                    self._side_buttons[scene_index].set_enabled(True)
                    for track_index in range(8):
                        self._matrix.get_button(track_index,
                                                scene_index).set_enabled(True)

                for button in self._nav_buttons:
                    button.set_enabled(True)

                as_active = True
                as_enabled = True
                self._session.set_allow_update(False)
                self._zooming.set_allow_update(False)
                self._config_button.send_value(40)
                self._config_button.send_value(1)
                release_buttons = self._mode_index == 1
                self._mode_index == 0 and self._setup_mixer(not as_active)
                self._setup_session(as_active, as_enabled)
            elif self._mode_index == 1:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 2:
                self._setup_session(not as_active, not as_enabled)
                self._setup_mixer(not as_active)
                self._setup_user(release_buttons)
            elif self._mode_index == 3:
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
            else:
                raise False or AssertionError
            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)
            self._update_control_channels()

    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.set_force_next_value()

    def _setup_session(self, as_active, as_enabled):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            for button in self._nav_buttons:
                if as_enabled:
                    button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
                else:
                    button.set_on_off_values(127, LED_OFF)

            for scene_index in range(8):
                scene = self._session.scene(scene_index)
                if as_active:
                    scene_button = self._side_buttons[scene_index]
                    scene_button.set_on_off_values(127, LED_OFF)
                    scene.set_launch_button(scene_button)
                else:
                    scene.set_launch_button(None)
                for track_index in range(8):
                    if as_active:
                        button = self._matrix.get_button(
                            track_index, scene_index)
                        button.set_on_off_values(127, LED_OFF)
                        scene.clip_slot(track_index).set_launch_button(button)
                    else:
                        scene.clip_slot(track_index).set_launch_button(None)

            if as_active:
                self._zooming.set_zoom_button(self._modes_buttons[0])
                self._zooming.set_button_matrix(self._matrix)
                self._zooming.set_scene_bank_buttons(self._side_buttons)
                self._zooming.set_nav_buttons(self._nav_buttons[0],
                                              self._nav_buttons[1],
                                              self._nav_buttons[2],
                                              self._nav_buttons[3])
                self._zooming.update()
            else:
                self._zooming.set_zoom_button(None)
                self._zooming.set_button_matrix(None)
                self._zooming.set_scene_bank_buttons(None)
                self._zooming.set_nav_buttons(None, None, None, None)
            as_enabled and self._session.set_track_bank_buttons(
                self._nav_buttons[3], self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_mixer(self, as_active):
        if not isinstance(as_active, type(False)):
            raise AssertionError
            as_active and self._sub_modes.is_enabled(
            ) and self._sub_modes.set_mode(-1)
        self._sub_modes.set_enabled(as_active)

    def _setup_user(self, release_buttons):
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values(127, LED_OFF)
            scene_button.turn_off()
            scene_button.set_enabled(not release_buttons)
            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values(127, LED_OFF)
                button.turn_off()
                button.set_enabled(not release_buttons)

        for button in self._nav_buttons:
            button.set_on_off_values(127, LED_OFF)
            button.turn_off()
            button.set_enabled(not release_buttons)

        if release_buttons:
            self._config_button.send_value(2)
        self._config_button.send_value(32, force=True)

    def _init_session(self):
        self._session.set_stop_clip_value(AMBER_THIRD)
        self._session.set_stop_clip_triggered_value(AMBER_BLINK)
        for scene_index in range(self._matrix.height()):
            scene = self._session.scene(scene_index)
            scene.set_triggered_value(GREEN_BLINK)
            scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_triggered_to_play_value(GREEN_BLINK)
                clip_slot.set_triggered_to_record_value(RED_BLINK)
                clip_slot.set_stopped_value(AMBER_FULL)
                clip_slot.set_started_value(GREEN_FULL)
                clip_slot.set_recording_value(RED_FULL)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        self._zooming.set_stopped_value(RED_FULL)
        self._zooming.set_selected_value(AMBER_FULL)
        self._zooming.set_playing_value(GREEN_FULL)
class MF3D_Color_Clip(ControlSurface):
    __doc__ = " Script for Mad Zach's Weekly soundpacks "

    _active_instances = []

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        self.set_suppress_rebuild_requests(True)
        self._session = None
        self._session_zoom = None
        self._last_tr_off = 0
        self._last_sc_off = 1
        self._setup_session_control()
        self.set_suppress_rebuild_requests(False)

    def disconnect(self):
        self._session = None
        self._session_zoom = None
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= MIDI Fighter Mad Zach Soundpack log closed =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        ControlSurface.disconnect(self)

    def _setup_session_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        self._session = SpecialSessionComponent(4, 4)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._set_button(BUTTONCHANNEL+1, SESSIONRIGHT),self._set_button(BUTTONCHANNEL+1, SESSIONLEFT))
        self._session.set_scene_bank_buttons(self._set_button(BUTTONCHANNEL+1, SESSIONDOWN),self._set_button(BUTTONCHANNEL+1, SESSIONUP))
        self._session_zoom = SpecialZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_nav_buttons(self._set_button(BUTTONCHANNEL+1, ZOOMUP), self._set_button(BUTTONCHANNEL+1, ZOOMDOWN), self._set_button(BUTTONCHANNEL+1, ZOOMLEFT), self._set_button(BUTTONCHANNEL+1, ZOOMRIGHT))
        tracks = self.getslots() #get clip slots to access clip colors
        for scene_index in range(4):
            scene_off=self._session._scene_offset
            scene = self._session.scene(scene_index+scene_off)
            scene.name = 'Scene_' + str(scene_index+scene_off)
            button_row = []
            for track_index in range(4):
                button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF)
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index+scene_off)
                clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index+scene_off] #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval=self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    self.log_message("Clip:  tr: " + str(track_index) + " clip: " + str(scene_index+scene_off) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval))
                    clip_slot.set_stopped_value(cval)
##                clip_slot.set_triggered_to_launch_value(1)
                clip_slot.set_triggered_to_play_value(PLAYTRIG_COL)
                clip_slot.set_started_value(TRIGD_COL)
                clip_slot.set_triggered_to_record_value(RECTRIG_COL)
                clip_slot.set_recording_value(RECD_COL)

    def int_to_rgb(self,rgbint):
        return (rgbint/256/256%256, rgbint/256%256,rgbint%256)

    def getslots(self):
        tracks = self.song().visible_tracks

        clipSlots = []
        for track in tracks:
            clipSlots.append(track.clip_slots)
        return clipSlots

    def _set_button(self,_channel,_note,_on_color=118,_off_color=0):
        _button=None;
        if not _note is -1:
          _button = ConfigurableButtonElement(True, MESSAGETYPE, _channel, _note,_on_color,_off_color)
        return _button

    def _set_colors(self, scene_dir):
        tracks = self.getslots() #get clip slots to access clip colors
        scene_off=self._session.scene_offset()
        track_off=self._session.track_offset()
        for scene_index in range(4):
            sc=scene_index
            scene = self._session.scene(sc)
            self.log_message("scene offset + index " + str(scene_index))
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            for track_index in range(4):
                #button = self._set_button(BUTTONCHANNEL, CLIPNOTEMAP[scene_index][track_index], GREEN, OFF)
                #button_row.append(button)
                tr=track_index
                clip_slot = scene.clip_slot(tr)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                #clip_slot.set_launch_button(button)
                c = tracks[track_index][scene_index+scene_off+scene_dir] #get clip for color
                clip_slot.set_stopped_value(LOWYELLOW)
                if c.clip != None:
                    cval=self._get_MF3D_color(self.int_to_rgb(c.clip.color))
                    clip_slot.set_stopped_value(cval)
                    self.log_message("Clip:  tr: " + str(track_index) + " clip: " + str(scene_index) + " has color: " + str(self.int_to_rgb(c.clip.color)) + " va " + str(cval))

    def update_display(self):
        ControlSurface.update_display(self)
        scene_off=self._session.scene_offset()
        track_off=self._session.track_offset()
        if (scene_off>self._last_sc_off):
            self.log_message("vooce"+ str(self._session._track_offset)+ " " +str(self._session._scene_offset))
            self._set_colors(1)
            self._last_tr_off = track_off
            self._last_sc_off = scene_off
        if (scene_off<self._last_sc_off):
            self.log_message("vooce"+ str(self._session._track_offset)+ " " +str(self._session._scene_offset))
            self._set_colors(-1)
            self._last_tr_off = track_off
            self._last_sc_off = scene_off

    def _get_MF3D_color(self, colors):
        red = colors[0]
        green = colors[1]
        blue = colors[2]
        color_table=((255,0,0,RED),(125,0,0,LOWRED),(255,127,0,ORANGE),(127,64,0,LOWORANGE),
                     (255,255,0,YELLOW),(127,127,0,LOWYELLOW),(127,255,0,CHARTREUSSE),(64,127,0,LOWCHARTREUSSE),
                     (0,255,0,GREEN),(0,127,0,LOWGREEN),(0,255,255,CYAN),(0,127,127,LOWCYAN),
                     (0,0,255,BLUE),(0,0,127,LOWBLUE),(0,255,127,PURPLE),(0,127,64,LOWPURPLE),
                     (0,255,255,PINK),(0,127,127,LOWPINK),(255,255,255,WHITE))
        min_dist=9999999
        color_node=(0,0,0,119)
        for index in range(len(color_table)):
             if (min_dist>self._get_distance(colors,color_table[index])):
                min_dist=self._get_distance(colors,color_table[index])
                #self.log_message("colors " +  str(color_node) + " and " + str(color_table[index]))
                color_node=color_table[index]
        #self.log_message("red " + str(red) + " green " + str(green) + " blue " + str(blue) + " distance to" + str(color_node[3]) + " :: " + str(self._get_distance(colors,color_node))) 
        return color_node[3]

    def _get_distance(self,color1,color2):
        r1=color1[0]
        g1=color1[1]
        b1=color1[2]
        r2=color2[0]
        g2=color2[1]
        b2=color2[2]
        #self.log_message("got " + str(color1) + " and " + str(color2))
        return (abs((r1-r2))+abs((g1-g2))+abs((b1-b2)))
Пример #26
0
class MainSelectorComponent(ModeSelectorComponent):
    """ Class that reassigns the button on the launchpad to different functions """

    #def log(self, message):
    #	self._control_surface.log_message((' ' + message + ' ').center(50, '='))

    def __init__(self, matrix, top_buttons, side_buttons, config_button, osd,
                 control_surface):
        #verify matrix dimentions
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(top_buttons, tuple)
        assert (len(top_buttons) == 8)
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(config_button, ButtonElement)
        ModeSelectorComponent.__init__(self)  #super constructor

        #inject ControlSurface and OSD components (M4L)
        self._osd = osd
        self._control_surface = control_surface

        #initialize index variables
        self._mode_index = 0  #Inherited from parent
        self._main_mode_index = 0  #LP original modes
        self._sub_mode_list = [0, 0, 0, 0]
        for index in range(4):
            self._sub_mode_list[index] = 0
        self.set_mode_buttons(top_buttons[4:])

        if Settings.SESSION__STOP_BUTTONS:  #session with bottom stop buttons
            clip_stop_buttons = []
            for column in range(8):
                clip_stop_buttons.append(
                    matrix.get_button(column,
                                      matrix.height() - 1))
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height() - 1,
                                                    clip_stop_buttons,
                                                    self._control_surface,
                                                    self)
        else:  #no stop buttons
            self._session = SpecialSessionComponent(matrix.width(),
                                                    matrix.height(), None,
                                                    self._control_surface,
                                                    self)

        #initialize _session variables
        self._session.set_osd(self._osd)
        self._session.name = 'Session_Control'

        #initialize _zooming variables
        self._zooming = DeprecatedSessionZoomingComponent(self._session,
                                                          enable_skinning=True)
        self._zooming.name = 'Session_Overview'
        self._zooming.set_empty_value("Default.Button.Off")

        self._matrix = matrix
        self._side_buttons = side_buttons  #launch buttons
        self._nav_buttons = top_buttons[:4]  #arrow buttons
        self._config_button = config_button  #used to reset launchpad

        self._all_buttons = []
        for button in self._side_buttons + self._nav_buttons:
            self._all_buttons.append(button)

        #SubSelector changes the Mode using side buttons (ie. Pan, Volume, Send1, Send2, Stop, Solo, Activate, Arm)
        self._sub_modes = SubSelectorComponent(matrix, side_buttons,
                                               self._session,
                                               self._control_surface)
        self._sub_modes.name = 'Mixer_Modes'
        self._sub_modes._mixer.set_osd(self._osd)
        self._sub_modes.set_update_callback(self._update_control_channels)

        #User2 stepSequencer (Drum & Melodic)
        self._stepseq = StepSequencerComponent(self._matrix,
                                               self._side_buttons,
                                               self._nav_buttons,
                                               self._control_surface)
        self._stepseq.set_osd(self._osd)

        #User2 stepSequencer (Retro style)
        self._stepseq2 = StepSequencerComponent2(self._matrix,
                                                 self._side_buttons,
                                                 self._nav_buttons,
                                                 self._control_surface)
        self._stepseq2.set_osd(self._osd)

        #User1 Instrument controller (Scale)
        self._instrument_controller = InstrumentControllerComponent(
            self._matrix, self._side_buttons, self._nav_buttons,
            self._control_surface)
        self._instrument_controller.set_osd(self._osd)
        #self._instrument_controller = None

        #User1 Device controller (Fx or Instrument parameters)
        self._device_controller = DeviceComponent(
            control_surface=self._control_surface,
            matrix=self._matrix,
            side_buttons=self._side_buttons,
            top_buttons=self._nav_buttons)
        self._device_controller.set_osd(self._osd)

        self._init_session()
        self._all_buttons = tuple(self._all_buttons)

    def disconnect(self):
        for button in self._modes_buttons:
            button.remove_value_listener(self._mode_value)

        self._session = None
        self._zooming = None
        for button in self._all_buttons:
            button.set_on_off_values("DefaultButton.Disabled",
                                     "DefaultButton.Disabled")

        self._config_button.turn_off()
        self._matrix = None
        self._side_buttons = None
        self._nav_buttons = None
        self._config_button = None
        ModeSelectorComponent.disconnect(self)

    def session_component(self):
        return self._session

    def _update_mode(self):
        mode = self._modes_heap[-1][
            0]  #get first value of last _modes_heap tuple. _modes_heap tuple structure is (mode, sender, observer)

        assert mode in range(self.number_of_modes())  # 8 for this script
        if self._main_mode_index == mode:
            if self._main_mode_index == 1:  #user mode 1 and device controller and instrument mode
                self._sub_mode_list[self._main_mode_index] = (
                    self._sub_mode_list[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 2:  #user mode 2  and step sequencer
                self._sub_mode_list[self._main_mode_index] = (
                    self._sub_mode_list[self._main_mode_index] + 1) % 3
                self.update()
            elif self._main_mode_index == 3:  #Mixer mode
                self.update()
            else:  #Session mode
                self._sub_mode_list[self._main_mode_index] = 0
                self._mode_index = 0

        else:
            self._main_mode_index = mode
            self.update()

    def set_mode(self, mode):
        self._clean_heap()
        self._modes_heap = [(mode, None, None)]
        # if ((self.__main_mode_index != mode) or (mode == 3) or True):
        # 	self._main_mode_index = mode
        # 	self._update_mode()
        # 	self.update()

    def number_of_modes(self):
        return 1 + 3 + 3 + 1

    def on_enabled_changed(self):
        self.update()

    def _update_mode_buttons(self):
        self._modes_buttons[0].set_on_off_values("Mode.Session.On",
                                                 "Mode.Session.Off")
        self._modes_buttons[3].set_on_off_values("Mode.Mixer.On",
                                                 "Mode.Mixer.Off")
        mode1 = self.getSkinName(Settings.USER_MODES[self._sub_mode_list[1]])
        mode2 = self.getSkinName(Settings.USER_MODES[3 +
                                                     self._sub_mode_list[2]])
        self._modes_buttons[1].set_on_off_values("Mode." + mode1 + ".On",
                                                 "Mode." + mode1 + ".Off")
        self._modes_buttons[2].set_on_off_values("Mode." + mode2 + ".On",
                                                 "Mode." + mode2 + ".Off")

        for index in range(4):
            if (index == self._main_mode_index):
                self._modes_buttons[index].turn_on()
            else:
                self._modes_buttons[index].turn_off()

    def getSkinName(self, user2Mode):
        if user2Mode == "instrument":
            user2Mode = "Note"
        if user2Mode == "device":
            user2Mode = "Device"
        if user2Mode == "user 1":
            user2Mode = "User"
        if user2Mode == "user 2":
            user2Mode = "User2"
        if user2Mode == "drum stepseq":
            user2Mode = "StepSequencer"
        if user2Mode == "melodic stepseq":
            user2Mode = "StepSequencer2"
        return user2Mode

    def channel_for_current_mode(self):
        # in this code, midi channels start at 0.
        # so channels range from 0 - 15.
        # mapping to 1-16 in the real world

        if self._main_mode_index == 0:
            new_channel = 0  # session

        elif self._main_mode_index == 1:
            if self._sub_mode_list[self._main_mode_index] == 0:
                new_channel = 11  # instrument controller
                # instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
                if self._instrument_controller != None:
                    self._instrument_controller.base_channel = new_channel
            elif self._sub_mode_list[self._main_mode_index] == 1:
                new_channel = 3  # device controller
            elif self._sub_mode_list[self._main_mode_index] == 2:
                new_channel = 4  # plain user mode 1

        elif self._main_mode_index == 2:
            if self._sub_mode_list[self._main_mode_index] == 0:
                new_channel = 1  # step seq
            elif self._sub_mode_list[self._main_mode_index] == 1:
                new_channel = 2  # melodic step seq
            elif self._sub_mode_list[self._main_mode_index] == 2:
                new_channel = 5  # plain user mode 2

        elif self._main_mode_index == 3:  # mixer modes
            # mixer uses base channel 7 and the 4 next ones.
            new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

        return new_channel

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():

            self._update_mode_buttons()

            as_active = True
            as_enabled = True
            self._session.set_allow_update(False)
            self._zooming.set_allow_update(False)
            self._config_button.send_value(
                40)  #Set LP double buffering mode (investigate this)
            self._config_button.send_value(
                1)  #Set LP X-Y layout grid mapping mode

            if self._main_mode_index == 0:
                # session
                self._control_surface.show_message("SESSION MODE")
                self._setup_mixer(not as_active)
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(as_active, as_enabled)
                self._update_control_channels()
                self._mode_index = 0

            elif self._main_mode_index == 1 or self._main_mode_index == 2:
                self._setup_sub_mode(Settings.USER_MODES[
                    (self._main_mode_index - 1) * 3 +
                    self._sub_mode_list[self._main_mode_index]])

            elif self._main_mode_index == 3:
                # mixer
                self._control_surface.show_message("MIXER MODE")
                self._setup_device_controller(not as_active)
                self._setup_step_sequencer(not as_active)
                self._setup_step_sequencer2(not as_active)
                self._setup_instrument_controller(not as_active)
                self._setup_session(not as_active, as_enabled)
                self._setup_mixer(as_active)
                self._update_control_channels()
                self._mode_index = 3
            else:
                assert False

            self._session.set_allow_update(True)
            self._zooming.set_allow_update(True)

    def _setup_sub_mode(self, mode):
        as_active = True
        as_enabled = True
        if mode == "instrument":
            self._control_surface.show_message("INSTRUMENT MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._update_control_channels()
            self._setup_instrument_controller(as_active)
            self._mode_index = 4
        elif mode == "melodic stepseq":
            self._control_surface.show_message("MELODIC SEQUENCER MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(as_active)
            self._update_control_channels()
            self._mode_index = 7
        elif mode == "user 1":
            self._control_surface.show_message("USER 1 MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_user_mode(True, True, False, True)
            self._update_control_channels()
            self._mode_index = 1
            self._osd.clear()
            self._osd.mode = "User 1"
            self._osd.update()
        elif mode == "drum stepseq":
            self._control_surface.show_message("DRUM STEP SEQUENCER MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_step_sequencer(as_active)
            self._update_control_channels()
            self._mode_index = 6
        elif mode == "device":
            self._control_surface.show_message("DEVICE CONTROLLER MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_mixer(not as_active)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(as_active)
            self._update_control_channels()
            self._mode_index = 5
        elif mode == "user 2":
            self._control_surface.show_message("USER 2 MODE")
            self._setup_session(not as_active, not as_enabled)
            self._setup_instrument_controller(not as_active)
            self._setup_device_controller(not as_active)
            self._setup_mixer(not as_active)
            self._setup_step_sequencer(not as_active)
            self._setup_step_sequencer2(not as_active)
            self._setup_user_mode(False, False, False, False)
            self._update_control_channels()
            self._mode_index = 2
            self._osd.clear()
            self._osd.mode = "User 2"
            self._osd.update()

    def _setup_session(self, as_active, as_navigation_enabled):
        assert isinstance(as_active, type(False))  #assert is boolean
        for button in self._nav_buttons:
            if as_navigation_enabled:
                button.set_on_off_values("Mode.Session.On", "Mode.Session.Off")
            else:
                button.set_on_off_values("DefaultButton.Disabled",
                                         "DefaultButton.Disabled")

        # matrix
        self._activate_matrix(True)
        for scene_index in range(
                self._session._num_scenes):  #iterate over scenes
            scene = self._session.scene(scene_index)
            if as_active:  #set scene launch buttons
                scene_button = self._side_buttons[scene_index]
                scene_button.set_enabled(as_active)
                scene_button.set_on_off_values("DefaultButton.Disabled",
                                               "DefaultButton.Disabled")
                scene.set_launch_button(scene_button)
            else:
                scene.set_launch_button(None)

            for track_index in range(
                    self._session._num_tracks
            ):  #iterate over tracks of a scene -> clip slots
                if as_active:  #set clip slot launch button
                    button = self._matrix.get_button(track_index, scene_index)
                    button.set_on_off_values("DefaultButton.Disabled",
                                             "DefaultButton.Disabled")
                    button.set_enabled(as_active)
                    scene.clip_slot(track_index).set_launch_button(button)
                else:
                    scene.clip_slot(track_index).set_launch_button(None)

        if as_active:  #Set up stop clip buttons and stop all clips button
            if self._session._stop_clip_buttons != None:
                for button in self._session._stop_clip_buttons:
                    button.set_enabled(as_active)
                #	button.set_on_off_values("Session.StopClip", "DefaultButton.Disabled")
                self._session.set_stop_track_clip_buttons(
                    self._session._stop_clip_buttons)

                self._side_buttons[self._session._num_scenes].set_enabled(
                    as_active)
                self._side_buttons[
                    self._session._num_scenes].set_on_off_values(
                        "Session.StopClip", "DefaultButton.Disabled")
                self._session.set_stop_all_clips_button(
                    self._side_buttons[self._session._num_scenes])
            else:
                self._session.set_stop_track_clip_buttons(None)
                self._session.set_stop_all_clips_button(None)
        else:
            self._session.set_stop_track_clip_buttons(None)
            self._session.set_stop_all_clips_button(None)

        if as_active:  # zoom
            self._zooming.set_zoom_button(
                self._modes_buttons[0]
            )  # Set Session button as zoom shift button
            self._zooming.set_button_matrix(self._matrix)
            self._zooming.set_scene_bank_buttons(self._side_buttons)
            self._zooming.set_nav_buttons(self._nav_buttons[0],
                                          self._nav_buttons[1],
                                          self._nav_buttons[2],
                                          self._nav_buttons[3])
            self._zooming.update()
        else:
            self._zooming.set_zoom_button(None)
            self._zooming.set_button_matrix(None)
            self._zooming.set_scene_bank_buttons(None)
            self._zooming.set_nav_buttons(None, None, None, None)

        if as_navigation_enabled:  # nav buttons (track/scene)
            self._session.set_track_bank_buttons(self._nav_buttons[3],
                                                 self._nav_buttons[2])
            self._session.set_scene_bank_buttons(self._nav_buttons[1],
                                                 self._nav_buttons[0])
        else:
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)

    def _setup_instrument_controller(self, as_active):
        if self._instrument_controller != None:
            if as_active:
                self._activate_matrix(
                    False)  #Disable matrix buttons (clip slots)
                self._activate_scene_buttons(True)  #Enable side buttons
                self._activate_navigation_buttons(True)  #Enable nav buttons
            else:
                for scene_index in range(
                        8
                ):  #Restore all matrix buttons and scene launch buttons
                    scene_button = self._side_buttons[scene_index]
                    scene_button.use_default_message(
                    )  # Reset to original channel
                    scene_button.force_next_send()  #Flush
                    for track_index in range(8):
                        button = self._matrix.get_button(
                            track_index, scene_index)
                        button.use_default_message(
                        )  # Reset to original channel
                        button.force_next_send()  #Flush
            self._instrument_controller.set_enabled(
                as_active)  #Enable/disable instrument controller

    def _setup_device_controller(self, as_active):
        if self._device_controller != None:
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._device_controller._is_active = True
                self._config_button.send_value(32)
                self._device_controller.set_enabled(True)
                self._device_controller.update()
            else:
                self._device_controller._is_active = False
                self._device_controller.set_enabled(False)

    def _setup_user_mode(self,
                         release_matrix=True,
                         release_side_buttons=True,
                         release_nav_buttons=True,
                         drum_rack_mode=True):
        # user1 -> All True but release_nav_buttons / user2 -> All false
        for scene_index in range(8):
            scene_button = self._side_buttons[scene_index]
            scene_button.set_on_off_values("DefaultButton.Disabled",
                                           "DefaultButton.Disabled")
            scene_button.force_next_send()
            scene_button.turn_off()
            scene_button.set_enabled(
                (not release_side_buttons))  #User2 enabled

            for track_index in range(8):
                button = self._matrix.get_button(track_index, scene_index)
                button.set_on_off_values("DefaultButton.Disabled",
                                         "DefaultButton.Disabled")
                button.turn_off()
                button.set_enabled((not release_matrix))  #User2 enabled

        for button in self._nav_buttons:
            button.set_on_off_values("DefaultButton.Disabled",
                                     "DefaultButton.Disabled")
            button.turn_off()
            button.set_enabled(
                (not release_nav_buttons))  #User1 & User2 enabled

        if drum_rack_mode:  #User1 enabled
            self._config_button.send_value(
                2)  #Set LP drum rack layout grid mapping mode
        self._config_button.send_value(
            32)  #Send enable flashing led config message to LP

    def _setup_step_sequencer(self, as_active):
        if (self._stepseq != None):
            #if(self._stepseq.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq.set_enabled(True)
            else:
                self._stepseq.set_enabled(False)

    def _setup_step_sequencer2(self, as_active):
        if (self._stepseq2 != None):
            #if(self._stepseq2.is_enabled() != as_active):
            if as_active:
                self._activate_scene_buttons(True)
                self._activate_matrix(True)
                self._activate_navigation_buttons(True)
                self._config_button.send_value(32)
                self._stepseq2.set_enabled(True)
            else:
                self._stepseq2.set_enabled(False)

    def _setup_mixer(self, as_active):
        assert isinstance(as_active, type(False))
        if as_active:
            self._activate_navigation_buttons(True)
            self._activate_scene_buttons(True)
            self._activate_matrix(True)
            if (self._sub_modes.is_enabled()):  # go back to default mode
                self._sub_modes.set_mode(-1)
            else:
                self._sub_modes.release_controls()

        self._sub_modes.set_enabled(as_active)

    def _init_session(self):
        #self._session.set_stop_clip_value("Session.StopClip")
        #self._session.set_stop_clip_triggered_value("Session.ClipTriggeredStop")

        session_height = self._matrix.height()
        if self._session._stop_clip_buttons != None:
            session_height = self._matrix.height() - 1

        for scene_index in range(session_height):
            #	scene = self._session.scene(scene_index)
            #	scene.set_triggered_value("Session.SceneTriggered")
            #	scene.name = 'Scene_' + str(scene_index)
            for track_index in range(self._matrix.width()):
                #		clip_slot = scene.clip_slot(track_index)
                #		clip_slot.set_triggered_to_play_value("Session.ClipTriggeredPlay")
                #		clip_slot.set_triggered_to_record_value("Session.ClipTriggeredRecord")
                #		clip_slot.set_stopped_value("Session.ClipStopped")
                #		clip_slot.set_started_value("Session.ClipStarted")
                #		clip_slot.set_recording_value("Session.ClipRecording")
                #		clip_slot.set_record_button_value("Session.RecordButton")
                #		clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                self._all_buttons.append(
                    self._matrix.get_button(track_index, scene_index))

        #self._zooming.set_stopped_value("Zooming.Stopped")
        #self._zooming.set_selected_value("Zooming.Selected")
        #self._zooming.set_playing_value("Zooming.Playing")

    def _activate_navigation_buttons(self, active):
        for button in self._nav_buttons:
            button.set_enabled(active)

    def _activate_scene_buttons(self, active):
        for button in self._side_buttons:
            button.set_enabled(active)

    def _activate_matrix(self, active):
        for scene_index in range(8):
            for track_index in range(8):
                self._matrix.get_button(track_index,
                                        scene_index).set_enabled(active)

    def log_message(self, msg):
        self._control_surface.log_message(msg)

    # Update the channels of the buttons in the user modes..
    def _update_control_channels(self):
        new_channel = self.channel_for_current_mode()
        for button in self._all_buttons:
            button.set_channel(new_channel)
            button.force_next_send()
Пример #27
0
class MainSelectorComponent(ModeSelectorComponent):

	""" Class that reassigns the button on the launchpad to different functions """

	def log(self, message):
		self._parent.log_message((' ' + message + ' ').center(50, '='))

	def __init__(self, matrix, top_buttons, side_buttons, config_button, osd, parent, skin):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._skin = skin
		self._osd = osd
		self._parent = parent
		self._mode_index = 0
		self._previous_mode_index = -1
		self._main_mode_index = 0
		self._sub_mode_index = [0, 0, 0, 0]
		for index in range(4):
			self._sub_mode_index[index] = 0
		self.set_mode_buttons(top_buttons[4:])
			
		if Settings.SESSION__STOP_BUTTONS:
			#session with bottom stop buttons
			clip_stop_buttons = [] 
			for column in range(8):
				clip_stop_buttons.append(matrix.get_button(column,matrix.height()-1))
			self._session = SpecialSessionComponent(matrix.width(), matrix.height()-1, clip_stop_buttons, self, self._skin)
		else:
			#no stop buttons
			self._session = SpecialSessionComponent(matrix.width(), matrix.height(), None, self, self._skin)
			
		self._session.set_osd(self._osd)
		self._session.name = 'Session_Control'
		
		self._zooming = DeprecatedSessionZoomingComponent(self._session)
		self._zooming.name = 'Session_Overview'
		self._zooming.set_empty_value(self._skin.off)
		
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session, skin)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes._mixer.set_osd(self._osd)
		self._sub_modes.set_update_callback(self._update_control_channels)

		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._stepseq.set_osd(self._osd)
		
		self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._stepseq2.set_osd(self._osd)

		self._instrument_controller = InstrumentControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._instrument_controller.set_osd(self._osd)

		self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self, skin)
		self._device_controller.set_osd(self._osd)

		self._init_session()
		self._all_buttons = tuple(self._all_buttons)

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, self._skin.off)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)

	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._main_mode_index == mode:
			if self._main_mode_index == 1:
				# user mode 1 and device controller and instrument mode
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 2:
				# user mode 2  and step sequencer
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index] + 1) % 3
				self.update()
			elif self._main_mode_index == 3:
				self.update()
			else:
				self._sub_mode_index[self._main_mode_index] = 0
				self._mode_index = 0

			self._previous_mode_index = self._main_mode_index
		else:
			self._main_mode_index = mode
			self.update()

	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		# if ((self.__main_mode_index != mode) or (mode == 3) or True):
		# 	self._main_mode_index = mode
		# 	self._update_mode()
		# 	self.update()

	def number_of_modes(self):
		return 1 + 3 + 3 + 1

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		for index in range(4):
			if(self._sub_mode_index[index] == 0):
				self._modes_buttons[index].set_on_off_values(self._skin.AMBER_FULL, self._skin.AMBER_THIRD)
			if(self._sub_mode_index[index] == 1):
				self._modes_buttons[index].set_on_off_values(self._skin.GREEN_FULL, self._skin.GREEN_THIRD)
			if(self._sub_mode_index[index] == 2):
				self._modes_buttons[index].set_on_off_values(self._skin.RED_FULL, self._skin.RED_THIRD)

			if (index == self._main_mode_index):
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()

	def channel_for_current_mode(self):
		# in this code, midi channels start at 0.
		# so channels range from 0 - 15.
		# mapping to 1-16 in the real world

		if self._main_mode_index == 0:
			new_channel = 0  # session

		elif self._main_mode_index == 1:
			if self._sub_mode_index[self._main_mode_index] == 0:
				new_channel = 11  # instrument controller
				# instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
				if self._instrument_controller != None:
					self._instrument_controller.base_channel = new_channel
			elif self._sub_mode_index[self._main_mode_index] == 1:
				new_channel = 3  # device controller
			elif self._sub_mode_index[self._main_mode_index] == 2:
				new_channel = 4  # plain user mode 1

		elif self._main_mode_index == 2:
			if self._sub_mode_index[self._main_mode_index] == 0:
				new_channel = 1  # step seq
			elif self._sub_mode_index[self._main_mode_index] == 1:
				new_channel = 2  # melodic step seq
			elif self._sub_mode_index[self._main_mode_index] == 2:
				new_channel = 5  # plain user mode 2

		elif self._main_mode_index == 3:  # mixer modes
			# mixer uses base channel 7 and the 4 next ones.
			new_channel = 6 + self._sub_modes.mode()  # 6,7,8,9,10

		return new_channel

				
	
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()

			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)

			if self._main_mode_index == 0:
				# session
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				self._mode_index = 0

			elif self._main_mode_index == 1 or self._main_mode_index == 2:
				self._setup_usermode(Settings.USER_MODES[ (self._main_mode_index-1) * 3 + self._sub_mode_index[self._main_mode_index] ] )
				#if self._sub_mode_index[self._main_mode_index] == 0:
				#	self._setup_usermode(Settings.USER_MODES[0])
				#elif self._sub_mode_index[self._main_mode_index] == 1:
				#	self._setup_usermode(Settings.USER_MODES[1])
				#else:
				#	self._setup_usermode(Settings.USER_MODES[2])
			#elif self._main_mode_index == 2:
			#	if self._sub_mode_index[self._main_mode_index] == 0:
			#		self._setup_usermode(Settings.USER_MODES[3])
			#	elif self._sub_mode_index[self._main_mode_index] == 1:
			#		self._setup_usermode(Setting.USER_MODES[4])
			#	else:
			#		self._setup_usermode(Settings.USER_MODES[5])

			elif self._main_mode_index == 3:
				# mixer
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
				self._mode_index = 3
			else:
				assert False
			self._previous_mode_index = self._main_mode_index

			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
			#self.log_message("main selector update")
			#for line in traceback.format_stack():
			#	self.log_message(line.strip())
		
	def _setup_usermode(self, mode):
		as_active = True
		as_enabled = True
		if mode == "instrument":
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._update_control_channels()
			self._setup_instrument_controller(as_active)
			self._mode_index = 4
		elif mode == "melodic stepseq":
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(as_active)
			self._update_control_channels()
			self._mode_index = 7
		elif mode == "user 1":
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_user_mode(True, True, False, True)
			self._update_control_channels()
			self._mode_index = 1
			self._osd.clear()
			self._osd.mode = "User 1"
			self._osd.update()
		elif mode == "drum stepseq":
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_step_sequencer(as_active)
			self._update_control_channels()
			self._mode_index = 6
		elif mode == "device":
			self._setup_session(not as_active, not as_enabled)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_mixer(not as_active)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(as_active)
			self._update_control_channels()
			self._mode_index = 5
		elif mode == "user 2":
			self._setup_session(not as_active, not as_enabled)
			self._setup_instrument_controller(not as_active)
			self._setup_device_controller(not as_active)
			self._setup_mixer(not as_active)
			self._setup_step_sequencer(not as_active)
			self._setup_step_sequencer2(not as_active)
			self._setup_user_mode(False, False, False, False)
			self._update_control_channels()
			self._mode_index = 2
			self._osd.clear()
			self._osd.mode = "User 2"
			self._osd.update()
		
	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(self._skin.GREEN_FULL, self._skin.GREEN_THIRD)
			else:
				button.set_on_off_values(127, self._skin.off)

		# matrix
		self._activate_matrix(True)
		for scene_index in range(self._session._num_scenes):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._side_buttons[scene_index]
				scene_button.set_enabled(as_active)
				scene_button.set_on_off_values(127, self._skin.off)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)  
			for track_index in range(self._session._num_tracks):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, self._skin.off)
					button.set_enabled(as_active)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		if as_active:
			if self._session._stop_clip_buttons != None:
				for button in self._session._stop_clip_buttons:
					button.set_enabled(as_active)
					button.set_on_off_values(self._skin.session.track_stop, self._skin.off)
				self._session.set_stop_track_clip_buttons(self._session._stop_clip_buttons)

				self._side_buttons[self._session._num_scenes].set_enabled(as_active)
				self._side_buttons[self._session._num_scenes].set_on_off_values(self._skin.session._stop_clip_buttons, self._skin.off)
				self._session.set_stop_all_clips_button(self._side_buttons[self._session._num_scenes])
			else:
				self._session.set_stop_track_clip_buttons(None)
				self._session.set_stop_all_clips_button(None)
		else:
			self._session.set_stop_track_clip_buttons(None)
			self._session.set_stop_all_clips_button(None)
				
		# zoom
		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		# nav buttons
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, enabled):
		if self._instrument_controller != None:
			if enabled:
				self._activate_matrix(False)
				self._activate_scene_buttons(True)
				self._activate_navigation_buttons(True)
			else:
				for scene_index in range(8):
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message()
					scene_button.force_next_send()
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()
						button.force_next_send()
			self._instrument_controller.set_enabled(enabled)

	def _setup_device_controller(self, as_active):
		if self._device_controller != None:
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)

	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons=True, drum_rack_mode=True):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, self._skin.off)
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))

			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, self._skin.off)
				button.turn_off()
				button.set_enabled((not release_matrix))

		for button in self._nav_buttons:
			button.set_on_off_values(127, self._skin.off)
			button.turn_off()
			button.set_enabled((not release_nav_buttons))

		if drum_rack_mode:
			self._config_button.send_value(2)
		self._config_button.send_value(32)

	def _setup_step_sequencer(self, as_active):
		if(self._stepseq != None):
			#if(self._stepseq.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq.set_enabled(True)
			else:
				self._stepseq.set_enabled(False)

	def _setup_step_sequencer2(self, as_active):
		if(self._stepseq2 != None):
			#if(self._stepseq2.is_enabled() != as_active):
			if as_active:
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
				self._config_button.send_value(32)
				self._stepseq2.set_enabled(True)
			else:
				self._stepseq2.set_enabled(False)

	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):
				# go back to default mode
				self._sub_modes.set_mode(-1)
		else:
			self._sub_modes.release_controls()

		self._sub_modes.set_enabled(as_active)

	def _init_session(self):
		major = self._parent._live_major_version
		minor = self._parent._live_minor_version
		bugfix = self._parent._live_bugfix_version
		if (major >= 9 and minor > 1) or (major >= 9 and minor >= 1 and bugfix >= 2):
			# api changed in 9.1.2
			self._session.set_stop_clip_value(self._skin.session.track_stop)
			self._session.set_stop_clip_triggered_value(self._skin.session.clip_triggered_to_stop)
		else:
			# api for 9.1.1 below
			self._session.set_stop_track_clip_value(self._skin.session.clip_triggered_to_stop)

		#if self._mk2:
		#	self._session.set_rgb_mode(self._skin.CLIP_COLOR_TABLE, self._skin.RGB_COLOR_TABLE)
			
		session_height = self._matrix.height()
		if self._session._stop_clip_buttons != None:
			session_height = self._matrix.height()-1
			
		for scene_index in range(session_height):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(self._skin.session.scene_triggered)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(self._skin.session.clip_triggered_to_play)
				clip_slot.set_triggered_to_record_value(self._skin.session.clip_triggered_to_record)
				clip_slot.set_stopped_value(self._skin.session.clip_stopped)
				clip_slot.set_started_value(self._skin.session.clip_playing)
				clip_slot.set_recording_value(self._skin.session.clip_recording)
				clip_slot.set_record_button_value(self._skin.session.clip_record)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		self._zooming.set_stopped_value(self._skin.RED_FULL)
		self._zooming.set_selected_value(self._skin.AMBER_FULL)
		self._zooming.set_playing_value(self._skin.GREEN_FULL)

	def _activate_navigation_buttons(self, active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self, active):
		for button in self._side_buttons:
			button.set_enabled(active)

	def _activate_matrix(self, active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)

	def log_message(self, msg):
		self._parent.log_message(msg)

	# Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()
Пример #28
0
class MainSelectorComponent(ModeSelectorComponent,Launchpad95M4LInterfaceMixin):

	""" Class that reassigns the button on the launchpad to different functions """
	def log(self, message):
		self._parent.log_message((' '+message+' ').center(50,'='))
		
	def __init__(self, matrix, top_buttons, side_buttons, config_button, parent):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(top_buttons, tuple)
		assert (len(top_buttons) == 8)
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(config_button, ButtonElement)
		ModeSelectorComponent.__init__(self)
		self._m4lmode_index = 0		
		self.init_m4l_interface()
		self._attributes = [ '-' for _ in range(8) ]
		self._attribute_names = [ '-' for _ in range(8) ]
		self._info = [' ', ' ']
		self._map_name = MAP_NAMES[self._m4lmode_index]
		self._parent = parent
		self._compact = False
		self._session = SpecialSessionComponent(matrix.width(), matrix.height())
		self._zooming = SessionZoomingComponent(self._session)
		self._session.name = 'Session_Control'
		self._zooming.name = 'Session_Overview'
		self._matrix = matrix
		self._side_buttons = side_buttons
		self._nav_buttons = top_buttons[:4]
		self._config_button = config_button
		self._zooming.set_empty_value(LED_OFF)
		self._all_buttons = []
		for button in self._side_buttons + self._nav_buttons:
			self._all_buttons.append(button)

		self._sub_modes = SubSelectorComponent(matrix, side_buttons, self._session)
		self._sub_modes.name = 'Mixer_Modes'
		self._sub_modes.set_update_callback(self._update_control_channels)
		self._stepseq = StepSequencerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._stepseq2 = StepSequencerComponent2(self._matrix, self._side_buttons, self._nav_buttons, self)
		
		self._instrument_controller = InstrumentControllerComponent( self._matrix, self._side_buttons, self._nav_buttons,self)
		self._device_controller = DeviceControllerComponent(self._matrix, self._side_buttons, self._nav_buttons, self)
		self._init_session()
		self._all_buttons = tuple(self._all_buttons)
		self._mode_index=0
		self._previous_mode_index=-1
		self._main_mode_index=0
		self._sub_mode_index=[0,0,0,0]
		for index in range(4):
			self._sub_mode_index[index]=0
		self.set_mode_buttons(top_buttons[4:])

	def disconnect(self):
		for button in self._modes_buttons:
			button.remove_value_listener(self._mode_value)

		self._session = None
		self._zooming = None
		for button in self._all_buttons:
			button.set_on_off_values(127, LED_OFF)

		self._config_button.turn_off()
		self._matrix = None
		self._side_buttons = None
		self._nav_buttons = None
		self._config_button = None
		ModeSelectorComponent.disconnect(self)
	def set_m4lmode(self,mode_str):
		#self.log(mode_str)
		if mode_str == 'SCALE':			
			self._m4lmode_index = 8
		elif mode_str == 'QUICK_SCALE':
			self._m4lmode_index = 9
		elif mode_str == 'MULTINOTE':			
			self._m4lmode_index = 10
		elif mode_str == 'INST':
			self._m4lmode_index = 1
		elif mode_str == 'STEP':
			self._m4lmode_index = 4
		self.refresh_map_display()
		
	@property
	def mode_name(self):
		""" Returns the name of the current mode. """
		#self.log(MODE_NAMES[self._m4lmode_index])
		return MODE_NAMES[self._m4lmode_index]

	@property
	def mode_attributes(self):
		""" Returns the attributes of the current mode. """
		#self.log(self._attributes)
		return self._attributes

	@property
	def mode_attribute_names(self):
		""" Returns the names of the attributes of the current mode. """
		#self.log(self._attributes_names)
		return self._attribute_names

	@property
	def mode_info(self):
		""" Returns info about the current mode. """
		#self.log(self._info)
		return self._info

	@property
	def mode_map(self):
		""" Returns the name of the relevant map for the current mode. """
		#self.log(MAP_NAMES[self._m4lmode_index])
		return MAP_NAMES[self._m4lmode_index]
		
	def session_component(self):
		return self._session

	def _update_mode(self):
		mode = self._modes_heap[-1][0]
		assert mode in range(self.number_of_modes())
		if self._main_mode_index==mode:
			if self._main_mode_index==1:
				#user mode 1 and device controller and instrument mode
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index]+1)%3
				self.update()
			elif self._main_mode_index==2:
				#user mode 2  and step sequencer
				self._sub_mode_index[self._main_mode_index] = (self._sub_mode_index[self._main_mode_index]+1)%3
				self.update()	
			elif self._main_mode_index==3:
				self.update()
			else:
				self._sub_mode_index[self._main_mode_index] = 0
				self._mode_index = 0
				
			self._previous_mode_index=self._main_mode_index	
		else:
			self._main_mode_index = mode
			self.update()
	
	def set_mode(self, mode):
		self._clean_heap()
		self._modes_heap = [(mode, None, None)]
		self._compute_mode_index()
		#if ((self.__main_mode_index != mode) or (mode == 3) or True):
		#self._main_mode_index = mode
			#self._update_mode()
		#	self.update()
	
	def number_of_modes(self):
		return 1+3+3+1

	def on_enabled_changed(self):
		self.update()

	def _update_mode_buttons(self):
		for index in range(4):
			if(self._sub_mode_index[index]==0):
				self._modes_buttons[index].set_on_off_values(AMBER_FULL,AMBER_THIRD)
			if(self._sub_mode_index[index]==1):
				self._modes_buttons[index].set_on_off_values(GREEN_FULL,GREEN_THIRD)
			if(self._sub_mode_index[index]==2):
				self._modes_buttons[index].set_on_off_values(RED_FULL,RED_THIRD)
				
			if (index == self._main_mode_index):	
				self._modes_buttons[index].turn_on()
			else:
				self._modes_buttons[index].turn_off()


	def channel_for_current_mode(self):
		# in this code, midi channels start at 0.
		# so channels range from 0 - 15. 
		# mapping to 1-16 in the real world
		
		if self._main_mode_index==0:
			new_channel =  0 # session 
			
		elif self._main_mode_index==1:
			if self._sub_mode_index[self._main_mode_index]==0:
				new_channel = 11 # instrument controller
				#instrument controller uses base channel plus the 4 next ones. 11,12,13,14,15
				if self._instrument_controller != None:
					self._instrument_controller.base_channel = new_channel
			elif self._sub_mode_index[self._main_mode_index]==1:
				new_channel = 3 #device controller
			elif self._sub_mode_index[self._main_mode_index]==2: 
				new_channel = 4 #plain user mode 1

		elif self._main_mode_index==2:
			if self._sub_mode_index[self._main_mode_index]==0:
				new_channel = 1 #step seq
			elif self._sub_mode_index[self._main_mode_index]==1:	
				new_channel = 2 #melodic step seq
			elif self._sub_mode_index[self._main_mode_index]==2:
				new_channel = 5 #plain user mode 2
				
		elif self._main_mode_index==3: #mixer modes
			#mixer uses base channel 7 and the 4 next ones.
			new_channel = 6 + self._sub_modes.mode() # 6,7,8,9,10
		
		return new_channel

	def _compute_mode_index(self):
		if self._main_mode_index == 0:
			#session
			self._mode_index = 0
		elif self._main_mode_index == 1:
			if self._sub_mode_index[self._main_mode_index]==0:
				#instrument controller
				self._mode_index = 4
			elif self._sub_mode_index[self._main_mode_index]==1:
				#device controller
				self._mode_index = 5
			else:
				#plain user mode 1
				self._mode_index = 1
		elif self._main_mode_index == 2:
			if self._sub_mode_index[self._main_mode_index]==0:
				#stepseq
				self._mode_index = 6
			elif self._sub_mode_index[self._main_mode_index]==1:
				#melodic step seq
				self._mode_index = 7			
			else:
				#plain user mode 2
				self._mode_index = 2
			
		elif self._main_mode_index == 3:
			self._mode_index = 3
		else:
			assert False
			
	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():

			self._update_mode_buttons()
			
			as_active = True
			as_enabled = True
			self._session.set_allow_update(False)
			self._zooming.set_allow_update(False)
			self._config_button.send_value(40)
			self._config_button.send_value(1)
			
			if self._main_mode_index == 0:
				#session
				self._m4lmode_index = 0
				self.refresh_map_display()
				self._setup_mixer(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(as_active, as_enabled)
				self._update_control_channels()
				
			elif self._main_mode_index == 1:
				self._setup_session(not as_active, not as_enabled)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_mixer(not as_active)
				if self._sub_mode_index[self._main_mode_index]==0:
					#instrument controller
					self._setup_device_controller(not as_active)
					self._update_control_channels()
					self._setup_instrument_controller(as_active)
				elif self._sub_mode_index[self._main_mode_index]==1:
					#device controller
					self._setup_instrument_controller(not as_active)
					self._setup_device_controller(as_active)
					self._update_control_channels()
				else:
					#plain user mode 1
					self._m4lmode_index = 3
					self.refresh_map_display()
					self._setup_device_controller(not as_active)
					self._setup_instrument_controller(not as_active)
					self._setup_user_mode(True, True, False, True)
					self._update_control_channels()
			
			elif self._main_mode_index == 2:
				self._setup_session(not as_active, not as_enabled)
				self._setup_instrument_controller(not as_active)
				self._setup_device_controller(not as_active)
				self._setup_mixer(not as_active)
				if self._sub_mode_index[self._main_mode_index]==0:
					#stepseq
					self._m4lmode_index = 4
					self.refresh_map_display()
					self._setup_step_sequencer2(not as_active)
					self._setup_step_sequencer(as_active)
				elif self._sub_mode_index[self._main_mode_index]==1:
					#melodic step seq
					self._m4lmode_index = 5
					self.refresh_map_display()
					self._setup_step_sequencer(not as_active)
					self._setup_step_sequencer2(as_active)				
				else:
					#plain user mode 2
					self._m4lmode_index = 6
					self.refresh_map_display()
					self._setup_step_sequencer(not as_active)
					self._setup_step_sequencer2(not as_active)
					self._setup_user_mode(False, False, False, False)
				self._update_control_channels()
				
			elif self._main_mode_index == 3:
				#mixer				
				self._m4lmode_index = 7
				self.refresh_map_display()
				self._setup_device_controller(not as_active)
				self._setup_step_sequencer(not as_active)
				self._setup_step_sequencer2(not as_active)
				self._setup_instrument_controller(not as_active)
				self._setup_session(not as_active, as_enabled)
				self._setup_mixer(as_active)
				self._update_control_channels()
			else:
				assert False
			self._compute_mode_index()
			self._previous_mode_index=self._main_mode_index
			
			self._session.set_allow_update(True)
			self._zooming.set_allow_update(True)
				
				

	def _setup_session(self, as_active, as_enabled):
		assert isinstance(as_active, type(False))
		for button in self._nav_buttons:
			if as_enabled:
				button.set_on_off_values(GREEN_FULL, GREEN_THIRD)
			else:
				button.set_on_off_values(127, LED_OFF)

		#matrix
		self._activate_matrix(True)
		for scene_index in range(8):
			scene = self._session.scene(scene_index)
			if as_active:
				scene_button = self._side_buttons[scene_index]
				scene_button.set_enabled(as_active)
				scene_button.set_on_off_values(127, LED_OFF)
				scene.set_launch_button(scene_button)
			else:
				scene.set_launch_button(None)
			for track_index in range(8):
				if as_active:
					button = self._matrix.get_button(track_index, scene_index)
					button.set_on_off_values(127, LED_OFF)
					button.set_enabled(as_active)
					scene.clip_slot(track_index).set_launch_button(button)
				else:
					scene.clip_slot(track_index).set_launch_button(None)

		#zoom
		if as_active:
			self._zooming.set_zoom_button(self._modes_buttons[0])
			self._zooming.set_button_matrix(self._matrix)
			self._zooming.set_scene_bank_buttons(self._side_buttons)
			self._zooming.set_nav_buttons(self._nav_buttons[0], self._nav_buttons[1], self._nav_buttons[2], self._nav_buttons[3])
			self._zooming.update()
		else:
			self._zooming.set_zoom_button(None)
			self._zooming.set_button_matrix(None)
			self._zooming.set_scene_bank_buttons(None)
			self._zooming.set_nav_buttons(None, None, None, None)

		#nav buttons
		if as_enabled:
			self._session.set_track_bank_buttons(self._nav_buttons[3], self._nav_buttons[2])
			self._session.set_scene_bank_buttons(self._nav_buttons[1], self._nav_buttons[0])
		else:
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)

	def _setup_instrument_controller(self, enabled):
		if self._instrument_controller != None:
			if enabled:
				self._m4lmode_index = 1
				self.refresh_map_display()
				self._activate_matrix(False)
				self._activate_scene_buttons(True)
				self._activate_navigation_buttons(True)
			else:
				for scene_index in range(8):
					scene_button = self._side_buttons[scene_index]
					scene_button.use_default_message()
					scene_button.force_next_send()
					for track_index in range(8):
						button = self._matrix.get_button(track_index, scene_index)
						button.use_default_message()
						button.force_next_send()
			self._instrument_controller.set_enabled(enabled)
		

	def _setup_device_controller(self, as_active):
		if self._device_controller!=None:
			if as_active:
				self._m4lmode_index = 2
				self.refresh_map_display()
				self._activate_scene_buttons(True)
				self._activate_matrix(True)
				self._activate_navigation_buttons(True)
 				self._device_controller._is_active = True
				self._config_button.send_value(32)
				self._device_controller.set_enabled(True)
				self._device_controller.update()
 			else:
				self._device_controller._is_active = False
				self._device_controller.set_enabled(False)



				
	def _setup_user_mode(self, release_matrix=True, release_side_buttons=True, release_nav_buttons = True, drum_rack_mode = True):
		for scene_index in range(8):
			scene_button = self._side_buttons[scene_index]
			scene_button.set_on_off_values(127, LED_OFF)
			scene_button.force_next_send()
			scene_button.turn_off()
			scene_button.set_enabled((not release_side_buttons))
				
			for track_index in range(8):
				button = self._matrix.get_button(track_index, scene_index)
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
				button.set_enabled((not release_matrix))

		for button in self._nav_buttons:
			button.set_on_off_values(127, LED_OFF)
			button.turn_off()
			button.set_enabled((not release_nav_buttons))

		if drum_rack_mode:
			self._config_button.send_value(2)
		self._config_button.send_value(32)
		

	def _setup_step_sequencer(self, as_active):
		if(self._stepseq!=None):
			if(self._stepseq.is_enabled()!=as_active):
				if as_active: 
					self._activate_scene_buttons(True)
					self._activate_matrix(True)
					self._activate_navigation_buttons(True)
					self._config_button.send_value(32)
					self._stepseq.set_enabled(True)
				else:
					self._stepseq.set_enabled(False)
					

	def _setup_step_sequencer2(self, as_active):
		if(self._stepseq2!=None):
			if(self._stepseq2.is_enabled()!=as_active):
				if as_active: 
					self._activate_scene_buttons(True)
					self._activate_matrix(True)
					self._activate_navigation_buttons(True)
					self._config_button.send_value(32)
					self._stepseq2.set_enabled(True)
				else:
					self._stepseq2.set_enabled(False)


	def _setup_mixer(self, as_active):
		assert isinstance(as_active, type(False))
		if as_active:
			self._activate_navigation_buttons(True)
			self._activate_scene_buttons(True)
			self._activate_matrix(True)
			if(self._sub_modes.is_enabled()):
				#go back to default mode
				self._sub_modes.set_mode(-1)
		self._sub_modes.set_enabled(as_active)
		

	def _init_session(self):
		if self._parent._live_major_version >= 9 and self._parent._live_minor_version >= 1 and self._parent._live_bugfix_version >= 2:
			#api changed in 9.1.2
			self._session.set_stop_clip_value(AMBER_THIRD)
			self._session.set_stop_clip_triggered_value(AMBER_BLINK)
		else:
			# api for 9.1.1 below
			self._session.set_stop_track_clip_value(AMBER_BLINK)
		
		for scene_index in range(self._matrix.height()):
			scene = self._session.scene(scene_index)
			scene.set_triggered_value(GREEN_BLINK)
			scene.name = 'Scene_' + str(scene_index)
			for track_index in range(self._matrix.width()):
				clip_slot = scene.clip_slot(track_index)
				clip_slot.set_triggered_to_play_value(GREEN_BLINK)
				clip_slot.set_triggered_to_record_value(RED_BLINK)
				clip_slot.set_stopped_value(AMBER_FULL)
				clip_slot.set_started_value(GREEN_FULL)
				clip_slot.set_recording_value(RED_FULL)
				clip_slot.set_record_button_value(RED_THIRD)
				#clip_slot.set_clip_palette(CLIP_COLOR_TABLE)
				#clip_slot.set_clip_rgb_table(RGB_COLOR_TABLE)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				self._all_buttons.append(self._matrix.get_button(track_index, scene_index))

		self._zooming.set_stopped_value(RED_FULL)
		self._zooming.set_selected_value(AMBER_FULL)
		self._zooming.set_playing_value(GREEN_FULL)



	def _activate_navigation_buttons(self,active):
		for button in self._nav_buttons:
			button.set_enabled(active)

	def _activate_scene_buttons(self,active):
		for button in self._side_buttons:
			button.set_enabled(active)
			
	def _activate_matrix(self,active):
		for scene_index in range(8):
			for track_index in range(8):
				self._matrix.get_button(track_index, scene_index).set_enabled(active)
				
	def log_message(self, msg):
		self._parent.log_message(msg)
		
	#Update the channels of the buttons in the user modes..
	def _update_control_channels(self):
		new_channel = self.channel_for_current_mode()
		for button in self._all_buttons:
			button.set_channel(new_channel)
			button.set_force_next_value()