class SubSelectorComponent(ModeSelectorComponent):
    """ Class that handles different mixer modes """

    def __init__(self, matrix, side_buttons, session):
        raise isinstance(matrix, ButtonMatrixElement) or AssertionError
        raise matrix.width() == 8 and matrix.height() == 8 or AssertionError
        raise isinstance(side_buttons, tuple) or AssertionError
        raise len(side_buttons) == 8 or AssertionError
        raise isinstance(session, SessionComponent) or AssertionError
        ModeSelectorComponent.__init__(self)
        self._session = session
        self._mixer = SpecialMixerComponent(matrix.width())
        self._matrix = matrix
        self._sliders = []
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_strip'
        self._mixer.selected_strip().name = 'Selected_Channel_strip'
        for column in range(matrix.width()):
            self._mixer.channel_strip(column).name = 'Channel_Strip_' + str(column)
            self._sliders.append(PreciseButtonSliderElement(tuple([ matrix.get_button(column, 7 - row) for row in range(8) ])))
            self._sliders[-1].name = 'Button_Slider_' + str(column)

        self._side_buttons = side_buttons[4:]
        self._update_callback = None
        self._session.set_mixer(self._mixer)
        self.set_modes_buttons(side_buttons[:4])

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

        self._session = None
        self._mixer = None
        for slider in self._sliders:
            slider.release_parameter()
            slider.set_disabled(True)

        self._sliders = None
        self._matrix = None
        self._side_buttons = None
        self._update_callback = None
        ModeSelectorComponent.disconnect(self)

    def set_update_callback(self, callback):
        raise dir(callback).count('im_func') is 1 or AssertionError
        self._update_callback = callback

    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)

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

    def mode(self):
        result = 0
        if self.is_enabled():
            result = self._mode_index + 1
        return result

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        enabled = self.is_enabled()
        for index in range(self._matrix.width()):
            self._sliders[index].set_disabled(not enabled)

        self._mixer.set_enabled(enabled)
        self.set_mode(-1)

    def release_controls(self):
        for track in range(self._matrix.width()):
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, LED_OFF)

            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)

        self._session.set_stop_track_clip_buttons(None)
        self._mixer.set_global_buttons(None, None, None)
        self._session.set_stop_all_clips_button(None)

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

                for button in self._side_buttons:
                    button.set_on_off_values(127, LED_OFF)
                    button.turn_off()

                for index in range(self._matrix.width()):
                    self._sliders[index].set_disabled(self._mode_index == -1)

                self._mixer.set_allow_update(False)
                self._session.set_allow_update(False)
                if self._mode_index == -1:
                    self._setup_mixer_overview()
                elif self._mode_index == 0:
                    self._setup_volume_mode()
                elif self._mode_index == 1:
                    self._setup_pan_mode()
                elif self._mode_index == 2:
                    self._setup_send1_mode()
                elif self._mode_index == 3:
                    self._setup_send2_mode()
                else:
                    raise False or AssertionError
                self._update_callback != None and self._update_callback()
            self._mixer.set_allow_update(True)
            self._session.set_allow_update(True)
        else:
            self.release_controls()

    def _setup_mixer_overview(self):
        trkon_index = 5
        stop_buttons = []
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)
            self._sliders[track].release_parameter()
            for row in range(self._matrix.height()):
                full_value = GREEN_THIRD
                third_value = GREEN_FULL
                if row == trkon_index:
                    full_value = AMBER_FULL
                    third_value = AMBER_THIRD
                elif row > 3:
                    full_value = RED_FULL
                    third_value = RED_THIRD
                self._matrix.get_button(track, row).set_on_off_values(full_value, third_value)

            strip.set_default_buttons(self._matrix.get_button(track, 0), self._matrix.get_button(track, 1), self._matrix.get_button(track, 2), self._matrix.get_button(track, 3))
            stop_buttons.append(self._matrix.get_button(track, 4))
            strip.set_mute_button(self._matrix.get_button(track, 5))
            strip.set_solo_button(self._matrix.get_button(track, 6))
            strip.set_arm_button(self._matrix.get_button(track, 7))

        for button in self._side_buttons:
            if list(self._side_buttons).index(button) == trkon_index - 4:
                button.set_on_off_values(AMBER_FULL, AMBER_THIRD)
            else:
                button.set_on_off_values(RED_FULL, RED_THIRD)
            button.set_force_next_value()
            button.turn_off()

        self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
        self._session.set_stop_all_clips_button(self._side_buttons[0])
        self._mixer.set_global_buttons(self._side_buttons[3], self._side_buttons[2], self._side_buttons[1])

    def _setup_volume_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(GREEN_FULL, LED_OFF)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(VOL_VALUE_MAP)
            strip.set_volume_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_pan_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_volume_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(AMBER_FULL, LED_OFF)

            self._sliders[track].set_mode(SLIDER_MODE_PAN)
            self._sliders[track].set_value_map(PAN_VALUE_MAP)
            strip.set_pan_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_send1_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(RED_FULL, LED_OFF)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((self._sliders[track], None))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_send2_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(RED_FULL, LED_OFF)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((None, self._sliders[track]))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
