示例#1
0
class BeatStep(ArturiaControlSurface):

    def __init__(self, *a, **k):
        super(BeatStep, self).__init__(*a, **k)
        self._skin = Skin(Colors)
        with self.component_guard():
            self._create_controls()
            self._create_device()
            self._create_session()
            self._create_mixer()
            self._create_transport()

    def _create_controls(self):
        self._device_encoders = ButtonMatrixElement(rows=[ [ EncoderElement(MIDI_CC_TYPE, 0, identifier, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Encoder_%d_%d' % (column_index, row_index)) for column_index, identifier in enumerate(row) ] for row_index, row in enumerate((
         ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[8:12]))
                                                         ])
        self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 75, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Horizontal_Scroll_Encoder')
        self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 72, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Vertical_Scroll_Encoder')
        self._volume_encoder = EncoderElement(MIDI_CC_TYPE, 0, 91, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Volume_Encoder')
        self._pan_encoder = EncoderElement(MIDI_CC_TYPE, 0, 17, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Pan_Encoder')
        self._send_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 77, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Send_A_Encoder')
        self._send_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 93, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Send_B_Encoder')
        self._send_encoders = ButtonMatrixElement(rows=[
         [
          self._send_a_encoder, self._send_b_encoder]])
        self._return_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 73, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Return_A_Encoder')
        self._return_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 79, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Return_B_Encoder')
        self._return_encoders = ButtonMatrixElement(rows=[
         [
          self._return_a_encoder, self._return_b_encoder]])
        self._pads = ButtonMatrixElement(rows=[ [ ButtonElement(True, MIDI_NOTE_TYPE, PAD_CHANNEL, identifier, name='Pad_%d_%d' % (col_index, row_index), skin=self._skin) for col_index, identifier in enumerate(row) ] for row_index, row in enumerate(PAD_MSG_IDS)
                                              ])
        self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 1, name='Stop_Button')
        self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 2, name='Play_Button')

    def _create_device(self):
        self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=self._device_encoders), device_selection_follows_track_selection=True)
        self._device.set_enabled(True)
        self.set_device_component(self._device)

    def _create_session(self):
        self._session = SessionComponent(name='Session', is_enabled=False, num_tracks=self._pads.width(), num_scenes=self._pads.height(), enable_skinning=True, layer=Layer(clip_launch_buttons=self._pads, scene_select_control=self._vertical_scroll_encoder))
        self._session.set_enabled(True)

    def _create_mixer(self):
        self._mixer = MixerComponent(name='Mixer', is_enabled=False, num_returns=2, layer=Layer(track_select_encoder=self._horizontal_scroll_encoder, selected_track_volume_control=self._volume_encoder, selected_track_pan_control=self._pan_encoder, selected_track_send_controls=self._send_encoders, return_volume_controls=self._return_encoders))
        self._mixer.set_enabled(True)

    def _create_transport(self):
        self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(stop_button=self._stop_button, play_button=self._play_button))
        self._transport.set_enabled(True)

    def _collect_setup_messages(self):
        for identifier, hardware_id in izip(ENCODER_MSG_IDS, HARDWARE_ENCODER_IDS):
            self._setup_hardware_encoder(hardware_id, identifier)

        self._setup_hardware_button(HARDWARE_STOP_BUTTON_ID, 1, msg_type='cc')
        self._setup_hardware_button(HARDWARE_PLAY_BUTTON_ID, 2, msg_type='cc')
        for hardware_id, identifier in izip(HARDWARE_PAD_IDS, chain(*PAD_MSG_IDS)):
            self._setup_hardware_button(hardware_id, identifier, PAD_CHANNEL, msg_type='note')
示例#2
0
 def _create_session(self):
     self._session = SessionComponent(
         num_tracks=self._pads.width(),
         num_scenes=self._pads.height(),
         name='Session',
         is_enabled=False,
         layer=Layer(clip_launch_buttons=self._pads,
                     scene_select_control=self._vertical_scroll_encoder))
     self._session.set_enabled(True)
