Esempio n. 1
0
 def _ffwd_value(self, value):
     if self._shift_pressed:
         self.song().current_song_time = self.song().last_event_time
     else:
         TransportComponent._ffwd_value(self, value)
Esempio n. 2
0
 def _rwd_value(self, value):
     if self._shift_pressed:
         self.song().current_song_time = 0.0
     else:
         TransportComponent._rwd_value(self, value)
Esempio n. 3
0
 def __init__(self):
     self._shift_button = None
     self._shift_pressed = False
     TransportComponent.__init__(self)
Esempio n. 4
0
 def disconnect(self):
     if self._shift_button != None:
         self._shift_button.remove_value_listener(self._shift_value)
         self._shift_button = None
     TransportComponent.disconnect(self)
Esempio n. 5
0
class Launchkey_MK2(OptimizedControlSurface):
    identity_request_delay = 0.5

    def __init__(self, c_instance, *a, **k):
        (super(Launchkey_MK2, self).__init__)(a, c_instance=c_instance, **k)
        self._is_25_key_model = False
        self._is_in_control_on = True
        self._identity_response_pending = False
        with self.component_guard():
            self._skin = make_skin()
            with inject(skin=(const(self._skin))).everywhere():
                self._create_controls()
        self._request_task = self._tasks.add(
            Task.sequence(Task.wait(self.identity_request_delay),
                          Task.run(self._send_identity_request)))
        self._request_task.kill()

    def _create_controls(self):
        self._encoders = ButtonMatrixElement(rows=[[
            make_encoder(identifier, name=('Encoder_%d' % (index, )))
            for index, identifier in enumerate(range(21, 29))
        ]])
        self._top_pad_row = ButtonMatrixElement(rows=[[
            make_button(identifier, name=('Pad_0_%d' % (index, )))
            for index, identifier in enumerate(range(96, 104))
        ]])
        self._bottom_pad_row_raw = [
            make_button(identifier, name=('Pad_1_%d' % (index, )))
            for index, identifier in enumerate(range(112, 120))
        ]
        self._bottom_pad_row = ButtonMatrixElement(
            rows=[self._bottom_pad_row_raw])
        self._top_launch_button = make_button(104, name='Scene_Launch_Button')
        self._bottom_launch_button = make_button(120,
                                                 name='Stop_All_Clips_Button')
        self._scene_up_button = make_button(112,
                                            MIDI_CC_TYPE,
                                            name='Scene_Up_Button')
        self._scene_down_button = make_button(113,
                                              MIDI_CC_TYPE,
                                              name='Scene_Down_Button')
        self._stop_button = make_button(114, MIDI_CC_TYPE, name='Stop_Button')
        self._play_button = make_button(115, MIDI_CC_TYPE, name='Play_Button')
        self._loop_button = make_button(116, MIDI_CC_TYPE, name='Loop_Button')
        self._record_button = make_button(117,
                                          MIDI_CC_TYPE,
                                          name='Record_Button')
        self._sliders = ButtonMatrixElement(rows=[[
            make_slider(identifier, name=('Slider_%d' % (index, )))
            for index, identifier in enumerate(range(41, 49))
        ]])
        self._master_slider = make_slider(7, name='Master_Slider')
        self._25_key_slider = make_slider(7, name='Slider', channel=0)
        self._mute_buttons_raw = [
            make_button(identifier,
                        MIDI_CC_TYPE,
                        name=('Mute_Button_%d' % (index, )))
            for index, identifier in enumerate(range(51, 59))
        ]
        self._mute_buttons = ButtonMatrixElement(rows=[self._mute_buttons_raw])
        self._master_button = make_button(59,
                                          MIDI_CC_TYPE,
                                          name='Master_Button')
        self._track_left_button = make_button(102,
                                              MIDI_CC_TYPE,
                                              name='Track_Left_Button')
        self._track_right_button = make_button(103,
                                               MIDI_CC_TYPE,
                                               name='Track_Right_Button')
        self._device_mode_button = self._bottom_pad_row_raw[0]
        self._pan_mode_button = self._bottom_pad_row_raw[1]
        self._send_mode_buttons = dict()
        for index in range(consts.MAX_SENDS):
            setattr(self, '_send_%d_button' % (index, ),
                    self._bottom_pad_row_raw[(index + 2)])
            self._send_mode_buttons['send_%d_mode_button' %
                                    (index, )] = getattr(
                                        self, '_send_%d_button' % (index, ))

        self._extended_mode_button = make_button(
            12, name='Dummy_Extended_Mode_Button')
        self._extended_mode_button.add_value_listener(nop)
        self._encoder_incontrol_button = make_button(
            13, is_momentary=False, name='Encoder_InControl_Button')
        self._encoder_incontrol_button.add_value_listener(nop)
        self._slider_incontrol_button = make_button(
            14, is_momentary=False, name='Fader_InControl_Button')
        self._slider_incontrol_button.add_value_listener(nop)
        self._pad_incontrol_button = make_button(15,
                                                 is_momentary=False,
                                                 name='Pad_InControl_Button')
        self._pad_incontrol_button.add_value_listener(self._update_pads)
        self._encoder_incontrol_button2 = make_button(
            16, name='Encoder_InControl_Button')
        self._pad_in_control_status_button = make_button(
            11, name='Dummy_InControl_Button')

    def _create_session(self):
        self._session = SessionComponent(
            name='Session',
            is_enabled=False,
            num_tracks=(self._top_pad_row.width()),
            num_scenes=(self._top_pad_row.height()),
            enable_skinning=True,
            layer=Layer(clip_launch_buttons=(self._top_pad_row),
                        scene_launch_buttons=ButtonMatrixElement(
                            rows=[[self._top_launch_button]]),
                        stop_track_clip_buttons=(self._bottom_pad_row),
                        stop_all_clips_button=(self._bottom_launch_button)))
        self._session.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES, RGB_COLOR_TABLE)
        self._session.set_mixer(self._mixer)
        self._session.set_enabled(True)

    def _setup_navigation(self):
        self._session_navigation = SessionNavigationComponent(
            is_enabled=False,
            name='Session_Navigation',
            layer=Layer(next_track_button=(self._track_right_button),
                        prev_track_button=(self._track_left_button),
                        next_scene_button=(self._scene_down_button),
                        prev_scene_button=(self._scene_up_button)))
        self._session_navigation.set_enabled(True)

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

    def _create_mixer(self):
        mixer_volume_layer = None
        if self._is_25_key_model:
            mixer_volume_layer = Layer(volume_control=(self._25_key_slider))
        else:
            mixer_volume_layer = Layer(volume_controls=(self._sliders))
        self._mixer = MixerComponent(is_enabled=False,
                                     name='Mixer',
                                     num_tracks=(self._sliders.width()),
                                     layer=mixer_volume_layer)
        if not self._is_25_key_model:
            self._mixer.master_strip().layer = Layer(
                volume_control=(self._master_slider))
        self._mixer.set_enabled(True)
        self._mute_button_modes = ModesComponent()
        mute_mode = AddLayerMode(self._mixer,
                                 Layer(mute_buttons=(self._mute_buttons)))
        solo_mode = AddLayerMode(self._mixer,
                                 Layer(solo_buttons=(self._mute_buttons)))
        self._mute_button_modes.add_mode('mute_mode', mute_mode)
        self._mute_button_modes.add_mode('solo_mode',
                                         solo_mode,
                                         behaviour=(CancellableBehaviour()))
        self._mute_button_modes.layer = Layer(
            solo_mode_button=(self._master_button))
        self._mute_button_modes.selected_mode = 'mute_mode'
        self._mute_button_modes.set_enabled(True)

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

    def _create_background(self):
        self._background = BackgroundComponent(name='BackgroundComponent')

    def _create_encoder_modes(self):
        self._encoder_modes = DisablingModesComponent()
        self._encoder_modes.default_behaviour = mixin(SkinableBehaviourMixin,
                                                      ImmediateBehaviour)()
        device_mode = LayerMode(
            self._device,
            Layer(parameter_controls=(self._encoders),
                  bank_buttons=(self._top_pad_row)))
        pan_mode = AddLayerMode(self._mixer,
                                Layer(pan_controls=(self._encoders)))
        sends_mode = AddLayerMode(self._mixer,
                                  Layer(send_controls=(self._encoders)))
        background_mode = LayerMode(self._background,
                                    Layer(bank_buttons=(self._top_pad_row)))
        self._encoder_modes.add_mode('device_mode',
                                     device_mode,
                                     is_enabled=True)
        self._encoder_modes.add_mode('pan_mode', [pan_mode, background_mode],
                                     is_enabled=True)
        for index in range(6):
            self._encoder_modes.add_mode(('send_%d_mode' % (index, )), [
                sends_mode,
                partial(self._set_send_index, index), background_mode
            ],
                                         is_enabled=False)

        self._encoder_modes.selected_mode = 'device_mode'
        self._encoder_modes.set_enabled(True)

    def _create_mode_selector(self):
        self._mode_selector = ModesComponent()
        mode_selection = LayerMode(
            self._encoder_modes,
            Layer(device_mode_button=self._device_mode_button,
                  pan_mode_button=self._pan_mode_button,
                  **self._send_mode_buttons))
        device_navigation = AddLayerMode(
            self._device,
            Layer(device_nav_left_button=(self._track_left_button),
                  device_nav_right_button=(self._track_right_button)))
        self._mode_selector.add_mode('mode_selection', [
            partial(self._toggle_in_control, True), mode_selection,
            device_navigation
        ],
                                     behaviour=(MomentaryBehaviour()))
        session_control = AddLayerMode(
            self._session, Layer(clip_launch_buttons=(self._top_pad_row)))
        self._mode_selector.add_mode(
            'session_mode',
            [partial(self._toggle_in_control, False), session_control])
        self._mode_selector.layer = Layer(
            mode_selection_button=(self._encoder_incontrol_button2))

    def _create_in_control_status_listener(self):
        self._in_control_status = InControlStatusComponent(
            set_is_in_control_on=(self._set_is_in_control_on),
            is_enabled=False,
            layer=Layer(
                in_control_status_button=(self._pad_in_control_status_button)))
        self._in_control_status.set_enabled(True)

    @subject_slot('value')
    def _update_pads(self, value):
        if value:
            self.update()

    @subject_slot('return_tracks')
    def _on_return_tracks_changed(self):
        num_sends = self._mixer.num_sends
        for index in range(6):
            self._encoder_modes.set_mode_enabled(
                'send_%d_mode' % (index, ),
                True if index < num_sends else False)

    def _set_send_index(self, index):
        self._mixer.send_index = index

    def _set_is_in_control_on(self, value):
        self._is_in_control_on = value

    def _toggle_in_control(self, value):
        if not self._is_in_control_on:
            self._send_midi(consts.DRUM_IN_CONTROL_ON_MESSAGE
                            if value else consts.DRUM_IN_CONTROL_OFF_MESSAGE)

    def port_settings_changed(self):
        self._disconnect_and_unregister_all_components()
        self._request_task.restart()

    def handle_sysex(self, midi_bytes):
        if self._is_identity_response(midi_bytes):
            product_id_bytes = self._extract_product_id_bytes(midi_bytes)
            if self._is_identity_response_valid(product_id_bytes):
                self._set_model_type(product_id_bytes)
                self._request_task.kill()
                if self._identity_response_pending:
                    self.on_identified()
                    self._identity_response_pending = False
            else:
                self.log_message(
                    'MIDI device responded with wrong product id (%s).' %
                    (str(product_id_bytes), ))
        else:
            super(Launchkey_MK2, self).handle_sysex(midi_bytes)

    def _extract_product_id_bytes(self, midi_bytes):
        return midi_bytes[5:]

    def _is_identity_response(self, midi_bytes):
        return midi_bytes[3:5] == (6, 2)

    def _is_identity_response_valid(self, product_id_bytes):
        return product_id_bytes[:
                                3] == consts.PRODUCT_ID_BYTE_PREFIX and product_id_bytes[
                                    3] in consts.PRODUCT_ID_BYTES

    def _set_model_type(self, product_id_bytes):
        self._is_25_key_model = product_id_bytes[
            3] == consts.LAUNCHKEY_25_ID_BYTE

    def _send_identity_request(self):
        self._identity_response_pending = True
        self._send_midi(consts.IDENTITY_REQUEST)

    def on_identified(self):
        self._extended_mode_button.turn_on()
        with self.component_guard():
            self._create_mixer()
            self._create_session()
            self._setup_navigation()
            self._create_transport()
            self._create_device()
            self._create_background()
            self._create_encoder_modes()
            self._create_mode_selector()
            self._create_in_control_status_listener()
            self._on_return_tracks_changed.subject = self.song()
            self._on_return_tracks_changed()
        self._mode_selector.selected_mode = 'session_mode'
        self.update()

    def disconnect(self):
        self._extended_mode_button.turn_off()
        super(Launchkey_MK2, self).disconnect()