class LaunchControl(ControlSurface):

    def __init__(self, c_instance):
        super(LaunchControl, self).__init__(c_instance)
        with self.component_guard():
            self._device_selection_follows_track_selection = True
            self._init_mixer()
            self._init_session()
            self._init_device()
            self._init_modes()
            self._refresh_state_task = self._tasks.add(Task.sequence(Task.delay(3), Task.run(self._do_refresh_state)))
            self._refresh_state_task.kill()
        self.log_message('Launch Control script loaded')

    def disconnect(self):
        super(LaunchControl, self).disconnect()
        for channel in xrange(16):
            self._send_midi((CC_STATUS + channel, 0, 0))

    def refresh_state(self):
        self._refresh_state_task.restart()

    def _do_refresh_state(self):
        self._send_current_mode()
        self._update_hardware()
        self.schedule_message(3, super(LaunchControl, self).refresh_state)

    def _update_hardware(self):
        for channel in xrange(8, 11):
            self._send_midi(Sysex.make_automatic_flashing_message(channel))

    def _send_current_mode(self):
        try:
            self._send_midi(MODE_SYSEX_MAP[self._modes.selected_mode])
        except KeyError:
            pass

    def _init_mixer(self):
        make_button = partial(make_launch_control_button, channel=8)
        make_encoder = partial(make_launch_control_encoder, channel=8)
        bottom_encoders, top_encoders = make_all_encoders('Mixer', make_encoder)
        pan_volume_layer = Layer(volume_controls=ButtonMatrixElement(rows=[bottom_encoders]), pan_controls=ButtonMatrixElement(rows=[top_encoders]))
        sends_layer = Layer(sends_controls=ButtonMatrixElement(rows=[bottom_encoders, top_encoders]))
        modes_layer = Layer(pan_volume_button=make_button(114, 'Pan_Volume_Mode_Button'), sends_button=make_button(115, 'Sends_Mode_Button'))
        self._mixer = SpecialMixerComponent(8, modes_layer, pan_volume_layer, sends_layer)
        self._mixer.name = 'Mixer'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer_track_nav_layer = Layer(track_bank_left_button=make_button(116, 'Mixer_Track_Left_Button'), track_bank_right_button=make_button(117, 'Mixer_Track_Right_Button'))
        for index in xrange(8):
            strip = self._mixer.channel_strip(index)
            strip.name = 'Channel_Strip_' + str(index)
            strip.empty_color = Colors.LED_OFF
            strip.set_invert_mute_feedback(True)
            mute_button = make_button(pad_identifiers[index], 'Track_Mute_Button_' + str(index), is_pad=True)
            mute_button.set_on_off_values(Colors.AMBER_FULL, Colors.AMBER_THIRD)
            strip.set_mute_button(mute_button)

        self._on_selected_send_index.subject = self._mixer
        self._on_selected_mixer_mode.subject = self._mixer

    def _init_session(self):
        make_button = partial(make_launch_control_button, channel=9)
        make_encoder = partial(make_launch_control_encoder, channel=9)
        bottom_encoders, top_encoders = make_all_encoders('Session_Mixer', make_encoder)
        pan_volume_layer = Layer(volume_controls=ButtonMatrixElement(rows=[bottom_encoders]), pan_controls=ButtonMatrixElement(rows=[top_encoders]))
        self._session_mixer = SpecialMixerComponent(8, Layer(), pan_volume_layer, Layer())
        self._session_mixer.set_enabled(False)
        self._session_mixer.name = 'Session_Mixer'
        clip_launch_buttons = [ make_button(identifier, 'Clip_Launch_Button_' + str(i), is_pad=True) for i, identifier in enumerate(pad_identifiers) ]
        self._session = SpecialSessionComponent(num_tracks=8, num_scenes=0, name='Session')
        self._session.set_enabled(False)
        self._session.set_mixer(self._session_mixer)
        self._session_layer = Layer(track_bank_left_button=make_button(116, 'Track_Bank_Left_Button'), track_bank_right_button=make_button(117, 'Track_Bank_Right_Button'), select_prev_button=make_button(114, 'Scene_Bank_Up_Button'), select_next_button=make_button(115, 'Scene_Bank_Down_Button'), clip_launch_buttons=ButtonMatrixElement(rows=[clip_launch_buttons]))
        scene = self._session.selected_scene()
        for index in range(8):
            clip_slot = scene.clip_slot(index)
            clip_slot.set_triggered_to_play_value(Colors.GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(Colors.RED_BLINK)
            clip_slot.set_stopped_value(Colors.AMBER_FULL)
            clip_slot.set_started_value(Colors.GREEN_FULL)
            clip_slot.set_recording_value(Colors.RED_FULL)
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._on_track_offset.subject = self._session

    def _init_device(self):
        make_button = partial(make_launch_control_button, channel=10)
        make_encoder = partial(make_launch_control_encoder, channel=10)
        bottom_encoders, top_encoders = make_all_encoders('Device', make_encoder)
        parameter_controls = top_encoders[:4] + bottom_encoders[:4]
        bank_buttons = [ make_button(identifier, 'Device_Bank_Button_' + str(i), is_pad=True) for i, identifier in enumerate(pad_identifiers) ]
        for button in bank_buttons:
            button.set_on_off_values(Colors.LED_ON, Colors.LED_OFF)

        self._device_bank_registry = DeviceBankRegistry()
        self._device = DeviceComponent(device_bank_registry=self._device_bank_registry, name='Device')
        self._device.set_enabled(False)
        self._device.layer = Layer(parameter_controls=ButtonMatrixElement(rows=[parameter_controls]), bank_buttons=ButtonMatrixElement(rows=[bank_buttons]))
        self.set_device_component(self._device)
        self._device_navigation = DeviceNavigationComponent()
        self._device_navigation.set_enabled(False)
        self._device_navigation.name = 'Device_Navigation'
        self._device_navigation.layer = Layer(next_device_button=make_button(115, 'Next_Device_Button'), previous_device_button=make_button(114, 'Prev_Device_Button'))
        self._view_control = ViewControlComponent()
        self._view_control.set_enabled(False)
        self._view_control.name = 'View_Control'
        self._view_control.layer = Layer(next_track_button=make_button(117, 'Device_Next_Track_Button'), prev_track_button=make_button(116, 'Device_Prev_Track_Button'))

    def _init_modes(self):
        self._modes = ModesComponent()
        self._modes.add_mode('mixer', [partial(self._session.set_mixer, self._mixer),
         LayerMode(self._session, self._mixer_track_nav_layer),
         self._mixer,
         self._session,
         self._show_controlled_tracks_message])
        self._modes.add_mode('session', [partial(self._session.set_mixer, self._session_mixer),
         LayerMode(self._session, self._session_layer),
         self._session_mixer,
         self._session,
         self._show_controlled_tracks_message])
        self._modes.add_mode('device', [self._device, self._device_navigation, self._view_control])
        self._modes.add_mode('user', None)
        self._modes.selected_mode = 'mixer'
        self._modes.layer = Layer(mixer_button=ButtonSysexControl(Sysex.MIXER_MODE), session_button=ButtonSysexControl(Sysex.SESSION_MODE), device_button=ButtonSysexControl(Sysex.DEVICE_MODE))

    @subject_slot('offset')
    def _on_track_offset(self):
        self._show_controlled_tracks_message()

    @subject_slot('selected_send_index')
    def _on_selected_send_index(self, index):
        self._show_controlled_sends_message()

    @subject_slot('selected_mixer_mode')
    def _on_selected_mixer_mode(self, mode):
        if mode == 'sends':
            self._show_controlled_sends_message()
        else:
            self.show_message('Controlling Pan and Volume')

    def _show_controlled_tracks_message(self):
        start = self._session.track_offset() + 1
        end = min(start + 8, len(self._session.tracks_to_use()))
        if start < end:
            self.show_message('Controlling Track %d to %d' % (start, end))
        else:
            self.show_message('Controlling Track %d' % start)

    def _show_controlled_sends_message(self):
        send_index = self._mixer.selected_send_index
        send_name1 = chr(ord('A') + send_index)
        if send_index + 1 < self._mixer.num_sends:
            send_name2 = chr(ord('A') + send_index + 1)
            self.show_message('Controlling Send %s and %s' % (send_name1, send_name2))
        else:
            self.show_message('Controlling Send %s' % send_name1)

    def handle_sysex(self, midi_bytes):
        super(LaunchControl, self).handle_sysex(midi_bytes)
        if self._is_user_mode_message(midi_bytes):
            self._modes.selected_mode = 'user'
            self.request_rebuild_midi_map()

    def _is_user_mode_message(self, midi_bytes):
        """
        True if midi_byes refer to a mode change, but none of the three
        predefined Live modes
        """
        return midi_bytes[:7] == Sysex.MODE_CHANGE_PREFIX and midi_bytes not in SYSEX_MODE_MAP
class SubSelectorComponent(ModeSelectorComponent):
    """ Class that handles different mixer modes """
    def __init__(self, matrix, side_buttons, session, control_surface):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(session, SessionComponent)
        ModeSelectorComponent.__init__(self)
        self._control_surface = control_surface
        self._session = session
        self._mixer = SpecialMixerComponent(matrix.width())
        self._matrix = matrix
        self._sliders = []
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_strip'
        self._mixer.selected_strip().name = 'Selected_Channel_strip'
        for column in range(matrix.width()):
            self._mixer.channel_strip(
                column).name = 'Channel_Strip_' + str(column)
            self._sliders.append(
                PreciseButtonSliderElement(
                    tuple([
                        matrix.get_button(column, 7 - row) for row in range(8)
                    ])))
            self._sliders[-1].name = 'Button_Slider_' + str(column)

        self._side_buttons = side_buttons[4:]
        self._update_callback = None
        self._session.set_mixer(self._mixer)
        self.set_modes_buttons(side_buttons[:4])

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

        self._session = None
        self._mixer = None
        for slider in self._sliders:
            slider.release_parameter()
            slider.set_disabled(True)

        self._sliders = None
        self._matrix = None
        self._side_buttons = None
        self._update_callback = None
        ModeSelectorComponent.disconnect(self)

    def set_update_callback(self, callback):
        assert (dir(callback).count("im_func") is 1)
        self._update_callback = callback

    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)

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

    def mode(self):
        result = 0
        if self.is_enabled():
            result = self._mode_index + 1
        return result

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        enabled = self.is_enabled()
        for index in range(self._matrix.width()):
            self._sliders[index].set_disabled(not enabled)

        self._mixer.set_enabled(enabled)
        self.set_mode(-1)

    def release_controls(self):
        for track in range(self._matrix.width()):
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(
                    127, "DefaultButton.Disabled")

            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)

        self._session.set_stop_track_clip_buttons(None)
        self._mixer.set_global_buttons(None, None, None)
        self._session.set_stop_all_clips_button(None)

    def update(self):
        assert (self._modes_buttons != None)
        if self.is_enabled():
            if (self._modes_buttons != None):
                for index in range(len(self._modes_buttons)):
                    button = self._modes_buttons[index]
                    if index == 0:
                        button.set_on_off_values("Mixer.Volume")
                    elif index == 1:
                        button.set_on_off_values("Mixer.Pan")
                    elif index == 2:
                        button.set_on_off_values("Mixer.Sends")
                    elif index == 3:
                        button.set_on_off_values("Mixer.Sends")
                    elif index == 4:
                        button.set_on_off_values("Mixer.Stop")
                    elif index == 5:
                        button.set_on_off_values("Mixer.Mute")
                    elif index == 6:
                        button.set_on_off_values("Mixer.Solo")
                    elif index == 7:
                        button.set_on_off_values("Mixer.Arm")
                    if (index == self._mode_index):
                        button.turn_on()
                    else:
                        button.turn_off()

            for button in self._side_buttons:
                button.set_on_off_values(127, "DefaultButton.Disabled")
                button.turn_off()

            for index in range(self._matrix.width()):
                self._sliders[index].set_disabled((self._mode_index == -1))

            self._mixer.set_allow_update(False)
            self._session.set_allow_update(False)
            if self._mode_index == -1:
                self._setup_mixer_overview()
            elif self._mode_index == 0:
                self._setup_volume_mode()
            elif self._mode_index == 1:
                self._setup_pan_mode()
            elif self._mode_index == 2:
                self._setup_send1_mode()
            elif self._mode_index == 3:
                self._setup_send2_mode()
            else:
                assert False
            if (self._update_callback != None):
                self._update_callback()
            self._mixer.set_allow_update(True)
            self._session.set_allow_update(True)
        #else:
        #self.release_controls()

    def _setup_mixer_overview(self):
        stop_buttons = []
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)
            self._sliders[track].release_parameter()
            for row in range(self._matrix.height()):
                if row == 0:
                    self._matrix.get_button(
                        track, row).set_on_off_values("Mixer.Volume")
                elif row == 1:
                    self._matrix.get_button(track,
                                            row).set_on_off_values("Mixer.Pan")
                elif row == 2:
                    self._matrix.get_button(
                        track, row).set_on_off_values("Mixer.Sends")
                elif row == 3:
                    self._matrix.get_button(
                        track, row).set_on_off_values("Mixer.Sends")
                elif row == 4:
                    self._matrix.get_button(
                        track, row).set_on_off_values("Mixer.Stop")
                elif row == 5:
                    self._matrix.get_button(
                        track, row).set_on_off_values("Mixer.Mute")
                elif row == 6:
                    self._matrix.get_button(
                        track, row).set_on_off_values("Mixer.Solo")
                elif row == 7:
                    self._matrix.get_button(track,
                                            row).set_on_off_values("Mixer.Arm")

            strip.set_default_buttons(self._matrix.get_button(track, 0),
                                      self._matrix.get_button(track, 1),
                                      self._matrix.get_button(track, 2),
                                      self._matrix.get_button(track, 3))
            stop_buttons.append(self._matrix.get_button(track, 4))
            strip.set_mute_button(self._matrix.get_button(track, 5))
            strip.set_solo_button(self._matrix.get_button(track, 6))
            strip.set_arm_button(self._matrix.get_button(track, 7))

        for button in self._side_buttons:
            if row == 0:
                button.set_on_off_values("Mixer.Volume")
            elif row == 1:
                button.set_on_off_values("Mixer.Pan")
            elif row == 2:
                button.set_on_off_values("Mixer.Sends")
            elif row == 3:
                button.set_on_off_values("Mixer.Sends")
            elif row == 4:
                button.set_on_off_values("Mixer.Stop")
            elif row == 5:
                button.set_on_off_values("Mixer.Mute")
            elif row == 6:
                button.set_on_off_values("Mixer.Solo")
            elif row == 7:
                button.set_on_off_values("Mixer.Arm")
            button.force_next_send()
            button.turn_on()

        self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
        self._session.set_stop_all_clips_button(self._side_buttons[0])
        self._mixer.set_global_buttons(self._side_buttons[3],
                                       self._side_buttons[2],
                                       self._side_buttons[1])

    def _setup_volume_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(
                    track, row).set_on_off_values("Mixer.VolumeSlider")

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(VOL_VALUE_MAP)
            strip.set_volume_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_pan_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_volume_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(
                    track, row).set_on_off_values("Mixer.PanSlider")

            self._sliders[track].set_mode(SLIDER_MODE_PAN)
            self._sliders[track].set_value_map(PAN_VALUE_MAP)
            strip.set_pan_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_send1_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(
                    track, row).set_on_off_values("Mixer.SendsSlider")

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((self._sliders[track], None))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_send2_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(
                    track, row).set_on_off_values("Mixer.SendsSlider")

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((None, self._sliders[track]))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
Esempio n. 4
0
class LaunchControl(ControlSurface):

    def __init__(self, c_instance):
        super(LaunchControl, self).__init__(c_instance)
        with self.component_guard():
            self._device_selection_follows_track_selection = True
            self._init_mixer()
            self._init_session()
            self._init_device()
            self._init_modes()
            self._refresh_state_task = self._tasks.add(Task.sequence(Task.delay(3), Task.run(self._do_refresh_state)))
            self._refresh_state_task.kill()
        self.log_message('Launch Control script loaded')

    def disconnect(self):
        super(LaunchControl, self).disconnect()
        for channel in xrange(16):
            self._send_midi((CC_STATUS + channel, 0, 0))

    def refresh_state(self):
        self._refresh_state_task.restart()

    def _do_refresh_state(self):
        self._send_current_mode()
        self._update_hardware()
        self.schedule_message(3, super(LaunchControl, self).refresh_state)

    def _update_hardware(self):
        for channel in xrange(8, 11):
            self._send_midi(Sysex.make_automatic_flashing_message(channel))

    def _send_current_mode(self):
        try:
            self._send_midi(MODE_SYSEX_MAP[self._modes.selected_mode])
        except KeyError:
            pass

    def _init_mixer(self):
        make_button = partial(make_launch_control_button, channel=8)
        make_encoder = partial(make_launch_control_encoder, channel=8)
        bottom_encoders, top_encoders = make_all_encoders('Mixer', make_encoder)
        pan_volume_layer = Layer(volume_controls=ButtonMatrixElement(rows=[bottom_encoders]), pan_controls=ButtonMatrixElement(rows=[top_encoders]))
        sends_layer = Layer(sends_controls=ButtonMatrixElement(rows=[bottom_encoders, top_encoders]))
        modes_layer = Layer(pan_volume_button=make_button(114, 'Pan_Volume_Mode_Button'), sends_button=make_button(115, 'Sends_Mode_Button'))
        self._mixer = SpecialMixerComponent(8, modes_layer, pan_volume_layer, sends_layer)
        self._mixer.set_enabled(False)
        self._mixer.name = 'Mixer'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer_track_nav_layer = Layer(track_bank_left_button=make_button(116, 'Mixer_Track_Left_Button'), track_bank_right_button=make_button(117, 'Mixer_Track_Right_Button'))
        for index in xrange(8):
            strip = self._mixer.channel_strip(index)
            strip.name = 'Channel_Strip_' + str(index)
            strip.empty_color = Colors.LED_OFF
            strip.set_invert_mute_feedback(True)
            mute_button = make_button(pad_identifiers[index], 'Track_Mute_Button_' + str(index), is_pad=True)
            mute_button.set_on_off_values(Colors.AMBER_FULL, Colors.AMBER_THIRD)
            strip.set_mute_button(mute_button)

        self._on_selected_send_index.subject = self._mixer
        self._on_selected_mixer_mode.subject = self._mixer

    def _init_session(self):
        make_button = partial(make_launch_control_button, channel=9)
        make_encoder = partial(make_launch_control_encoder, channel=9)
        bottom_encoders, top_encoders = make_all_encoders('Session_Mixer', make_encoder)
        pan_volume_layer = Layer(volume_controls=ButtonMatrixElement(rows=[bottom_encoders]), pan_controls=ButtonMatrixElement(rows=[top_encoders]))
        self._session_mixer = SpecialMixerComponent(8, Layer(), pan_volume_layer, Layer())
        self._session_mixer.set_enabled(False)
        self._session_mixer.name = 'Session_Mixer'
        clip_launch_buttons = [ make_button(identifier, 'Clip_Launch_Button_' + str(i), is_pad=True) for i, identifier in enumerate(pad_identifiers) ]
        self._session = SpecialSessionComponent(num_tracks=8, num_scenes=0, name='Session')
        self._session.set_enabled(False)
        self._session.set_mixer(self._session_mixer)
        self._session_layer = Layer(track_bank_left_button=make_button(116, 'Track_Bank_Left_Button'), track_bank_right_button=make_button(117, 'Track_Bank_Right_Button'), select_prev_button=make_button(114, 'Scene_Bank_Up_Button'), select_next_button=make_button(115, 'Scene_Bank_Down_Button'), clip_launch_buttons=ButtonMatrixElement(rows=[clip_launch_buttons]))
        scene = self._session.selected_scene()
        for index in range(8):
            clip_slot = scene.clip_slot(index)
            clip_slot.set_triggered_to_play_value(Colors.GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(Colors.RED_BLINK)
            clip_slot.set_stopped_value(Colors.AMBER_FULL)
            clip_slot.set_started_value(Colors.GREEN_FULL)
            clip_slot.set_recording_value(Colors.RED_FULL)
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._on_track_offset.subject = self._session

    def _init_device(self):
        make_button = partial(make_launch_control_button, channel=10)
        make_encoder = partial(make_launch_control_encoder, channel=10)
        bottom_encoders, top_encoders = make_all_encoders('Device', make_encoder)
        parameter_controls = top_encoders[:4] + bottom_encoders[:4]
        bank_buttons = [ make_button(identifier, 'Device_Bank_Button_' + str(i), is_pad=True) for i, identifier in enumerate(pad_identifiers) ]
        for button in bank_buttons:
            button.set_on_off_values(Colors.LED_ON, Colors.LED_OFF)

        self._device_bank_registry = DeviceBankRegistry()
        self._device = DeviceComponent(device_bank_registry=self._device_bank_registry, name='Device')
        self._device.set_enabled(False)
        self._device.layer = Layer(parameter_controls=ButtonMatrixElement(rows=[parameter_controls]), bank_buttons=ButtonMatrixElement(rows=[bank_buttons]))
        self.set_device_component(self._device)
        self._device_navigation = DeviceNavigationComponent()
        self._device_navigation.set_enabled(False)
        self._device_navigation.name = 'Device_Navigation'
        self._device_navigation.layer = Layer(next_device_button=make_button(115, 'Next_Device_Button'), previous_device_button=make_button(114, 'Prev_Device_Button'))
        self._view_control = ViewControlComponent()
        self._view_control.set_enabled(False)
        self._view_control.name = 'View_Control'
        self._view_control.layer = Layer(next_track_button=make_button(117, 'Device_Next_Track_Button'), prev_track_button=make_button(116, 'Device_Prev_Track_Button'))

    def _init_modes(self):
        self._modes = ModesComponent(is_root=True)
        self._modes.add_mode('mixer', [partial(self._session.set_mixer, self._mixer),
         LayerMode(self._session, self._mixer_track_nav_layer),
         self._mixer,
         self._session,
         self._show_controlled_tracks_message])
        self._modes.add_mode('session', [partial(self._session.set_mixer, self._session_mixer),
         LayerMode(self._session, self._session_layer),
         self._session_mixer,
         self._session,
         self._show_controlled_tracks_message])
        self._modes.add_mode('device', [self._device, self._device_navigation, self._view_control])
        self._modes.add_mode('user', None)
        self._modes.selected_mode = 'mixer'
        self._modes.layer = Layer(mixer_button=ButtonSysexControl(Sysex.MIXER_MODE), session_button=ButtonSysexControl(Sysex.SESSION_MODE), device_button=ButtonSysexControl(Sysex.DEVICE_MODE))
        return

    @subject_slot('offset')
    def _on_track_offset(self):
        self._show_controlled_tracks_message()

    @subject_slot('selected_send_index')
    def _on_selected_send_index(self, index):
        self._show_controlled_sends_message()

    @subject_slot('selected_mixer_mode')
    def _on_selected_mixer_mode(self, mode):
        if mode == 'sends':
            self._show_controlled_sends_message()
        else:
            self.show_message('Controlling Pan and Volume')

    def _show_controlled_tracks_message(self):
        start = self._session.track_offset() + 1
        end = min(start + 8, len(self._session.tracks_to_use()))
        if start < end:
            self.show_message('Controlling Track %d to %d' % (start, end))
        else:
            self.show_message('Controlling Track %d' % start)

    def _show_controlled_sends_message(self):
        send_index = self._mixer.selected_send_index
        send_name1 = chr(ord('A') + send_index)
        if send_index + 1 < self._mixer.num_sends:
            send_name2 = chr(ord('A') + send_index + 1)
            self.show_message('Controlling Send %s and %s' % (send_name1, send_name2))
        else:
            self.show_message('Controlling Send %s' % send_name1)

    def handle_sysex(self, midi_bytes):
        super(LaunchControl, self).handle_sysex(midi_bytes)
        if self._is_user_mode_message(midi_bytes):
            self._modes.selected_mode = 'user'
            self.request_rebuild_midi_map()

    def _is_user_mode_message(self, midi_bytes):
        """
        True if midi_byes refer to a mode change, but none of the three
        predefined Live modes
        """
        return midi_bytes[:7] == Sysex.MODE_CHANGE_PREFIX and midi_bytes not in SYSEX_MODE_MAP
Esempio n. 5
0
class SubSelectorComponent(ModeSelectorComponent):
    __module__ = __name__
    __doc__ = ' Class that handles different mixer modes '

    def __init__(self, matrix, side_buttons, session):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(session, SessionComponent)
        ModeSelectorComponent.__init__(self)
        self._session = session
        self._mixer = SpecialMixerComponent(matrix.width())
        self._matrix = matrix
        self._sliders = []
        for column in range(8):
            self._sliders.append(
                PreciseButtonSliderElement(
                    tuple([
                        matrix.get_button(column, (7 - row))
                        for row in range(8)
                    ])))

        self._side_buttons = side_buttons[4:]
        self._update_callback = None
        self._session.set_mixer(self._mixer)
        self.set_modes_buttons(side_buttons[:4])

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

        self._session = None
        self._mixer = None
        for slider in self._sliders:
            slider.release_parameter()
            slider.set_disabled(True)

        self._sliders = None
        self._matrix = None
        self._side_buttons = None
        self._update_callback = None
        ModeSelectorComponent.disconnect(self)

    def set_update_callback(self, callback):
        assert (dir(callback).count('im_func') is 1)
        self._update_callback = callback

    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)

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

    def mode(self):
        result = 0
        if self.is_enabled():
            result = (self._mode_index + 1)
        return result

    def number_of_modes(self):
        return 4

    def on_enabled_changed(self):
        enabled = self.is_enabled()
        for index in range(self._matrix.width()):
            self._sliders[index].set_disabled((not enabled))

        self._mixer.set_enabled(enabled)
        self.set_mode(-1)

    def release_controls(self):
        for track in range(self._matrix.width()):
            for row in range(self._matrix.height()):
                self._matrix.get_button(track,
                                        row).set_on_off_values(127, LED_OFF)

            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)

        self._session.set_stop_track_clip_buttons(None)
        self._mixer.set_global_buttons(None, None, None)
        self._session.set_stop_all_clips_button(None)

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

            for button in self._side_buttons:
                button.set_on_off_values(127, 0)
                button.turn_off()

            for index in range(self._matrix.width()):
                self._sliders[index].set_disabled((self._mode_index == -1))

            self._mixer.set_allow_update(False)
            self._session.set_allow_update(False)
            if (self._mode_index == -1):
                self._setup_mixer_overview()
            elif (self._mode_index == 0):
                self._setup_volume_mode()
            elif (self._mode_index == 1):
                self._setup_pan_mode()
            elif (self._mode_index == 2):
                self._setup_send1_mode()
            elif (self._mode_index == 3):
                self._setup_send2_mode()
            else:
                assert False
            if (self._update_callback != None):
                self._update_callback()
            #self._rebuild_callback()
            self._mixer.set_allow_update(True)
            self._session.set_allow_update(True)
        else:
            self.release_controls()

    def _setup_mixer_overview(self):
        trkon_index = 5
        stop_buttons = []
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)
            self._sliders[track].release_parameter()
            for row in range(self._matrix.height()):
                full_value = 1
                third_value = 0
                if (row == trkon_index):
                    full_value = 127
                    third_value = 0
                elif (row > 3):
                    full_value = 127
                    third_value = 0
                self._matrix.get_button(track, row).set_on_off_values(
                    full_value, third_value)

            strip.set_default_buttons(self._matrix.get_button(track, 0),
                                      self._matrix.get_button(track, 1),
                                      self._matrix.get_button(track, 2),
                                      self._matrix.get_button(track, 3))
            stop_buttons.append(self._matrix.get_button(track, 4))
            strip.set_mute_button(self._matrix.get_button(track, 5))
            strip.set_solo_button(self._matrix.get_button(track, 6))
            strip.set_arm_button(self._matrix.get_button(track, 7))

        for button in self._side_buttons:
            if (list(self._side_buttons).index(button) == (trkon_index - 4)):
                button.set_on_off_values(127, 0)
            else:
                button.set_on_off_values(127, 0)
            button.set_force_next_value()
            button.turn_off()

        self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
        self._session.set_stop_all_clips_button(self._side_buttons[0])
        self._mixer.set_global_buttons(self._side_buttons[3],
                                       self._side_buttons[2],
                                       self._side_buttons[1])

    def _setup_volume_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(VOL_VALUE_MAP)
            strip.set_volume_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_pan_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None, None))
            strip.set_volume_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_PAN)
            self._sliders[track].set_value_map(PAN_VALUE_MAP)
            strip.set_pan_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_send1_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((self._sliders[track], None))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)

    def _setup_send2_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((None, self._sliders[track]))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