class BeatStep(ArturiaControlSurface):

    def __init__(self, *a, **k):
        super(BeatStep, self).__init__(*a, **k)
        self._skin = Skin(Colors)
        with self.component_guard():
            self._create_controls()
            self._create_device()
            self._create_session()
            self._create_mixer()
            self._create_transport()

    def _create_controls(self):
        self._device_encoders = ButtonMatrixElement(rows=[ [ EncoderElement(MIDI_CC_TYPE, 0, identifier, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Encoder_%d_%d' % (column_index, row_index)) for column_index, identifier in enumerate(row) ] for row_index, row in enumerate((ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[8:12])) ])
        self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 75, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Horizontal_Scroll_Encoder')
        self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 72, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Vertical_Scroll_Encoder')
        self._volume_encoder = EncoderElement(MIDI_CC_TYPE, 0, 91, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Volume_Encoder')
        self._pan_encoder = EncoderElement(MIDI_CC_TYPE, 0, 17, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Pan_Encoder')
        self._send_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 77, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Send_A_Encoder')
        self._send_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 93, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Send_B_Encoder')
        self._send_encoders = ButtonMatrixElement(rows=[[self._send_a_encoder, self._send_b_encoder]])
        self._return_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 73, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Return_A_Encoder')
        self._return_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 79, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Return_B_Encoder')
        self._return_encoders = ButtonMatrixElement(rows=[[self._return_a_encoder, self._return_b_encoder]])
        self._pads = ButtonMatrixElement(rows=[ [ ButtonElement(True, MIDI_NOTE_TYPE, PAD_CHANNEL, identifier, name='Pad_%d_%d' % (col_index, row_index), skin=self._skin) for col_index, identifier in enumerate(row) ] for row_index, row in enumerate(PAD_MSG_IDS) ])
        self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 1, name='Stop_Button')
        self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 2, name='Play_Button')

    def _create_device(self):
        self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=self._device_encoders))
        self._device.set_enabled(True)
        self.set_device_component(self._device)
        self._device_selection_follows_track_selection = True

    def _create_session(self):
        self._session = SessionComponent(name='Session', is_enabled=False, num_tracks=self._pads.width(), num_scenes=self._pads.height(), enable_skinning=True, layer=Layer(clip_launch_buttons=self._pads, scene_select_control=self._vertical_scroll_encoder))
        self._session.set_enabled(True)

    def _create_mixer(self):
        self._mixer = MixerComponent(name='Mixer', is_enabled=False, num_returns=2, layer=Layer(track_select_encoder=self._horizontal_scroll_encoder, selected_track_volume_control=self._volume_encoder, selected_track_pan_control=self._pan_encoder, selected_track_send_controls=self._send_encoders, return_volume_controls=self._return_encoders))
        self._mixer.set_enabled(True)

    def _create_transport(self):
        self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(stop_button=self._stop_button, play_button=self._play_button))
        self._transport.set_enabled(True)

    def _collect_setup_messages(self):
        for identifier, hardware_id in izip(ENCODER_MSG_IDS, HARDWARE_ENCODER_IDS):
            self._setup_hardware_encoder(hardware_id, identifier)

        self._setup_hardware_button(HARDWARE_STOP_BUTTON_ID, 1, msg_type='cc')
        self._setup_hardware_button(HARDWARE_PLAY_BUTTON_ID, 2, msg_type='cc')
        for hardware_id, identifier in izip(HARDWARE_PAD_IDS, chain(*PAD_MSG_IDS)):
            self._setup_hardware_button(hardware_id, identifier, PAD_CHANNEL, msg_type='note')
class MiniLab(ArturiaControlSurface):

    def __init__(self, *a, **k):
        super(MiniLab, self).__init__(*a, **k)
        with self.component_guard():
            self._create_controls()
            self._create_device()
            self._create_session()
            self._create_mixer()

    def _create_controls(self):
        self._device_controls = ButtonMatrixElement(rows=[ [ EncoderElement(MIDI_CC_TYPE, 0, identifier, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Encoder_%d_%d' % (column_index, row_index)) for column_index, identifier in enumerate(row) ] for row_index, row in enumerate((ENCODER_MSG_IDS[:4], ENCODER_MSG_IDS[8:12])) ])
        self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 75, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Horizontal_Scroll_Encoder')
        self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE, 0, 72, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Vertical_Scroll_Encoder')
        self._volume_encoder = EncoderElement(MIDI_CC_TYPE, 0, 91, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Volume_Encoder')
        self._pan_encoder = EncoderElement(MIDI_CC_TYPE, 0, 17, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Pan_Encoder')
        self._send_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 77, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Send_A_Encoder')
        self._send_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 93, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Send_B_Encoder')
        self._send_encoders = ButtonMatrixElement(rows=[[self._send_a_encoder, self._send_b_encoder]])
        self._return_a_encoder = EncoderElement(MIDI_CC_TYPE, 0, 73, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Return_A_Encoder')
        self._return_b_encoder = EncoderElement(MIDI_CC_TYPE, 0, 79, Live.MidiMap.MapMode.relative_smooth_two_compliment, name='Return_B_Encoder')
        self._return_encoders = ButtonMatrixElement(rows=[[self._return_a_encoder, self._return_b_encoder]])
        self._pads = ButtonMatrixElement(rows=[ [ ButtonElement(True, MIDI_NOTE_TYPE, PAD_CHANNEL, col + 36 + 8 * row, name='Pad_%d_%d' % (col, row)) for col in xrange(8) ] for row in xrange(2) ])

    def _create_device(self):
        self._device = DeviceComponent(name='Device', is_enabled=False, layer=Layer(parameter_controls=self._device_controls))
        self._device.set_enabled(True)
        self.set_device_component(self._device)
        self._device_selection_follows_track_selection = True

    def _create_session(self):
        self._session = SessionComponent(num_tracks=self._pads.width(), num_scenes=self._pads.height(), name='Session', is_enabled=False, layer=Layer(clip_launch_buttons=self._pads, scene_select_control=self._vertical_scroll_encoder))
        self._session.set_enabled(True)

    def _create_mixer(self):
        self._mixer = MixerComponent(name='Mixer', is_enabled=False, num_returns=2, layer=Layer(track_select_encoder=self._horizontal_scroll_encoder, selected_track_volume_control=self._volume_encoder, selected_track_pan_control=self._pan_encoder, selected_track_send_controls=self._send_encoders, return_volume_controls=self._return_encoders))
        self._mixer.set_enabled(True)

    def _collect_setup_messages(self):
        for cc_id, encoder_id in izip(ENCODER_MSG_IDS, HARDWARE_ENCODER_IDS):
            self._setup_hardware_encoder(encoder_id, cc_id)

        for index, pad_id in enumerate(HARDWARE_BUTTON_IDS):
            identifier = index + PAD_IDENTIFIER_OFFSET
            channel = PAD_CHANNEL
            self._setup_hardware_button(pad_id, identifier, channel)
示例#5
0
    def _setup_session_control(self):
        self._session = SessionComponent(num_tracks=2,
                                         num_scenes=1,
                                         name=u'Session',
                                         is_enabled=False)

        # set horizontal scene selector (this is why we import SessionComponent from _Arturia!)
        self._session.set_scene_select_control(self._center_browse_encoder)

        # set launch-buttons for scene
        self._session.selected_scene().clip_slot(0).set_launch_button(
            self._left_play_button)
        self._session.selected_scene().clip_slot(1).set_launch_button(
            self._right_play_button)

        # hightlite the current selection
        self.set_highlighting_session_component(self._session)
        self._session.set_enabled(True)

        # ----------- add functionality to turn playing-light on-off
        def update_lights(track, button):
            playing_clip_idx = track.playing_slot_index
            if playing_clip_idx >= 0:
                button.turn_on()
            else:
                button.turn_off()

        def update_playlight_left():
            track = self.song().tracks[LEFT_STRIP_ID]
            update_lights(track, self._left_play_button)

        def update_playlight_right():
            track = self.song().tracks[RIGHT_STRIP_ID]
            update_lights(track, self._right_play_button)

        self.song().tracks[LEFT_STRIP_ID].add_playing_slot_index_listener(
            update_playlight_left)
        self.song().tracks[RIGHT_STRIP_ID].add_playing_slot_index_listener(
            update_playlight_right)
        # override the selected scene change behaviour of the playing light
        self.song().view.add_selected_scene_listener(update_playlight_left)
        self.song().view.add_selected_scene_listener(update_playlight_right)
 def _create_session(self):
     self._session = SessionComponent(name='Session', is_enabled=False, num_tracks=self._pads.width(), num_scenes=self._pads.height(), enable_skinning=True, layer=Layer(clip_launch_buttons=self._pads, scene_select_control=self._vertical_scroll_encoder))
     self._session.set_enabled(True)
示例#7
0
class KorgKaossDJ(ControlSurface):
    __module__ = __name__
    __doc__ = " Korg Kaoss DJ controller script "

    def __init__(self, c_instance):
        """everything except the '_on_selected_track_changed' override and 'disconnect' runs from here"""
        ControlSurface.__init__(self, c_instance)

        self._selected_track = None
        self._current_clip = None

        with self.component_guard():
            self._create_controls()
            self._setup_transport_control(
            )  # Run the transport setup part of the script
            self._setup_loop_control()
            self._setup_scrub_control()
            self._setup_fx_control()
            self._setup_mixer_control()  # Setup the mixer object
            self._setup_session_control()  # Setup the session object

    def _create_controls(self):

        # ------ SLIDER
        self._crossfader_slider = SliderElement(MIDI_CC_TYPE, CHANNEL_CENTER,
                                                23)

        self._left_volume_slider = SliderElement(MIDI_CC_TYPE, CHANNEL_LEFT,
                                                 24)
        self._right_volume_slider = SliderElement(MIDI_CC_TYPE, CHANNEL_RIGHT,
                                                  24)

        self._left_tempo_fader = SliderElement(MIDI_CC_TYPE, CHANNEL_LEFT, 25)
        self._right_tempo_fader = SliderElement(MIDI_CC_TYPE, CHANNEL_RIGHT,
                                                25)

        # ------ BUTTONS
        self._left_play_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                               CHANNEL_LEFT, 27)
        self._right_play_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                                CHANNEL_RIGHT, 27)

        self._left_prelisten_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                                    CHANNEL_LEFT, 25)
        self._right_prelisten_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                                     CHANNEL_RIGHT, 25)

        self._left_fx_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                             CHANNEL_LEFT, 24)
        self._right_fx_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                              CHANNEL_RIGHT, 24)

        self._left_A_button = ButtonElement(True, MIDI_NOTE_TYPE, CHANNEL_LEFT,
                                            14)
        self._right_B_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                             CHANNEL_RIGHT, 14)

        self._left_shift_button = ButtonElement(
            True,
            MIDI_NOTE_TYPE,
            CHANNEL_LEFT,
            26,
            name='Shift_Button',
            resource_type=PrioritizedResource)
        self._right_shift_button = ButtonElement(
            True,
            MIDI_NOTE_TYPE,
            CHANNEL_RIGHT,
            26,
            name='Shift_Button',
            resource_type=PrioritizedResource)

        self._left_sync_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                               CHANNEL_LEFT, 29)
        self._right_sync_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                                CHANNEL_RIGHT, 29)

        self._left_cue_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                              CHANNEL_LEFT, 30)
        self._right_cue_button = ButtonElement(True, MIDI_NOTE_TYPE,
                                               CHANNEL_RIGHT, 30)

        self._left_sync_button_shift = ButtonElement(True, MIDI_NOTE_TYPE,
                                                     CHANNEL_LEFT, 47)
        self._right_sync_button_shift = ButtonElement(True, MIDI_NOTE_TYPE,
                                                      CHANNEL_RIGHT, 47)

        self._left_cue_button_shift = ButtonElement(True, MIDI_NOTE_TYPE,
                                                    CHANNEL_LEFT, 48)
        self._right_cue_button_shift = ButtonElement(True, MIDI_NOTE_TYPE,
                                                     CHANNEL_RIGHT, 48)

        for i in range(3):
            for side, channel in zip(['_left', '_right'],
                                     [CHANNEL_LEFT, CHANNEL_RIGHT]):
                setattr(self, side + '_loop_' + str(i + 1),
                        ButtonElement(True, MIDI_NOTE_TYPE, channel, 15 + i))
                setattr(self, side + '_loop_' + str(i + 1) + '_shift',
                        ButtonElement(True, MIDI_NOTE_TYPE, channel, 40 + i))
                setattr(self, side + '_hotcue_' + str(i + 1),
                        ButtonElement(True, MIDI_NOTE_TYPE, channel, 18 + i))
                setattr(self, side + '_hotcue_' + str(i + 1) + '_shift',
                        ButtonElement(True, MIDI_NOTE_TYPE, channel, 43 + i))
                setattr(self, side + '_nolight_' + str(i + 1),
                        ButtonElement(True, MIDI_NOTE_TYPE, channel, 21 + i))

        # ------ ENCODER

        # browser
        self._center_browse_encoder = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_CENTER, 30,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)
        # gain left
        self._left_gain_encoder = EncoderElement(MIDI_CC_TYPE, CHANNEL_LEFT,
                                                 26,
                                                 Live.MidiMap.MapMode.absolute)
        # gain right
        self._right_gain_encoder = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_RIGHT, 26, Live.MidiMap.MapMode.absolute)

        # middle light off -> does not send on-off messages!
        self._left_jogwheel_encoder = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_LEFT, 14,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)
        self._right_jogwheel_encoder = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_RIGHT, 14,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)

        self._left_jogwheel_encoder_shift = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_LEFT, 15,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)
        self._right_jogwheel_encoder_shift = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_RIGHT, 15,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)

        # middle light on  -> sends on-off message on channel 31!
        self._left_jogwheel_encoder_active = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_LEFT, 16,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)
        self._left_jogwheel_encoder_active_button = ButtonElement(
            True, MIDI_NOTE_TYPE, CHANNEL_LEFT, 31)

        self._right_jogwheel_encoder_active = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_RIGHT, 16,
            Live.MidiMap.MapMode.relative_smooth_two_compliment)
        self._right_jogwheel_encoder_active_button = ButtonElement(
            True, MIDI_NOTE_TYPE, CHANNEL_RIGHT, 31)

        # FX touchpad (same for both channels so we need to read only one)
        self._touchpad_x_encoder = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_LEFT, 12, Live.MidiMap.MapMode.absolute)
        self._touchpad_y_encoder = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_LEFT, 13, Live.MidiMap.MapMode.absolute)
        self._touchpad_x_encoder_shift = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_CENTER, 17, Live.MidiMap.MapMode.absolute)
        self._touchpad_y_encoder_shift = EncoderElement(
            MIDI_CC_TYPE, CHANNEL_CENTER, 18, Live.MidiMap.MapMode.absolute)

        # hi-mid-lo encoders
        _device_MSG_IDS = [27, 28, 29]
        self._device_encoders = ButtonMatrixElement(
            rows=[[
                EncoderElement(MIDI_CC_TYPE, CHANNEL_LEFT, MSG_ID,
                               Live.MidiMap.MapMode.absolute)
                for MSG_ID in _device_MSG_IDS
            ],
                  [
                      EncoderElement(MIDI_CC_TYPE, CHANNEL_RIGHT, MSG_ID,
                                     Live.MidiMap.MapMode.absolute)
                      for MSG_ID in _device_MSG_IDS
                  ]])

    def _setup_loop_control(self):
        # set looping function ality to Loop- and HotCue buttons
        self._looper_left = LooperComponent(self,
                                            assign_track=0,
                                            move_increment=4,
                                            increase_factor=(0, 2),
                                            decrease_factor=(0, 2),
                                            start_loop_length=32,
                                            quantize_start=4)
        self._looper_right = LooperComponent(self,
                                             assign_track=1,
                                             move_increment=4,
                                             increase_factor=(0, 2),
                                             decrease_factor=(0, 2),
                                             start_loop_length=32,
                                             quantize_start=1)

        self._looper_left_fine = LooperComponent(self,
                                                 assign_track=0,
                                                 move_increment=1,
                                                 increase_factor=(1, 1),
                                                 decrease_factor=(1, 1),
                                                 start_loop_length=16,
                                                 quantize_start=1)
        self._looper_right_fine = LooperComponent(self,
                                                  assign_track=1,
                                                  move_increment=1,
                                                  increase_factor=(1, 1),
                                                  decrease_factor=(1, 1),
                                                  start_loop_length=16,
                                                  quantize_start=1)

        self._looper_left.set_loop_decrease_button(self._left_loop_1)
        self._looper_left.set_loop_start_button(self._left_loop_2)
        self._looper_left.set_loop_increase_button(self._left_loop_3)
        self._looper_left.set_loop_move_left_button(self._left_loop_1_shift)
        self._looper_left.set_loop_toggle_button(self._left_loop_2_shift)
        self._looper_left.set_loop_move_right_button(self._left_loop_3_shift)

        self._looper_left_fine.set_loop_decrease_button(self._left_hotcue_1)
        self._looper_left_fine.set_loop_start_button(self._left_hotcue_2)
        self._looper_left_fine.set_loop_increase_button(self._left_hotcue_3)
        self._looper_left_fine.set_loop_move_left_button(
            self._left_hotcue_1_shift)
        self._looper_left_fine.set_loop_toggle_button(
            self._left_hotcue_2_shift)
        self._looper_left_fine.set_loop_move_right_button(
            self._left_hotcue_3_shift)

        self._looper_right.set_loop_decrease_button(self._right_loop_1)
        self._looper_right.set_loop_start_button(self._right_loop_2)
        self._looper_right.set_loop_increase_button(self._right_loop_3)
        self._looper_right.set_loop_move_left_button(self._right_loop_1_shift)
        self._looper_right.set_loop_toggle_button(self._right_loop_2_shift)
        self._looper_right.set_loop_move_right_button(self._right_loop_3_shift)

        self._looper_right_fine.set_loop_decrease_button(self._right_hotcue_1)
        self._looper_right_fine.set_loop_start_button(self._right_hotcue_2)
        self._looper_right_fine.set_loop_increase_button(self._right_hotcue_3)
        self._looper_right_fine.set_loop_move_left_button(
            self._right_hotcue_1_shift)
        self._looper_right_fine.set_loop_toggle_button(
            self._right_hotcue_2_shift)
        self._looper_right_fine.set_loop_move_right_button(
            self._right_hotcue_3_shift)

    def _setup_scrub_control(self):
        self._scrub_left = ScrubComponent(self,
                                          assign_track=LEFT_STRIP_ID,
                                          increment_scrub=1,
                                          increment_fine=0.1)
        self._scrub_right = ScrubComponent(self,
                                           assign_track=RIGHT_STRIP_ID,
                                           increment_scrub=1,
                                           increment_fine=0.1)

        self._scrub_left.set_move_position_button(self._left_jogwheel_encoder)
        self._scrub_left.set_move_position_coarse_button(
            self._left_jogwheel_encoder_shift)
        self._scrub_left.set_scrub_position_button(
            self._left_jogwheel_encoder_active)
        self._scrub_left.set_scrub_on_off_button(
            self._left_jogwheel_encoder_active_button)

        self._scrub_right.set_move_position_button(
            self._right_jogwheel_encoder)
        self._scrub_right.set_move_position_coarse_button(
            self._right_jogwheel_encoder_shift)
        self._scrub_right.set_scrub_position_button(
            self._right_jogwheel_encoder_active)
        self._scrub_right.set_scrub_on_off_button(
            self._right_jogwheel_encoder_active_button)

    def _setup_fx_control(self):
        self._fx_left = FXComponent(self, assign_track=LEFT_STRIP_ID)
        self._fx_left.set_touchpad_x_button(self._touchpad_x_encoder)
        self._fx_left.set_touchpad_y_button(self._touchpad_y_encoder)
        self._fx_left.set_touchpad_x_shift_button(
            self._touchpad_x_encoder_shift)
        self._fx_left.set_touchpad_y_shift_button(
            self._touchpad_y_encoder_shift)
        self._fx_left.set_fx_on_off_button(self._left_fx_button)
        self._fx_left.set_gain_encoder_button(self._left_gain_encoder)

        self._fx_left.set_warping_button(self._left_sync_button_shift)
        self._fx_left.set_warp_mode_button(self._left_sync_button)

        self._fx_left.set_pitch_down_button(self._left_nolight_1)
        self._fx_left.set_pitch_up_button(self._left_nolight_3)

        self._fx_right = FXComponent(self, assign_track=RIGHT_STRIP_ID)
        self._fx_right.set_touchpad_x_button(self._touchpad_x_encoder)
        self._fx_right.set_touchpad_y_button(self._touchpad_y_encoder)
        self._fx_right.set_touchpad_x_shift_button(
            self._touchpad_x_encoder_shift)
        self._fx_right.set_touchpad_y_shift_button(
            self._touchpad_y_encoder_shift)
        self._fx_right.set_fx_on_off_button(self._right_fx_button)
        self._fx_right.set_gain_encoder_button(self._right_gain_encoder)

        self._fx_right.set_warping_button(self._right_sync_button_shift)
        self._fx_right.set_warp_mode_button(self._right_sync_button)

    def _setup_transport_control(self):
        """set up the sliders"""

        self._transport = TransportComponent(self,
                                             name=u'Transport',
                                             is_enabled=False)

        #set tempo-fader
        self._transport.set_tempo_control(
            self._left_tempo_fader,
            fine_control=self._right_tempo_fader)  #(control, fine_control)

        self._transport.set_enabled(True)

    def _setup_mixer_control(self):
        self._mixer = MixerComponent(num_tracks=2,
                                     num_returns=0,
                                     name=u'Mixer',
                                     is_enabled=False)

        self._mixer.set_crossfader_control(self._crossfader_slider)

        # set volume sliders
        self._mixer.channel_strip(LEFT_STRIP_ID).set_volume_control(
            self._left_volume_slider)
        self._mixer.channel_strip(RIGHT_STRIP_ID).set_volume_control(
            self._right_volume_slider)

        # set prelisten buttons
        self._mixer.channel_strip(LEFT_STRIP_ID).set_solo_button(
            self._left_prelisten_button)
        self._mixer.channel_strip(RIGHT_STRIP_ID).set_solo_button(
            self._right_prelisten_button)

        # use fx buttons to select a track
        self._mixer.channel_strip(LEFT_STRIP_ID).set_select_button(
            self._left_A_button)
        self._mixer.channel_strip(RIGHT_STRIP_ID).set_select_button(
            self._right_B_button)

        self._mixer.set_enabled(True)

    def _setup_session_control(self):
        self._session = SessionComponent(num_tracks=2,
                                         num_scenes=1,
                                         name=u'Session',
                                         is_enabled=False)

        # set horizontal scene selector (this is why we import SessionComponent from _Arturia!)
        self._session.set_scene_select_control(self._center_browse_encoder)

        # set launch-buttons for scene
        self._session.selected_scene().clip_slot(0).set_launch_button(
            self._left_play_button)
        self._session.selected_scene().clip_slot(1).set_launch_button(
            self._right_play_button)

        # hightlite the current selection
        self.set_highlighting_session_component(self._session)
        self._session.set_enabled(True)

        # ----------- add functionality to turn playing-light on-off
        def update_lights(track, button):
            playing_clip_idx = track.playing_slot_index
            if playing_clip_idx >= 0:
                button.turn_on()
            else:
                button.turn_off()

        def update_playlight_left():
            track = self.song().tracks[LEFT_STRIP_ID]
            update_lights(track, self._left_play_button)

        def update_playlight_right():
            track = self.song().tracks[RIGHT_STRIP_ID]
            update_lights(track, self._right_play_button)

        self.song().tracks[LEFT_STRIP_ID].add_playing_slot_index_listener(
            update_playlight_left)
        self.song().tracks[RIGHT_STRIP_ID].add_playing_slot_index_listener(
            update_playlight_right)
        # override the selected scene change behaviour of the playing light
        self.song().view.add_selected_scene_listener(update_playlight_left)
        self.song().view.add_selected_scene_listener(update_playlight_right)