Esempio n. 6
0
class FocusControl(ControlSurface):
    controlled_track = None

    def __init__(self, c_instance):
        super().__init__(c_instance)
        self.song().add_is_playing_listener(
            self._FocusControl__update_play_button_led)
        register_sender(self)
        self._active = False
        self._tracks = []
        self.rewind_button_down = False
        self.forward_button_down = False
        with self.component_guard():
            self._set_suppress_rebuild_requests(True)
            self._suppress_send_midi = True
            device = SimpleDeviceComponent()
            self.set_device_component(device)
            self._on_selected_track_changed()
            self.set_up_controls()
            self.request_rebuild_midi_map()
            self._set_suppress_rebuild_requests(False)
            self._active = True
            self._suppress_send_midi = False
            self.transport = TransportComponent()
            self.transport.set_play_button(
                ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_PLAY))
            self.transport.set_record_button(
                ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_RECORD))
            self.transport.set_seek_buttons(
                ButtonElement(True, MIDI_NOTE_TYPE, 0,
                              SID_TRANSPORT_FAST_FORWARD),
                ButtonElement(True, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_REWIND))
            self.transport.set_loop_button(
                ButtonElement(False, MIDI_NOTE_TYPE, 0, SID_TRANSPORT_LOOP))
        self._assign_tracks()
        ctrack = self.get_controlled_track()
        if ctrack:
            track = ctrack[0]
            instr = ctrack[1]
            self.controlled_track = track
            index = list(self.song().tracks).index(track)
            self.update_status_midi(index, track, instr, 1)
        self.refresh_state()

    def refresh_state(self):
        self._FocusControl__update_play_button_led()

    def receive_midi(self, midi_bytes):
        if midi_bytes[0] & 240 == MIDI_NOTE_ON_STATUS or midi_bytes[
                0] & 240 == MIDI_NOTE_OFF_STATUS:
            note = midi_bytes[1]
            value = BUTTON_PRESSED if midi_bytes[2] > 0 else BUTTON_RELEASED
            if note in transport_control_switch_ids:
                self.handle_transport_switch_ids(note, value)
        super().receive_midi(midi_bytes)

    def handle_transport_switch_ids(self, switch_id, value):
        if switch_id == SID_TRANSPORT_REWIND:
            if value == BUTTON_PRESSED:
                self.rewind_button_down = True
            else:
                if value == BUTTON_RELEASED:
                    self.rewind_button_down = False
            self._FocusControl__update_forward_rewind_leds()
        else:
            if switch_id == SID_TRANSPORT_FAST_FORWARD:
                if value == BUTTON_PRESSED:
                    self.forward_button_down = True
                else:
                    if value == BUTTON_RELEASED:
                        self.forward_button_down = False
                self._FocusControl__update_forward_rewind_leds()
            else:
                if switch_id == SID_TRANSPORT_STOP:
                    if value == BUTTON_PRESSED:
                        self._FocusControl__stop_song()

    def __stop_song(self):
        self.song().stop_playing()
        self._FocusControl__update_play_button_led()

    def __update_play_button_led(self):
        if self.song().is_playing:
            self._send_midi(
                (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_PLAY, BUTTON_STATE_ON))
            self._send_midi(
                (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_STOP, BUTTON_STATE_OFF))
        else:
            self._send_midi(
                (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_PLAY, BUTTON_STATE_OFF))
            self._send_midi(
                (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_STOP, BUTTON_STATE_ON))

    def __update_forward_rewind_leds(self):
        if self.forward_button_down:
            self._send_midi((MIDI_NOTE_ON_STATUS, SID_TRANSPORT_FAST_FORWARD,
                             BUTTON_STATE_ON))
        else:
            self._send_midi((MIDI_NOTE_ON_STATUS, SID_TRANSPORT_FAST_FORWARD,
                             BUTTON_STATE_OFF))
        if self.rewind_button_down:
            self._send_midi(
                (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_REWIND, BUTTON_STATE_ON))
        else:
            self._send_midi(
                (MIDI_NOTE_ON_STATUS, SID_TRANSPORT_REWIND, BUTTON_STATE_OFF))

    def set_up_controls(self):
        is_momentary = True
        self.left_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0,
                                         SID_NAV_LEFT)
        self.right_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0,
                                          SID_NAV_RIGHT)
        self._do_left.subject = self.left_button
        self._do_right.subject = self.right_button
        self.stop_button = ButtonElement(False, MIDI_NOTE_TYPE, 0,
                                         SID_TRANSPORT_STOP)
        self._do_stop.subject = self.stop_button

    @subject_slot('value')
    def _do_stop(self, value):
        self._FocusControl__stop_song()

    @subject_slot('value')
    def _do_left(self, value):
        assert value in range(128)
        if value != 0:
            self.navigate_midi_track(-1)

    @subject_slot('value')
    def _do_right(self, value):
        assert value in range(128)
        if value != 0:
            self.navigate_midi_track(1)

    def navigate_midi_track(self, direction):
        tracks = self.song().tracks
        seltrack = self.song().view.selected_track
        index = vindexof(tracks, seltrack)
        nxttrack = self.get_next_track(direction, index, tracks)
        if nxttrack:
            self.song().view.selected_track = nxttrack
            arm_exclusive(self.song(), nxttrack)

    def get_next_track(self, direction, index, tracks):
        pos = index
        if pos is None:
            pos = len(tracks)
        pos = pos + direction
        while 0 <= pos < len(tracks):
            track = tracks[pos]
            if track.can_be_armed:
                return track
            pos = pos + direction

    def get_next_midi_track(self, direction, index, tracks):
        pos = index
        if pos is None:
            pos = len(tracks)
        pos = pos + direction
        while 0 <= pos < len(tracks):
            track = tracks[pos]
            if track.can_be_armed:
                if track.has_midi_input:
                    return track
            pos = pos + direction

    def get_controlled_track(self):
        armed_tracks = []
        tracks = self.song().tracks
        for track in tracks:
            if track.can_be_armed and track.arm:
                armed_tracks.append(track)

        if len(armed_tracks) == 1:
            return (armed_tracks[0],
                    self.find_instrument_list(armed_tracks[0].devices))
        if len(armed_tracks) > 1:
            instr = self.find_instrument_ni(armed_tracks)
            if instr:
                return instr
            return self.find_instrument_any(armed_tracks)

    def find_instrument_ni(self, tracks):
        for track in tracks:
            instr = self.find_instrument_list(track.devices)
            if instr and instr[1] is not None:
                return (track, instr)

    def find_instrument_any(self, tracks):
        for track in tracks:
            instr = self.find_instrument_list(track.devices)
            if instr:
                return (track, instr)

    def _assign_tracks(self):
        tracks = self.song().tracks
        for track in self._tracks:
            track.release()

        self._tracks = []
        for index in range(len(tracks)):
            self._tracks.append(TrackElement(index, tracks[index], self))

    def activate_track(self, index, track):
        self.controlled_track = track
        instr = self.find_instrument_list(track.devices)
        self.update_status_midi(index, track, instr, 1)

    def deactivate_track(self, index, track):
        pass

    def devices_changed(self, index, track):
        instr = self.find_instrument_list(track.devices)
        self.update_status_midi(index, track, instr, 1)

    def _on_track_list_changed(self):
        super()._on_track_list_changed()
        self._assign_tracks()
        ctrack = self.get_controlled_track()
        if ctrack:
            track = ctrack[0]
            instr = ctrack[1]
            if track != self.controlled_track:
                self.controlled_track = track
                index = list(self.song().tracks).index(track)
        elif self.controlled_track:
            self.controlled_track = None

    def _on_selected_track_changed(self):
        super()._on_selected_track_changed()
        self.set_controlled_track(self.song().view.selected_track)

    def broadcast(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if not s:
            debug_out(' Could Not open Socket ')
        else:
            try:
                s.connect(('localhost', 60090))
                s.sendall('Hello, world'.encode('utf-8'))
                s.close()
            except ConnectionError:
                debug_out(' No Server ')

    @subject_slot('devices')
    def _on_devices_changed(self):
        self.scan_devices()

    def find_instrument_list(self, devicelist):
        for device in devicelist:
            instr = self.find_instrument(device)
            if instr:
                return instr

    def find_in_chain(self, chain):
        for device in chain.devices:
            instr = self.find_instrument(device)
            if instr:
                return instr

    def find_instrument(self, device):
        if device.type == 1:
            if device.can_have_chains:
                chains = device.chains
                for chain in chains:
                    instr = self.find_in_chain(chain)
                    if instr:
                        return instr

            else:
                if device.class_name == PLUGIN_CLASS_NAME_VST or device.class_name == PLUGIN_CLASS_NAME_AU:
                    if device.class_display_name.startswith(PLUGIN_PREFIX):
                        parms = device.parameters
                        if parms:
                            if len(parms) > 1:
                                pn = parms[1].name
                                pnLen = len(pn)
                                if pn.startswith(PARAM_PREFIX):
                                    return (str(device.class_display_name),
                                            str(pn[4:pnLen]))
            return (device.class_display_name, None)

    def scan_chain(self, chain):
        for device in chain.devices:
            self.scan_device(device)

    def scan_device(self, device):
        if device.class_name == 'PluginDevice' and device.class_display_name == 'FocusTester1':
            parms = device.parameters
        else:
            if device.can_have_chains:
                chains = device.chains
                for chain in chains:
                    self.scan_chain(chain)

    def update_status_midi(self, index, track, instrument, value):
        msgsysex = [240, 0, 0, 102, 20, 18, 0]
        tr_name = track.name
        for c in tr_name:
            msgsysex.append(ord(c))

        msgsysex.append(25)
        ind_str = str(index)
        for c in ind_str:
            msgsysex.append(ord(c))

        if instrument is not None:
            msgsysex.append(25)
            for c in instrument[0]:
                msgsysex.append(ord(c))

            if instrument[1] is not None:
                msgsysex.append(25)
                for c in instrument[1]:
                    msgsysex.append(ord(c))

        msgsysex.append(247)
        self._send_midi(tuple(msgsysex))

    def send_to_display(self, text, grid=0):
        if len(text) > 28:
            text = text[:27]
        msgsysex = [240, 0, 0, 102, 23, 18, min(grid, 3) * 28]
        filled = text.ljust(28)
        for c in filled:
            msgsysex.append(ord(c))

        msgsysex.append(247)
        self._send_midi(tuple(msgsysex))

    def scan_devices(self):
        song = self.song()
        for track in song.tracks:
            for device in track.devices:
                self.scan_device(device)

    def disconnect(self):
        self._active = False
        self._suppress_send_midi = True
        self.song().remove_is_playing_listener(
            self._FocusControl__update_play_button_led)
        super().disconnect()
class Roland_A_PRO(ControlSurface):

    def __init__(self, *a, **k):
        (super(Roland_A_PRO, self).__init__)(*a, **k)
        with self.component_guard():
            self._create_controls()
            self._create_transport()
            self._create_mixer()
            self._create_device()
            self._create_drums()
            self._create_modes()

    def _create_controls(self):
        self._encoders = ButtonMatrixElement(rows=[
         [EncoderElement(MIDI_CC_TYPE, 0, identifier, (Live.MidiMap.MapMode.absolute), name=('Encoder_%d' % index)) for index, identifier in enumerate(ENCODER_IDS)]])
        self._master_encoder = EncoderElement(MIDI_CC_TYPE,
          0, 10, (Live.MidiMap.MapMode.absolute), name='Master_Encoder')
        self._sliders = ButtonMatrixElement(rows=[
         [SliderElement(MIDI_CC_TYPE, 0, identifier, name=('Slider_%d' % index)) for index, identifier in enumerate(SLIDER_IDS)]])
        self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 7, name='Master_Slider')
        self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 26)
        self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 25)
        self._record_button = ButtonElement(True, MIDI_CC_TYPE, 0, 28)
        self._forward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 24)
        self._backward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 21)
        self._ff_button = ButtonElement(True, MIDI_CC_TYPE, 0, 23)
        self._rw_button = ButtonElement(True, MIDI_CC_TYPE, 0, 22)
        self._device_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 80)
        self._pan_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 81)
        self._send_a_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 82)
        self._send_b_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 83)
        self._pads = ButtonMatrixElement(rows=[[ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier) for identifier in row] for row in PAD_ROWS])

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

    def _create_mixer(self):
        mixer_size = self._sliders.width()
        self._mixer = MixerComponent(mixer_size,
          name='Mixer',
          is_enabled=False,
          layer=Layer(volume_controls=(self._sliders),
          prehear_volume_control=(self._master_encoder)))
        self._mixer.master_strip().layer = Layer(volume_control=(self._master_slider))
        self._mixer.set_enabled(True)

    def _create_device(self):
        self._device = DeviceComponent(device_selection_follows_track_selection=True)
        self._device_navigation = DeviceNavigationComponent()
        self._device.set_enabled(True)
        self._device_navigation.set_enabled(True)
        self.set_device_component(self._device)

    def _create_drums(self):
        self._drums = DrumRackComponent(name='Drum_Rack',
          is_enabled=False,
          layer=Layer(pads=(self._pads)))
        self._drums.set_enabled(True)

    def _create_modes(self):
        self._encoder_modes = ModesComponent()
        device_layer_mode = LayerMode(self._device, Layer(parameter_controls=(self._encoders)))
        device_navigation_layer_mode = LayerMode(self._device_navigation, Layer(device_nav_right_button=(self._forward_button),
          device_nav_left_button=(self._backward_button)))
        self._encoder_modes.add_mode('device_mode', [device_layer_mode, device_navigation_layer_mode])
        self._encoder_modes.add_mode('pan_mode', AddLayerMode(self._mixer, Layer(pan_controls=(self._encoders),
          bank_up_button=(self._forward_button),
          bank_down_button=(self._backward_button),
          track_up_button=(self._ff_button),
          track_down_button=(self._rw_button))))
        send_layer_mode = AddLayerMode(self._mixer, Layer(send_controls=(self._encoders),
          bank_up_button=(self._forward_button),
          bank_down_button=(self._backward_button),
          track_up_button=(self._ff_button),
          track_down_button=(self._rw_button)))
        self._encoder_modes.add_mode('send_a_mode', [send_layer_mode, partial(self._set_send_index, 0)])
        self._encoder_modes.add_mode('send_b_mode', [send_layer_mode, partial(self._set_send_index, 1)])
        self._encoder_modes.layer = Layer(device_mode_button=(self._device_mode_button),
          pan_mode_button=(self._pan_mode_button),
          send_a_mode_button=(self._send_a_mode_button),
          send_b_mode_button=(self._send_b_mode_button))
        self._encoder_modes.selected_mode = 'device_mode'
        self._encoder_modes.set_enabled(True)

    def _set_send_index(self, index):
        self._mixer.send_index = index