Esempio n. 6
0
class SpecialMixerSelectorComponent(ModeSelectorComponent):
	" CLASS THAT HANDLES DIFFERENT MIXER MODES "

	" INIT "
	def __init__(self, matrix, side_buttons, session):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(session, SessionComponent)
		ModeSelectorComponent.__init__(self)
		self._session = session
		self._mixer = SpecialMixerComponent(len(self.song().tracks))
		self._matrix = matrix
		self._mixer.name = "Mixer"
		self._mixer.master_strip().name = "Master_Channel_strip"
		self._mixer.selected_strip().name = "Selected_Channel_strip"
		for column in range(len(self.song().tracks)):
			button_index = 0
			if self.song().tracks[column].is_foldable:
				if button_index < GROUPS_CONSIDERED:
					self._mixer.channel_strip(column).name = ("Channel_Strip_" + str(column))
					button_index = button_index + 1
		self._side_buttons = side_buttons[5:]
		self._update_callback = None
		self._session.set_mixer(self._mixer)

	" DISCONNECT "
	def disconnect(self):
		self._session = None
		self._mixer = None
		self._matrix = None
		self._side_buttons = None
		self._update_callback = None
		ModeSelectorComponent.disconnect(self)

	" SET THE UPDATE CALLBACK "
	def set_update_callback(self, callback):
		assert (dir(callback).count("im_func") is 1)
		self._update_callback = callback

	" SET THE MODE "
	def set_mode(self, mode):
		assert isinstance(mode, int)
		assert (mode in range(-1, self.number_of_modes()))
		if ((self._mode_index != mode) or (mode == -1)):
			self._mode_index = mode
			self.update()

	" GET THE MODE "
	def mode(self):
		result = 0
		if self.is_enabled():
			result = (self._mode_index + 1)
		return result

	" GET NUMBER OF MODES "
	def number_of_modes(self):
		return 1

	" ENABLED CALLBACK "
	def on_enabled_changed(self):
		enabled = self.is_enabled()
		self._mixer.set_enabled(enabled)
		self.set_mode(-1)

	" RELEASE ALL THE CONTROLS "	
	def release_controls(self):
		for track in range(len(self.song().tracks)):
			button_index = 0
			if self.song().tracks[track].is_foldable:
				if button_index < GROUPS_CONSIDERED:
					for row in range(self._matrix.height()):
						self._matrix.get_button(button_index, row).set_on_off_values(127, LED_OFF)
						button_index = button_index + 1
			strip = self._mixer.channel_strip(track)
			strip.set_solo_button(None)
			strip.set_mute_button(None)   
		self._session.set_stop_track_clip_buttons(None)
		self._mixer.set_global_buttons(None, None, None)
		self._session.set_stop_all_clips_button(None)

	" UPDATE ME "
	def update(self):
		if self.is_enabled():
			for button in self._side_buttons:
				button.set_on_off_values(127, LED_OFF)
				button.turn_off()
			self._mixer.set_allow_update(False)
			self._session.set_allow_update(False)
			if (self._mode_index == -1):
				self._setup_mixer_overview()
			else:
				assert False
			if (self._update_callback != None):
				self._update_callback()
			self._mixer.set_allow_update(True)
			self._session.set_allow_update(True)
		else:
			self.release_controls()

	" SETUP THE MIXER "
	def _setup_mixer_overview(self):
		# mute and solo and stop
		stop_buttons = []
		button_index = 0
		for track in range(len(self.song().tracks)):
			if self.song().tracks[track].is_foldable:
				if button_index < GROUPS_CONSIDERED:
					strip = self._mixer.channel_strip(track)
					# mute
					self._matrix.get_button(button_index, MUTE_INDEX).set_on_off_values(GREEN_FULL, GREEN_THIRD)
					strip.set_mute_button(self._matrix.get_button(button_index, MUTE_INDEX))		
					# solo
					self._matrix.get_button(button_index, SOLO_INDEX).set_on_off_values(RED_FULL, RED_THIRD )			
					strip.set_solo_button(self._matrix.get_button(button_index, SOLO_INDEX))
					# stop				
					button = self._matrix.get_button(button_index, STOP_INDEX)				
					button.set_on_off_values(AMBER_FULL, AMBER_THIRD)				
					button.turn_on();
					stop_buttons.append(button)
					# increment
					button_index = button_index + 1
				else:
					stop_buttons.append(None)
			else:
				stop_buttons.append(None)				
			
		# side buttons
		self._side_buttons[0].set_on_off_values(RED_FULL, RED_THIRD)
		self._side_buttons[0].set_force_next_value()
		self._side_buttons[0].turn_off()		
		self._side_buttons[1].set_on_off_values(AMBER_FULL, AMBER_HALF)
		self._side_buttons[1].set_force_next_value()
		self._side_buttons[1].turn_off()
		self._side_buttons[2].set_on_off_values(GREEN_FULL, GREEN_THIRD)
		self._side_buttons[2].set_force_next_value()
		self._side_buttons[2].turn_on()
			
		self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
		self._session.set_mixer(self._mixer)
		self._session.set_stop_all_clips_button(self._side_buttons[1])
		self._mixer.set_global_buttons(self._side_buttons[2], self._side_buttons[0], self._side_buttons[1])
Esempio n. 7
0
class SubSelectorComponent(ModeSelectorComponent):

	""" Class that handles different mixer modes """

	def __init__(self, matrix, side_buttons, session, control_surface):
		assert isinstance(matrix, ButtonMatrixElement)
		assert ((matrix.width() == 8) and (matrix.height() == 8))
		assert isinstance(side_buttons, tuple)
		assert (len(side_buttons) == 8)
		assert isinstance(session, SessionComponent)
		ModeSelectorComponent.__init__(self)
		self._control_surface = control_surface
		self._session = session
		self._mixer = SpecialMixerComponent(matrix.width())
		self._matrix = matrix
		self._sliders = []
		self._mixer.name = 'Mixer'
		self._mixer.master_strip().name = 'Master_Channel_strip'
		self._mixer.selected_strip().name = 'Selected_Channel_strip'
		for column in range(matrix.width()):
			self._mixer.channel_strip(column).name = 'Channel_Strip_' + str(column)
			self._sliders.append(PreciseButtonSliderElement(tuple([matrix.get_button(column, 7 - row) for row in range(8)])))
			self._sliders[-1].name = 'Button_Slider_' + str(column)

		self._side_buttons = side_buttons[4:]
		self._update_callback = None
		self._session.set_mixer(self._mixer)
		self.set_modes_buttons(side_buttons[:4])

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

		self._session = None
		self._mixer = None
		for slider in self._sliders:
			slider.release_parameter()
			slider.set_disabled(True)

		self._sliders = None
		self._matrix = None
		self._side_buttons = None
		self._update_callback = None
		ModeSelectorComponent.disconnect(self)

	def set_update_callback(self, callback):
		assert (dir(callback).count("im_func") is 1)
		self._update_callback = callback

	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)

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

	def mode(self):
		result = 0
		if self.is_enabled():
			result = self._mode_index + 1
		return result

	def number_of_modes(self):
		return 4

	def on_enabled_changed(self):
		enabled = self.is_enabled()
		for index in range(self._matrix.width()):
			self._sliders[index].set_disabled(not enabled)

		self._mixer.set_enabled(enabled)
		self.set_mode(-1)

	def release_controls(self):
		for track in range(self._matrix.width()):
			for row in range(self._matrix.height()):
				self._matrix.get_button(track, row).set_on_off_values(127, "DefaultButton.Disabled")

			strip = self._mixer.channel_strip(track)
			strip.set_default_buttons(None, None, None, None)
			strip.set_mute_button(None)
			strip.set_solo_button(None)
			strip.set_arm_button(None)
			strip.set_send_controls((None, None))
			strip.set_pan_control(None)
			strip.set_volume_control(None)

		self._session.set_stop_track_clip_buttons(None)
		self._mixer.set_global_buttons(None, None, None)
		self._session.set_stop_all_clips_button(None)

	def update(self):
		assert (self._modes_buttons != None)
		if self.is_enabled():
			if (self._modes_buttons != None):
				for index in range(len(self._modes_buttons)):
					button = self._modes_buttons[index]
					if index == 0:
						button.set_on_off_values("Mixer.Volume")
					elif index == 1:
						button.set_on_off_values("Mixer.Pan")
					elif index == 2:
						button.set_on_off_values("Mixer.Sends")
					elif index == 3:
						button.set_on_off_values("Mixer.Sends")
					elif index == 4:
						button.set_on_off_values("Mixer.Stop")
					elif index == 5:
						button.set_on_off_values("Mixer.Mute")
					elif index == 6:
						button.set_on_off_values("Mixer.Solo")
					elif index == 7:
						button.set_on_off_values("Mixer.Arm")
					if (index == self._mode_index):
						button.turn_on()
					else:
						button.turn_off()

			for button in self._side_buttons:
				button.set_on_off_values(127, "DefaultButton.Disabled")
				button.turn_off()

			for index in range(self._matrix.width()):
				self._sliders[index].set_disabled((self._mode_index == -1))

			self._mixer.set_allow_update(False)
			self._session.set_allow_update(False)
			if self._mode_index == -1:
				self._setup_mixer_overview()
			elif self._mode_index == 0:
				self._setup_volume_mode()
			elif self._mode_index == 1:
				self._setup_pan_mode()
			elif self._mode_index == 2:
				self._setup_send1_mode()
			elif self._mode_index == 3:
				self._setup_send2_mode()
			else:
				assert False
			if (self._update_callback != None):
				self._update_callback()
			self._mixer.set_allow_update(True)
			self._session.set_allow_update(True)
		#else:
			#self.release_controls()

	def _setup_mixer_overview(self):
		stop_buttons = []
		for track in range(self._matrix.width()):
			strip = self._mixer.channel_strip(track)
			strip.set_send_controls((None, None))
			strip.set_pan_control(None)
			strip.set_volume_control(None)
			self._sliders[track].release_parameter()
			for row in range(self._matrix.height()):
				if row == 0:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Volume")
				elif row == 1:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Pan")
				elif row == 2:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Sends")
				elif row == 3:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Sends")
				elif row == 4:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Stop")
				elif row == 5:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Mute")
				elif row == 6:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Solo")
				elif row == 7:
					self._matrix.get_button(track, row).set_on_off_values("Mixer.Arm")

			strip.set_default_buttons(self._matrix.get_button(track, 0), self._matrix.get_button(track, 1), self._matrix.get_button(track, 2), self._matrix.get_button(track, 3))
			stop_buttons.append(self._matrix.get_button(track, 4))
			strip.set_mute_button(self._matrix.get_button(track, 5))
			strip.set_solo_button(self._matrix.get_button(track, 6))
			strip.set_arm_button(self._matrix.get_button(track, 7))

		for button in self._side_buttons:
			if row == 0:
				button.set_on_off_values("Mixer.Volume")
			elif row == 1:
				button.set_on_off_values("Mixer.Pan")
			elif row == 2:
				button.set_on_off_values("Mixer.Sends")
			elif row == 3:
				button.set_on_off_values("Mixer.Sends")
			elif row == 4:
				button.set_on_off_values("Mixer.Stop")
			elif row == 5:
				button.set_on_off_values("Mixer.Mute")
			elif row == 6:
				button.set_on_off_values("Mixer.Solo")
			elif row == 7:
				button.set_on_off_values("Mixer.Arm")
			button.force_next_send()
			button.turn_on()

		self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
		self._session.set_stop_all_clips_button(self._side_buttons[0])
		self._mixer.set_global_buttons(self._side_buttons[3], self._side_buttons[2], self._side_buttons[1])

	def _setup_volume_mode(self):
		for track in range(self._matrix.width()):
			strip = self._mixer.channel_strip(track)
			strip.set_default_buttons(None, None, None, None)
			strip.set_mute_button(None)
			strip.set_solo_button(None)
			strip.set_arm_button(None)
			strip.set_send_controls((None, None))
			strip.set_pan_control(None)
			for row in range(self._matrix.height()):
				self._matrix.get_button(track, row).set_on_off_values("Mixer.VolumeSlider")

			self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
			self._sliders[track].set_value_map(VOL_VALUE_MAP)
			strip.set_volume_control(self._sliders[track])

		self._session.set_stop_track_clip_buttons(None)
		self._session.set_stop_all_clips_button(None)
		self._mixer.set_global_buttons(None, None, None)

	def _setup_pan_mode(self):
		for track in range(self._matrix.width()):
			strip = self._mixer.channel_strip(track)
			strip.set_default_buttons(None, None, None, None)
			strip.set_mute_button(None)
			strip.set_solo_button(None)
			strip.set_arm_button(None)
			strip.set_send_controls((None, None))
			strip.set_volume_control(None)
			for row in range(self._matrix.height()):
				self._matrix.get_button(track, row).set_on_off_values("Mixer.PanSlider")

			self._sliders[track].set_mode(SLIDER_MODE_PAN)
			self._sliders[track].set_value_map(PAN_VALUE_MAP)
			strip.set_pan_control(self._sliders[track])

		self._session.set_stop_track_clip_buttons(None)
		self._session.set_stop_all_clips_button(None)
		self._mixer.set_global_buttons(None, None, None)

	def _setup_send1_mode(self):
		for track in range(self._matrix.width()):
			strip = self._mixer.channel_strip(track)
			strip.set_default_buttons(None, None, None, None)
			strip.set_mute_button(None)
			strip.set_solo_button(None)
			strip.set_arm_button(None)
			strip.set_volume_control(None)
			strip.set_pan_control(None)
			for row in range(self._matrix.height()):
				self._matrix.get_button(track, row).set_on_off_values("Mixer.SendsSlider")

			self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
			self._sliders[track].set_value_map(SEND_VALUE_MAP)
			strip.set_send_controls((self._sliders[track], None))

		self._session.set_stop_track_clip_buttons(None)
		self._session.set_stop_all_clips_button(None)
		self._mixer.set_global_buttons(None, None, None)

	def _setup_send2_mode(self):
		for track in range(self._matrix.width()):
			strip = self._mixer.channel_strip(track)
			strip.set_default_buttons(None, None, None, None)
			strip.set_mute_button(None)
			strip.set_solo_button(None)
			strip.set_arm_button(None)
			strip.set_volume_control(None)
			strip.set_pan_control(None)
			for row in range(self._matrix.height()):
				self._matrix.get_button(track, row).set_on_off_values("Mixer.SendsSlider")

			self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
			self._sliders[track].set_value_map(SEND_VALUE_MAP)
			strip.set_send_controls((None, self._sliders[track]))

		self._session.set_stop_track_clip_buttons(None)
		self._session.set_stop_all_clips_button(None)
		self._mixer.set_global_buttons(None, None, None)