Esempio n. 8
0
 def _setup_transport(self):
     is_momentary = True
     transport = TransportComponent()
     studiotransport = MaschineTransport()
     playButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 108)
     stopButton = StateButton(not is_momentary, MIDI_CC_TYPE, 0, 110)
     recordButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 109)
     overdubButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 107)
     metrononmeButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 104)
     eventRecButton = StateButton(is_momentary, MIDI_CC_TYPE, 0, 98)
     playButton.name = 'Play'
     stopButton.name = 'Stop'
     recordButton.name = 'Record'
     overdubButton.name = 'Overdub'
     metrononmeButton.name = 'Metronome'
     transport.set_play_button(playButton)
     transport.set_stop_button(stopButton)
     transport.set_record_button(recordButton)
     transport.set_overdub_button(overdubButton)
     transport.set_metronome_button(metrononmeButton)
     studiotransport.set_session_auto_button(eventRecButton)
     studiotransport.set_arrangement_overdub_button(
         StateButton(is_momentary, MIDI_CC_TYPE, 0, 106))
     studiotransport.set_back_arrange_button(
         StateButton(is_momentary, MIDI_CC_TYPE, 0, 105))
     transport.set_nudge_buttons(
         StateButton(is_momentary, MIDI_CC_TYPE, 1, 51),
         StateButton(is_momentary, MIDI_CC_TYPE, 1, 50))
     punchinbutton = ToggleButton(MIDI_CC_TYPE, 1, 52)
     punchoutbutton = ToggleButton(MIDI_CC_TYPE, 1, 53)
     punchinbutton.name = 'Punch In'
     punchoutbutton.name = 'Punch Out'
     transport.set_punch_buttons(punchinbutton, punchoutbutton)
     transport.set_loop_button(
         StateButton(is_momentary, MIDI_CC_TYPE, 1, 54))
     self.song_follow_button = ButtonElement(True, MIDI_CC_TYPE, 2, 98)
     self._do_song_follow.subject = self.song_follow_button
     self._song_follow_changed.subject = self.song().view
     self._song_follow_changed()
     self.transp_ff_button = ButtonElement(True, MIDI_CC_TYPE, 1, 59)
     self.transp_rw_button = ButtonElement(True, MIDI_CC_TYPE, 1, 58)
     transport.set_seek_buttons(self.transp_ff_button,
                                self.transp_rw_button)
     self.xfadeKnob = SliderElement(MIDI_CC_TYPE, 1, 105)
     self.xfadeKnob.connect_to(
         self.song().master_track.mixer_device.crossfader)
     self.master_knob = SliderElement(MIDI_CC_TYPE, 0, 99)
     self.master_knob.connect_to(
         self.song().master_track.mixer_device.volume)
     self.tap_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 88)
     self._do_tap_tempo.subject = self.tap_button
     self.cue_add_delete_button = StateButton(is_momentary, MIDI_CC_TYPE, 1,
                                              55)
     self.cue_prev_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 56)
     self.cue_next_button = StateButton(is_momentary, MIDI_CC_TYPE, 1, 57)
     self._do_toggle_cue.subject = self.cue_add_delete_button
     self._do_toggle_prev_cue.subject = self.cue_prev_button
     self._do_toggle_next_cue.subject = self.cue_next_button
 def _create_transport(self):
     self._transport = TransportComponent(name='Transport')
 def _create_transport(self):
     self._transport = TransportComponent(is_enabled=True, name='Transport')
     self._transport.layer = Layer(play_button=(self._play_button),
       stop_button=(self._stop_button),
       record_button=(self._record_button))
 def __init__(self):
     TransportComponent.__init__(self)
     self._undo_button = None
     self._redo_button = None
     self._bts_button = None
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 zip(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 zip(HARDWARE_PAD_IDS, chain(*PAD_MSG_IDS)):
            self._setup_hardware_button(hardware_id,
              identifier, PAD_CHANNEL, msg_type='note')
 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)
class Axiom_AIR_25_49_61(ControlSurface):
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._alt_device_component = None
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = 'HyperControl'
            self._suggested_output_port = 'HyperControl'
            self._single_fader_button_modes = None
            self._has_faders = True
            self._display_reset_delay = -1
            self._hc_byte = HC_BYTE
            self._waiting_for_first_response = True
            self._setup_controls()
            self._setup_displays()
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_modes()
            self._drum_group_midi_button = None
            self._drum_group_hyper_button = None
            for component in self.components:
                component.set_enabled(False)

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

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

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

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

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

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

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

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

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

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

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

    def _update_device_selection(self):
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None:
            if len(track.devices) > 0:
                device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)
        if self._alt_device_component != None:
            self._alt_device_component.set_device(device_to_select)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            mixer_or_device.set_displays(encoder_display, parameter_display, device_display, tuple(page_displays))
            for component in self.components:
                component.set_enabled(False)