class SubSelectorComponent(ModeSelectorComponent):
    __module__ = __name__
    __doc__ = ' Class that handles different mixer modes '

    def __init__(self, matrix, side_buttons, session):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(session, SessionComponent)
        ModeSelectorComponent.__init__(self)
        self._session = session
        self._mixer = SpecialMixerComponent(matrix.width())
        self._matrix = matrix
        self._sliders = []
        for column in range(8):
            self._sliders.append(PreciseButtonSliderElement(tuple([ matrix.get_button(column, (7 - row)) for row in range(8) ])))

        self._side_buttons = side_buttons[4:]
        self._update_callback = None
        self._session.set_mixer(self._mixer)
        self.set_modes_buttons(side_buttons[:4])



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

        self._session = None
        self._mixer = None
        for slider in self._sliders:
            slider.release_parameter()
            slider.set_disabled(True)

        self._sliders = None
        self._matrix = None
        self._side_buttons = None
        self._update_callback = None
        ModeSelectorComponent.disconnect(self)



    def set_update_callback(self, callback):
        assert (dir(callback).count('im_func') is 1)
        self._update_callback = callback



    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)




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



    def mode(self):
        result = 0
        if self.is_enabled():
            result = (self._mode_index + 1)
        return result



    def number_of_modes(self):
        return 4



    def on_enabled_changed(self):
        enabled = self.is_enabled()
        for index in range(self._matrix.width()):
            self._sliders[index].set_disabled((not enabled))

        self._mixer.set_enabled(enabled)
        self.set_mode(-1)



    def release_controls(self):
        for track in range(self._matrix.width()):
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, LED_OFF)

            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None,
             None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)

        self._session.set_stop_track_clip_buttons(None)
        self._mixer.set_global_buttons(None, None, None)
        self._session.set_stop_all_clips_button(None)



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

            for button in self._side_buttons:
                button.set_on_off_values(127, 0)
                button.turn_off()

            for index in range(self._matrix.width()):
                self._sliders[index].set_disabled((self._mode_index == -1))

            self._mixer.set_allow_update(False)
            self._session.set_allow_update(False)
            if (self._mode_index == -1):
                self._setup_mixer_overview()
            elif (self._mode_index == 0):
                self._setup_volume_mode()
            elif (self._mode_index == 1):
                self._setup_pan_mode()
            elif (self._mode_index == 2):
                self._setup_send1_mode()
            elif (self._mode_index == 3):
                self._setup_send2_mode()
            else:
                assert False
            if (self._update_callback != None):
                self._update_callback()
            #self._rebuild_callback()
            self._mixer.set_allow_update(True)
            self._session.set_allow_update(True)
        else:
            self.release_controls()



    def _setup_mixer_overview(self):
        trkon_index = 5
        stop_buttons = []
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_send_controls((None,
             None))
            strip.set_pan_control(None)
            strip.set_volume_control(None)
            self._sliders[track].release_parameter()
            for row in range(self._matrix.height()):
                full_value = 1
                third_value = 0
                if (row == trkon_index):
                    full_value = 127
                    third_value = 0
                elif (row > 3):
                    full_value = 127
                    third_value = 0
                self._matrix.get_button(track, row).set_on_off_values(full_value, third_value)

            strip.set_default_buttons(self._matrix.get_button(track, 0), self._matrix.get_button(track, 1), self._matrix.get_button(track, 2), self._matrix.get_button(track, 3))
            stop_buttons.append(self._matrix.get_button(track, 4))
            strip.set_mute_button(self._matrix.get_button(track, 5))
            strip.set_solo_button(self._matrix.get_button(track, 6))
            strip.set_arm_button(self._matrix.get_button(track, 7))

        for button in self._side_buttons:
            if (list(self._side_buttons).index(button) == (trkon_index - 4)):
                button.set_on_off_values(127, 0)
            else:
                button.set_on_off_values(127, 0)
            button.set_force_next_value()
            button.turn_off()

        self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
        self._session.set_stop_all_clips_button(self._side_buttons[0])
        self._mixer.set_global_buttons(self._side_buttons[3], self._side_buttons[2], self._side_buttons[1])



    def _setup_volume_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None,
             None))
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(VOL_VALUE_MAP)
            strip.set_volume_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)



    def _setup_pan_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_send_controls((None,
             None))
            strip.set_volume_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_PAN)
            self._sliders[track].set_value_map(PAN_VALUE_MAP)
            strip.set_pan_control(self._sliders[track])

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)



    def _setup_send1_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((self._sliders[track],
             None))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)



    def _setup_send2_mode(self):
        for track in range(self._matrix.width()):
            strip = self._mixer.channel_strip(track)
            strip.set_default_buttons(None, None, None, None)
            strip.set_mute_button(None)
            strip.set_solo_button(None)
            strip.set_arm_button(None)
            strip.set_volume_control(None)
            strip.set_pan_control(None)
            for row in range(self._matrix.height()):
                self._matrix.get_button(track, row).set_on_off_values(127, 0)

            self._sliders[track].set_mode(SLIDER_MODE_VOLUME)
            self._sliders[track].set_value_map(SEND_VALUE_MAP)
            strip.set_send_controls((None,
             self._sliders[track]))

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)