コード例 #1
0
class Midi_Fighter_Twister(ControlSurface):
    __doc__ = " Script for Midi_Fighter_Twister in APC emulation mode "

    _active_instances = []

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

    _combine_active_instances = staticmethod(_combine_active_instances)

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

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

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

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

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

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

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

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

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

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

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

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        # From Axiom_AIR_25_49_61.py line 202
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)

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

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

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

    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL,
                                   note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)  # CC Hold, CC Toggle
            shift_bank_button = ButtonElement(is_momentary, MESSAGETYPE,
                                              SHIFTBANKCHANNEL, note)
            shift_bank_button.name = 'Note_' + str(note)
            self._shift_bank_map.append(shift_bank_button)  # Shift Bank
            shift_encoder = ButtonElement(is_momentary, 1, ENCODERSHIFTCHANNEL,
                                          note)
            shift_encoder.name = 'Note_' + str(note)
            self._shift_encoder_map.append(shift_encoder)  # Shift Encoder Hold
        self._note_map.append(
            None)  #add None to the end of the list, selectable with [-1]
        self._shift_encoder_map.append(None)
        self._shift_bank_map.append(None)
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)  # Standard Encoder
            self._ctrl_map.append(None)
コード例 #2
0
class Launchkey(ControlSurface):
    """ Script for Novation's Launchkey 25/49/61 keyboards """

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = "Launchkey InControl"
            self._suggested_output_port = "Launchkey InControl"
            self._has_sliders = True
            self._current_midi_map = None
            self._master_slider = make_slider(7, "Master_Volume_Control")
            self._modes_buttons = []
            for index in range(3):
                button = ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0, 13 + index)
                self._modes_buttons.append(button)
                self._modes_buttons[-1].add_value_listener(self._dummy_listener)

            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            for component in self.components:
                component.set_enabled(False)

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(2, self._send_midi, LIVE_MODE_ON)
        self.schedule_message(3, self._send_midi, SIZE_QUERY)

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:11] == SIZE_RESPONSE:
            self._has_sliders = midi_bytes[11] != 48
            self._send_midi(LED_FLASHING_ON)
            self._update_mixer_offset()
            for control in self.controls:
                if isinstance(control, InputControlElement):
                    control.clear_send_cache()

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

            if self._has_sliders:
                self._mixer.master_strip().set_volume_control(self._master_slider)
                self._mixer.update()
            else:
                self._mixer.master_strip().set_volume_control(None)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    self._mixer.channel_strip(index).set_mute_button(None)
                    slider = self._sliders[index]
                    slider.release_parameter()

                self._mixer.selected_strip().set_volume_control(self._master_slider)
            self.request_rebuild_midi_map()

    def disconnect(self):
        ControlSurface.disconnect(self)
        for button in self._modes_buttons:
            if button.value_has_listener(self._dummy_listener):
                button.remove_value_listener(self._dummy_listener)

        self._modes_buttons = None
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._transport_view_modes = None
        self._send_midi(LED_FLASHING_OFF)
        self._send_midi(LIVE_MODE_OFF)

    def build_midi_map(self, midi_map_handle):
        self._current_midi_map = midi_map_handle
        ControlSurface.build_midi_map(self, midi_map_handle)

    def _setup_mixer(self):
        self._next_nav_button = make_button(103, "Next_Track_Button")
        self._prev_nav_button = make_button(102, "Prev_Track_Button")
        mute_solo_flip_button = make_button(59, "Master_Button")
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = "Mixer"
        self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button)
        self._mixer.selected_strip().name = "Selected_Channel_Strip"
        self._mixer.master_strip().name = "Master_Channel_Strip"
        self._mixer.master_strip().set_volume_control(self._master_slider)
        self._sliders = []
        self._strip_buttons = []
        for index in range(8):
            strip = self._mixer.channel_strip(index)
            strip.name = "Channel_Strip_" + str(index)
            strip.set_invert_mute_feedback(True)
            self._sliders.append(make_slider(41 + index, "Volume_Control_%d" % index))
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(make_button(51 + index, "Mute_Button_%d" % index))

        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button)

    def _setup_session(self):
        scene_launch_button = make_configurable_button(104, "Scene_Launch_Button")
        scene_stop_button = make_configurable_button(120, "Scene_Stop_Button")
        self._session = SpecialSessionComponent(8, 0)
        self._session.name = "Session_Control"
        self._session.selected_scene().name = "Selected_Scene"
        self._session.selected_scene().set_launch_button(scene_launch_button)
        self._session.selected_scene().set_triggered_value(GREEN_BLINK)
        self._session.set_stop_all_clips_button(scene_stop_button)
        scene_stop_button.set_on_off_values(AMBER_FULL, LED_OFF)
        self._session.set_mixer(self._mixer)
        self._session.set_track_banking_increment(8)
        self._session.set_stop_track_clip_value(GREEN_BLINK)
        clip_launch_buttons = []
        clip_stop_buttons = []
        for index in range(8):
            clip_launch_buttons.append(make_configurable_button(96 + index, "Clip_Launch_%d" % index))
            clip_stop_buttons.append(make_configurable_button(112 + index, "Clip_Stop_%d" % index))
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_triggered_to_play_value(GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(RED_BLINK)
            clip_slot.set_stopped_value(AMBER_FULL)
            clip_slot.set_started_value(GREEN_FULL)
            clip_slot.set_recording_value(RED_FULL)
            clip_slot.set_launch_button(clip_launch_buttons[-1])
            clip_slot.name = "Selected_Clip_Slot_" + str(index)

        self._session.set_stop_track_clip_buttons(tuple(clip_stop_buttons))

    def _setup_transport(self):
        rwd_button = make_button(112, "Rwd_Button")
        ffwd_button = make_button(113, "FFwd_Button")
        stop_button = make_button(114, "Stop_Button")
        play_button = make_button(115, "Play_Button")
        loop_button = make_button(116, "Loop_Button")
        rec_button = make_button(117, "Record_Button")
        transport = TransportComponent()
        transport.name = "Transport"
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_record_button(rec_button)
        transport.set_loop_button(loop_button)
        self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button)
        self._transport_view_modes.name = "Transport_View_Modes"

    def _setup_device(self):
        encoders = [make_encoder(21 + index, "Device_Control_%d" % index) for index in xrange(8)]
        self._encoders = tuple(encoders)
        device = DeviceComponent()
        device.name = "Device_Component"
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)

    def _dummy_listener(self, value):
        pass

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._update_mixer_offset()

    def _update_mixer_offset(self):
        all_tracks = self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks:
            track_index = list(all_tracks).index(selected_track)
            new_offset = track_index - track_index % num_strips
            self._session.set_offsets(new_offset, self._session.scene_offset())
コード例 #3
0
class Launchkey(ControlSurface):
    """ Script for Novation's Launchkey 25/49/61 keyboards """
    def __init__(self,
                 c_instance,
                 control_factory=LaunchkeyControlFactory(),
                 identity_response=SIZE_RESPONSE):
        ControlSurface.__init__(self, c_instance)
        self._control_factory = control_factory
        self._identity_response = identity_response
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = 'Launchkey InControl'
            self._suggested_output_port = 'Launchkey InControl'
            self._has_sliders = True
            self._current_midi_map = None
            self._master_slider = make_slider(7, 'Master_Volume_Control')
            self._modes_buttons = []
            for index in range(3):
                button = ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,
                                       13 + index)
                self._modes_buttons.append(button)
                self._modes_buttons[-1].add_value_listener(
                    self._dummy_listener)

            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_navigation()
            for component in self.components:
                component.set_enabled(False)

        return

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(2, self._send_midi, LIVE_MODE_ON)
        self.schedule_message(3, self._send_midi, SIZE_QUERY)

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:11] == self._identity_response:
            self._has_sliders = midi_bytes[11] != 48
            self._send_midi(LED_FLASHING_ON)
            self._update_mixer_offset()
            for control in self.controls:
                if isinstance(control, InputControlElement):
                    control.clear_send_cache()

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

            if self._has_sliders:
                self._mixer.master_strip().set_volume_control(
                    self._master_slider)
                self._mixer.update()
            else:
                self._mixer.master_strip().set_volume_control(None)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    self._mixer.channel_strip(index).set_mute_button(None)
                    slider = self._sliders[index]
                    slider.release_parameter()

                self._mixer.selected_strip().set_volume_control(
                    self._master_slider)
            self.request_rebuild_midi_map()
        return

    def disconnect(self):
        ControlSurface.disconnect(self)
        for button in self._modes_buttons:
            if button.value_has_listener(self._dummy_listener):
                button.remove_value_listener(self._dummy_listener)

        self._modes_buttons = None
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._transport_view_modes = None
        self._send_midi(LED_FLASHING_OFF)
        self._send_midi(LIVE_MODE_OFF)
        return

    def build_midi_map(self, midi_map_handle):
        self._current_midi_map = midi_map_handle
        ControlSurface.build_midi_map(self, midi_map_handle)

    def _setup_mixer(self):
        mute_solo_flip_button = make_button(59, 'Master_Button')
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_volume_control(self._master_slider)
        self._sliders = []
        self._strip_buttons = []
        for index in range(8):
            strip = self._mixer.channel_strip(index)
            strip.name = 'Channel_Strip_' + str(index)
            strip.set_invert_mute_feedback(True)
            self._sliders.append(
                make_slider(41 + index, 'Volume_Control_%d' % index))
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(
                make_button(51 + index, 'Mute_Button_%d' % index))

        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons),
                                                mute_solo_flip_button)

    def _setup_session(self):
        scene_launch_button = self._control_factory.create_scene_launch_button(
        )
        scene_stop_button = self._control_factory.create_scene_stop_button()
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(scene_launch_button)
        self._session.selected_scene().set_triggered_value(GREEN_BLINK)
        self._session.set_stop_all_clips_button(scene_stop_button)
        scene_stop_button.set_on_off_values(AMBER_FULL, LED_OFF)
        self._session.set_mixer(self._mixer)
        self._session.set_stop_clip_value(AMBER_HALF)
        self._session.set_stop_clip_triggered_value(GREEN_BLINK)
        clip_launch_buttons = []
        clip_stop_buttons = []
        for index in range(8):
            clip_launch_buttons.append(
                self._control_factory.create_clip_launch_button(index))
            clip_stop_buttons.append(
                self._control_factory.create_clip_stop_button(index))
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_triggered_to_play_value(GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(RED_BLINK)
            clip_slot.set_stopped_value(AMBER_FULL)
            clip_slot.set_started_value(GREEN_FULL)
            clip_slot.set_recording_value(RED_FULL)
            clip_slot.set_launch_button(clip_launch_buttons[-1])
            clip_slot.name = 'Selected_Clip_Slot_' + str(index)

        self._session.set_stop_track_clip_buttons(tuple(clip_stop_buttons))

    def _setup_transport(self):
        rwd_button = make_button(112, 'Rwd_Button')
        ffwd_button = make_button(113, 'FFwd_Button')
        stop_button = make_button(114, 'Stop_Button')
        play_button = make_button(115, 'Play_Button')
        loop_button = make_button(116, 'Loop_Button')
        rec_button = make_button(117, 'Record_Button')
        transport = TransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_record_button(rec_button)
        transport.set_loop_button(loop_button)
        self._transport_view_modes = TransportViewModeSelector(
            transport, self._session, ffwd_button, rwd_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        encoders = [
            make_encoder(21 + index, 'Device_Control_%d' % index)
            for index in xrange(8)
        ]
        self._encoders = tuple(encoders)
        device = DeviceComponent(device_selection_follows_track_selection=True)
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)

    def _setup_navigation(self):
        self._next_track_button = self._control_factory.create_next_track_button(
        )
        self._prev_track_button = self._control_factory.create_prev_track_button(
        )
        self._session_navigation = SessionNavigationComponent(
            name='Session_Navigation')
        self._session_navigation.set_next_track_button(self._next_track_button)
        self._session_navigation.set_prev_track_button(self._prev_track_button)

    def _dummy_listener(self, value):
        pass

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._update_mixer_offset()

    def _update_mixer_offset(self):
        all_tracks = self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks:
            track_index = list(all_tracks).index(selected_track)
            new_offset = track_index - track_index % num_strips
            self._session.set_offsets(new_offset, self._session.scene_offset())
コード例 #4
0
ファイル: JAMP_alpha.py プロジェクト: 4dvn/JustAMidiPad
class JAMP_alpha(ControlSurface):
    __doc__ = " Script for JAMP_alpha in APC emulation mode "

    _active_instances = []

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

    _combine_active_instances = staticmethod(_combine_active_instances)

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

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

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

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

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

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

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

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map[DEVICEONOFF])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT],
                                          self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

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

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

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

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

    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL,
                                   note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)
        self._note_map.append(
            None)  #add None to the end of the list, selectable with [-1]
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
コード例 #5
0
class SubSelectorComponent(ModeSelectorComponent):
    """ Class that handles different mixer modes """
    def __init__(self, matrix, side_buttons, session, control_surface):
        assert isinstance(matrix, ButtonMatrixElement)
        assert ((matrix.width() == 8) and (matrix.height() == 8))
        assert isinstance(side_buttons, tuple)
        assert (len(side_buttons) == 8)
        assert isinstance(session, SessionComponent)
        ModeSelectorComponent.__init__(self)
        self._control_surface = control_surface
        self._session = session
        self._mixer = SpecialMixerComponent(matrix.width())
        self._matrix = matrix
        self._sliders = []
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_strip'
        self._mixer.selected_strip().name = 'Selected_Channel_strip'
        for column in range(matrix.width()):
            self._mixer.channel_strip(
                column).name = 'Channel_Strip_' + str(column)
            self._sliders.append(
                PreciseButtonSliderElement(
                    tuple([
                        matrix.get_button(column, 7 - row) for row in range(8)
                    ])))
            self._sliders[-1].name = 'Button_Slider_' + str(column)

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

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

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

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

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

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

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

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

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

    def number_of_modes(self):
        return 4

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
コード例 #6
0
class Oxygen_3rd_Gen(ControlSurface):
    """ Script for the 3rd generation of M-Audio's Oxygen controllers """
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            is_momentary = True
            self._suggested_input_port = 'Oxygen'
            self._suggested_output_port = 'Oxygen'
            self._has_slider_section = True
            self._device_selection_follows_track_selection = True
            self._shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                               GLOBAL_CHANNEL, 57)
            self._shift_button.add_value_listener(self._shift_value)
            self._mixer = SpecialMixerComponent(NUM_TRACKS)
            self._mute_solo_buttons = []
            self._track_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                                  GLOBAL_CHANNEL, 111)
            self._track_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                                    GLOBAL_CHANNEL, 110)
            self._master_slider = SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL,
                                                41)
            for index in range(NUM_TRACKS):
                self._mute_solo_buttons.append(
                    ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL,
                                  49 + index))
                self._mixer.channel_strip(index).set_volume_control(
                    SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 33 + index))

            self._shift_value(0)
            self._mixer.master_strip().set_volume_control(self._master_slider)
            self._mixer.selected_strip().set_volume_control(None)
            device = DeviceComponent()
            device.set_parameter_controls(
                tuple([
                    EncoderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 17 + index,
                                   Live.MidiMap.MapMode.absolute)
                    for index in range(8)
                ]))
            self.set_device_component(device)
            ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                        GLOBAL_CHANNEL, 115)
            rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                       GLOBAL_CHANNEL, 114)
            loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE,
                                        GLOBAL_CHANNEL, 113)
            transport = TransportComponent()
            transport.set_stop_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 116))
            transport.set_play_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 117))
            transport.set_record_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 118))
            session = SessionComponent(0, 0)
            transport_view_modes = TransportViewModeSelector(
                transport, session, ffwd_button, rwd_button, loop_button)

    def disconnect(self):
        self._shift_button.remove_value_listener(self._shift_value)
        self._shift_button = None
        ControlSurface.disconnect(self)

    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:5] == IDENTITY_RESPONSE:
            if midi_bytes[10] == 38:
                self._mixer.master_strip().set_volume_control(None)
                self._mixer.selected_strip().set_volume_control(
                    self._master_slider)

    def _shift_value(self, value):
        raise value in range(128) or AssertionError
        for index in range(NUM_TRACKS):
            if value == 0:
                self._mixer.channel_strip(index).set_solo_button(None)
                self._mixer.channel_strip(index).set_mute_button(
                    self._mute_solo_buttons[index])
                self._mixer.set_bank_buttons(None, None)
                self._mixer.set_select_buttons(self._track_up_button,
                                               self._track_down_button)
            else:
                self._mixer.channel_strip(index).set_mute_button(None)
                self._mixer.channel_strip(index).set_solo_button(
                    self._mute_solo_buttons[index])
                self._mixer.set_select_buttons(None, None)
                self._mixer.set_bank_buttons(self._track_up_button,
                                             self._track_down_button)
コード例 #7
0
class Novation_Impulse(ControlSurface):
    """ Script for Novation's Impulse keyboards """

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'Impulse'
            self._suggested_output_port = 'Impulse'
            self._has_sliders = True
            self._current_midi_map = None
            self._display_reset_delay = -1
            self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 39)
            self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 41)
            self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8)
            self._shift_button.name = 'Shift_Button'
            self._master_slider.name = 'Master_Volume_Control'
            self._master_slider.add_value_listener(self._slider_value, identify_sender=True)
            self._preview_button.add_value_listener(self._preview_value)
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_name_display()
            device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 10)
            mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9)
            device_button.name = 'Encoder_Device_Mode'
            mixer_button.name = 'Encoder_Mixer_Mode'
            self._encoder_modes = EncoderModeSelector(self._device_component, self._mixer, self._next_bank_button, self._prev_bank_button, self._encoders)
            self._encoder_modes.set_device_mixer_buttons(device_button, mixer_button)
            self._string_to_display = None
            for component in self.components:
                component.set_enabled(False)

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(3, self._send_midi, SYSEX_START + (6, 1, 1, 1, 247))

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:-2] == SYSEX_START + (7,) and midi_bytes[-2] != 0:
            self._has_sliders = midi_bytes[-2] != 25
            self.schedule_message(1, self._show_startup_message)
            for control in self.controls:
                if isinstance(control, InputControlElement):
                    control.clear_send_cache()

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

            if self._has_sliders:
                self._mixer.master_strip().set_volume_control(self._master_slider)
                self._mixer.update()
            else:
                self._mixer.master_strip().set_volume_control(None)
                self._mixer.selected_strip().set_volume_control(self._master_slider)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    slider = self._sliders[index]
                    slider.release_parameter()
                    if slider.value_has_listener(self._slider_value):
                        slider.remove_value_listener(self._slider_value)

            self._encoder_modes.set_provide_volume_mode(not self._has_sliders)
            self.request_rebuild_midi_map()

    def disconnect(self):
        self._name_display_data_source.set_display_string('  ')
        for encoder in self._encoders:
            encoder.remove_value_listener(self._encoder_value)

        self._master_slider.remove_value_listener(self._slider_value)
        if self._has_sliders:
            for slider in tuple(self._sliders):
                slider.remove_value_listener(self._slider_value)

        for button in self._strip_buttons:
            button.remove_value_listener(self._mixer_button_value)

        self._preview_button.remove_value_listener(self._preview_value)
        ControlSurface.disconnect(self)
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._shift_button = None
        self._name_display = None
        self._prev_bank_button = None
        self._next_bank_button = None
        self._encoder_modes = None
        self._transport_view_modes = None
        self._send_midi(SYSEX_START + (6, 0, 0, 0, 247))

    def build_midi_map(self, midi_map_handle):
        self._current_midi_map = midi_map_handle
        ControlSurface.build_midi_map(self, midi_map_handle)

    def update_display(self):
        ControlSurface.update_display(self)
        if self._string_to_display != None:
            self._name_display_data_source.set_display_string(self._string_to_display)
            self._string_to_display = None
        if self._display_reset_delay >= 0:
            self._display_reset_delay -= 1
            if self._display_reset_delay == -1:
                self._show_current_track_name()

    def _setup_mixer(self):
        mute_solo_flip_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 34)
        self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 37)
        self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 38)
        self._strip_buttons = []
        mute_solo_flip_button.name = 'Mute_Solo_Flip_Button'
        self._next_nav_button.name = 'Next_Track_Button'
        self._prev_nav_button.name = 'Prev_Track_Button'
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button)
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_volume_control(self._master_slider)
        self._sliders = []
        for index in range(8):
            strip = self._mixer.channel_strip(index)
            strip.name = 'Channel_Strip_' + str(index)
            strip.set_invert_mute_feedback(True)
            self._sliders.append(SliderElement(MIDI_CC_TYPE, 0, index))
            self._sliders[-1].name = str(index) + '_Volume_Control'
            self._sliders[-1].set_feedback_delay(-1)
            self._sliders[-1].add_value_listener(self._slider_value, identify_sender=True)
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + index))
            self._strip_buttons[-1].name = str(index) + '_Mute_Button'
            self._strip_buttons[-1].add_value_listener(self._mixer_button_value, identify_sender=True)

        self._mixer.master_strip().set_mute_button(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 17))
        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button)

    def _setup_session(self):
        num_pads = len(PAD_TRANSLATIONS)
        self._track_left_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36)
        self._track_right_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35)
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.set_mixer(self._mixer)
        self._session.set_page_left_button(self._track_left_button)
        self._session.set_page_right_button(self._track_right_button)
        pads = []
        for index in range(num_pads):
            pads.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index))
            pads[-1].name = 'Pad_' + str(index)
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_triggered_to_play_value(GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(RED_BLINK)
            clip_slot.set_stopped_value(AMBER_FULL)
            clip_slot.set_started_value(GREEN_FULL)
            clip_slot.set_recording_value(RED_FULL)
            clip_slot.set_launch_button(pads[-1])
            clip_slot.name = str(index) + '_Selected_Clip_Slot'

    def _setup_transport(self):
        rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 27)
        ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 28)
        stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 29)
        play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 30)
        loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 31)
        rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 32)
        ffwd_button.name = 'FFwd_Button'
        rwd_button.name = 'Rwd_Button'
        loop_button.name = 'Loop_Button'
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        rec_button.name = 'Record_Button'
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        transport.set_stop_button(stop_button)
        transport.set_play_button(play_button)
        transport.set_record_button(rec_button)
        transport.set_shift_button(self._shift_button)
        self._transport_view_modes = TransportViewModeSelector(transport, self._session, ffwd_button, rwd_button, loop_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        encoders = []
        for index in range(8):
            encoders.append(PeekableEncoderElement(MIDI_CC_TYPE, 1, index, Live.MidiMap.MapMode.relative_binary_offset))
            encoders[-1].set_feedback_delay(-1)
            encoders[-1].add_value_listener(self._encoder_value, identify_sender=True)
            encoders[-1].name = 'Device_Control_' + str(index)

        self._encoders = tuple(encoders)
        self._prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 12)
        self._next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 11)
        self._prev_bank_button.name = 'Device_Bank_Down_Button'
        self._next_bank_button.name = 'Device_Bank_Up_Button'
        device = DeviceComponent()
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)
        device.set_bank_nav_buttons(self._prev_bank_button, self._next_bank_button)

    def _setup_name_display(self):
        self._name_display = PhysicalDisplayElement(16, 1)
        self._name_display.name = 'Display'
        self._name_display.set_message_parts(SYSEX_START + (8,), (247,))
        self._name_display_data_source = DisplayDataSource()
        self._name_display.segment(0).set_data_source(self._name_display_data_source)

    def _encoder_value(self, value, sender):
        if not sender in self._encoders:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                display_string = self._device_component.is_enabled() and ' - '
                display_string = sender.mapped_parameter() != None and sender.mapped_parameter().name
            self._set_string_to_display(display_string)

    def _slider_value(self, value, sender):
        if not sender in tuple(self._sliders) + (self._master_slider,):
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                if self._mixer.is_enabled():
                    display_string = ' - '
                    if sender.mapped_parameter() != None:
                        master = self.song().master_track
                        tracks = self.song().tracks
                        returns = self.song().return_tracks
                        track = None
                        if sender == self._master_slider:
                            track = self._has_sliders and master
                        else:
                            track = self.song().view.selected_track
                    else:
                        track = self._mixer.channel_strip(self._sliders.index(sender))._track
                    display_string = track == master and 'Master'
                elif track in tracks:
                    display_string = str(list(tracks).index(track) + 1)
                elif track in returns:
                    display_string = str(chr(ord('A') + list(returns).index(track)))
                else:
                    raise False or AssertionError
                display_string += ' Volume'
            self._set_string_to_display(display_string)

    def _mixer_button_value(self, value, sender):
        if not value in range(128):
            raise AssertionError
            if self._mixer.is_enabled() and value > 0:
                strip = self._mixer.channel_strip(self._strip_buttons.index(sender))
                self._string_to_display = strip != None and None
                self._name_display.segment(0).set_data_source(strip.track_name_data_source())
                self._name_display.update()
                self._display_reset_delay = STANDARD_DISPLAY_DELAY
            else:
                self._set_string_to_display(' - ')

    def _preview_value(self, value):
        raise value in range(128) or AssertionError
        for encoder in self._encoders:
            encoder.set_peek_mode(value > 0)

    def _show_current_track_name(self):
        if self._name_display != None and self._mixer != None:
            self._string_to_display = None
            self._name_display.segment(0).set_data_source(self._mixer.selected_strip().track_name_data_source())
            self._name_display.update()

    def _show_startup_message(self):
        self._name_display.display_message('LIVE')
        self._display_reset_delay = INITIAL_DISPLAY_DELAY

    def _set_string_to_display(self, string_to_display):
        raise isinstance(string_to_display, (str, unicode)) or AssertionError
        self._name_display.segment(0).set_data_source(self._name_display_data_source)
        self._string_to_display = string_to_display
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        self._show_current_track_name()
        all_tracks = self._has_sliders or self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks:
            track_index = list(all_tracks).index(selected_track)
            new_offset = track_index - track_index % num_strips
            if not new_offset / num_strips == int(new_offset / num_strips):
                raise AssertionError
                self._session.set_offsets(new_offset, self._session.scene_offset())
コード例 #8
0
class SpecialMixerSelectorComponent(ModeSelectorComponent):
	" CLASS THAT HANDLES DIFFERENT MIXER MODES "

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

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

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

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

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

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

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

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

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

	" SETUP THE MIXER "
	def _setup_mixer_overview(self):
		# mute and solo and stop
		stop_buttons = []
		button_index = 0
		for track in range(len(self.song().tracks)):
			if self.song().tracks[track].is_foldable:
				if button_index < GROUPS_CONSIDERED:
					strip = self._mixer.channel_strip(track)
					# mute
					self._matrix.get_button(button_index, MUTE_INDEX).set_on_off_values(GREEN_FULL, GREEN_THIRD)
					strip.set_mute_button(self._matrix.get_button(button_index, MUTE_INDEX))		
					# solo
					self._matrix.get_button(button_index, SOLO_INDEX).set_on_off_values(RED_FULL, RED_THIRD )			
					strip.set_solo_button(self._matrix.get_button(button_index, SOLO_INDEX))
					# stop				
					button = self._matrix.get_button(button_index, STOP_INDEX)				
					button.set_on_off_values(AMBER_FULL, AMBER_THIRD)				
					button.turn_on();
					stop_buttons.append(button)
					# increment
					button_index = button_index + 1
				else:
					stop_buttons.append(None)
			else:
				stop_buttons.append(None)				
			
		# side buttons
		self._side_buttons[0].set_on_off_values(RED_FULL, RED_THIRD)
		self._side_buttons[0].set_force_next_value()
		self._side_buttons[0].turn_off()		
		self._side_buttons[1].set_on_off_values(AMBER_FULL, AMBER_HALF)
		self._side_buttons[1].set_force_next_value()
		self._side_buttons[1].turn_off()
		self._side_buttons[2].set_on_off_values(GREEN_FULL, GREEN_THIRD)
		self._side_buttons[2].set_force_next_value()
		self._side_buttons[2].turn_on()
			
		self._session.set_stop_track_clip_buttons(tuple(stop_buttons))
		self._session.set_mixer(self._mixer)
		self._session.set_stop_all_clips_button(self._side_buttons[1])
		self._mixer.set_global_buttons(self._side_buttons[2], self._side_buttons[0], self._side_buttons[1])
コード例 #9
0
ファイル: APC40.py プロジェクト: psykel/APC40-Magic
class APC40(APC):
    __doc__ = " Script for Akai's APC40 Controller "

    def __init__(self, c_instance):
        APC.__init__(self, c_instance)

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)
        right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        right_button.name = "Bank_Select_Right_Button"
        left_button.name = "Bank_Select_Left_Button"
        up_button.name = "Bank_Select_Up_Button"
        down_button.name = "Bank_Select_Down_Button"
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = "Session_Control"
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        matrix.name = "Button_Matrix"
        scene_launch_buttons = [
            ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5)
        ]
        self._double_buttons = [
            ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5)
        ]
        track_stop_buttons = [ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8)]
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = "Scene_" + str(index) + "_Launch_Button"
        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = "Track_" + str(index) + "_Stop_Button"
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        stop_all_button.name = "Stop_All_Clips_Button"
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = "Scene_" + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53))
                button.name = str(track_index) + "_Clip_" + str(scene_index) + "_Button"
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + "_Clip_Slot_" + str(scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(3)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(5)
                clip_slot.set_launch_button(button)

            matrix.add_row(tuple(button_row))

        self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = "Selected_Scene"
        self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session)
        self._session_zoom.name = "Session_Overview"
        self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)

        scene_user_mode = SceneUserModeComponent(self._session, self._session_zoom, self)

        return None  # return session

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = "Mixer"
        self._mixer.master_strip().name = "Master_Channel_Strip"
        self._mixer.selected_strip().name = "Selected_Channel_Strip"
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = "Channel_Strip_" + str(track)
            volume_control = SliderElement(MIDI_CC_TYPE, track, 7)
            arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
            select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51)
            volume_control.name = str(track) + "_Volume_Control"
            arm_button.name = str(track) + "_Arm_Button"
            solo_button.name = str(track) + "_Solo_Button"
            mute_button.name = str(track) + "_Mute_Button"
            select_button.name = str(track) + "_Select_Button"
            strip.set_volume_control(volume_control)
            strip.set_arm_button(arm_button)
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_select_button(select_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)
        crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
        self.prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)

        self._mixer.set_shift_button(self._shift_button)  # added for shifting prehear

        crossfader.name = "Crossfader"
        master_volume_control.name = "Master_Volume_Control"
        master_select_button.name = "Master_Select_Button"
        self.prehear_control.name = "Prehear_Volume_Control"
        self._mixer.set_crossfader_control(crossfader)
        self._mixer.set_prehear_volume_control(self.prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._mixer.master_strip().set_select_button(master_select_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = (
            "Clip_Track_Button",
            "Device_On_Off_Button",
            "Previous_Device_Button",
            "Next_Device_Button",
            "Detail_View_Button",
            "Rec_Quantization_Button",
            "Midi_Overdub_Button",
            "Metronome_Button",
        )
        for index in range(8):
            device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = "Device_Control_" + str(index)
            ring_mode_button.name = ringed_encoder.name + "_Ring_Mode_Button"
            device_param_controls.append(ringed_encoder)

        device = ShiftableDeviceComponent()
        device.name = "Device_Component"
        device.set_bank_buttons(tuple(device_bank_buttons))
        device.set_shift_button(self._shift_button)
        device.set_parameter_controls(tuple(device_param_controls))
        device.set_on_off_button(device_bank_buttons[1])

        self.set_device_component(device)
        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = "Detail_View_Control"
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])
        transport = ShiftableTransportComponent()
        transport.name = "Transport"
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = "Play_Button"
        stop_button.name = "Stop_Button"
        record_button.name = "Record_Button"
        nudge_up_button.name = "Nudge_Up_Button"
        nudge_down_button.name = "Nudge_Down_Button"
        tap_tempo_button.name = "Tap_Tempo_Button"
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])

        # The metronome button is device lock instead
        # transport.set_metronome_button(device_bank_buttons[7])
        device.set_lock_button(device_bank_buttons[7])  # assign device lock to bank_button 8 (in place of metronome)...

        transport.set_tempo_encoder(self.prehear_control)

        bank_button_translator = ShiftableTranslatorComponent()
        bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        global_bank_buttons = []
        global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = "Track_Control_" + str(index)
            ring_button.name = ringed_encoder.name + "_Ring_Mode_Button"
            ringed_encoder.set_ring_mode_button(ring_button)
            global_param_controls.append(ringed_encoder)
        global_bank_buttons = []
        global_bank_labels = ("Pan_Button", "Send_A_Button", "Send_B_Button", "Send_C_Button")
        for index in range(4):
            global_bank_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            global_bank_buttons[-1].name = global_bank_labels[index]
        encoder_modes = EncoderMixerModeSelectorComponent(self._mixer)
        encoder_modes.name = "Track_Control_Modes"
        encoder_modes.set_modes_buttons(global_bank_buttons)
        encoder_modes.set_controls(tuple(global_param_controls))
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = "Global_Translations"
        global_translation_selector.set_controls_to_translate(tuple(global_param_controls))
        global_translation_selector.set_mode_buttons(tuple(global_bank_buttons))

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

    def _product_model_id_byte(self):
        return 115
コード例 #10
0
ファイル: AumPC40.py プロジェクト: Adamdma/monomodular
class AumPC40(APC):
	__doc__ = " Script for Akai's APC40 Controller "
	
	def __init__(self, c_instance):
		APC.__init__(self, c_instance)
		self._device_selection_follows_track_selection = True


	def _setup_session_control(self):
		is_momentary = True
		self._shift_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98, self)		   
		right_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96, self)
		self._right_button = right_button
		left_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97, self)
		self._left_button = left_button
		up_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94, self)
		self._up_button = up_button
		down_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95, self)
		self._down_button = down_button
		right_button.name = 'Bank_Select_Right_Button'
		left_button.name = 'Bank_Select_Left_Button'
		up_button.name = 'Bank_Select_Up_Button'
		down_button.name = 'Bank_Select_Down_Button'
		self._session = PedaledSessionComponent(8, 5)
		self._session.name = 'Session_Control'
		self._session.set_track_bank_buttons(right_button, left_button)
		self._session.set_scene_bank_buttons(down_button, up_button)
		matrix = ButtonMatrixElement()
		self._matrix = matrix  # added a
		matrix.name = 'Button_Matrix'
		scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5) ]
		track_stop_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52, self) for index in range(8) ]
		self._track_stop_buttons = track_stop_buttons  # added a
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
		for index in range(len(track_stop_buttons)):
			track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
		stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
		stop_all_button.name = 'Stop_All_Clips_Button'
		self._session.set_stop_all_clips_button(stop_all_button)
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session.set_stop_track_clip_value(2)
		for scene_index in range(5):
			scene = self._session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			scene.set_triggered_value(2)
			for track_index in range(8):
				button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53), self)
				button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				clip_slot.set_triggered_to_play_value(2)
				clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(5)
				clip_slot.set_started_value(1)
				clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)
			matrix.add_row(tuple(button_row))
		self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
		self._session.selected_scene().name = 'Selected_Scene'
		self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		self._session_zoom = SessionZoomingComponent(self._session)
		self._session_zoom.name = 'Session_Overview'
		self._session_zoom.set_button_matrix(matrix)
		self._session_zoom.set_zoom_button(self._shift_button)
		self._session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
		self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		self._session_zoom.set_stopped_value(3)
		self._session_zoom.set_selected_value(5)
		return None	  
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._mixer = SpecialMixerComponent(8)
		self._mixer.name = 'Mixer'
		self._mixer.master_strip().name = 'Master_Channel_Strip'
		self._mixer.selected_strip().name = 'Selected_Channel_Strip'
		self._solo_buttons = []	# added a
		self._select_buttons = []	# added a
		for track in range(8):
			strip = self._mixer.channel_strip(track)
			strip.name = 'Channel_Strip_' + str(track)
			volume_control = MonoEncoderElement2(MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute, 'Slider_' + str(track), track, self)
			arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
			solo_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50, self)
			self._solo_buttons.append(solo_button)	# added a
			mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
			select_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51, self)
			self._select_buttons.append(select_button)	# added a
			#volume_control.name = str(track) + '_Volume_Control'
			arm_button.name = str(track) + '_Arm_Button'
			solo_button.name = str(track) + '_Solo_Button'
			mute_button.name = str(track) + '_Mute_Button'
			select_button.name = str(track) + '_Select_Button'
			strip.set_volume_control(volume_control)
			strip.set_arm_button(arm_button)
			strip.set_solo_button(solo_button)
			strip.set_mute_button(mute_button)
			strip.set_select_button(select_button)
			strip.set_shift_button(self._shift_button)
			strip.set_invert_mute_feedback(True)
		crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
		self._master_select_button = master_select_button
		prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
		crossfader.name = 'Crossfader'
		master_volume_control.name = 'Master_Volume_Control'
		master_select_button.name = 'Master_Select_Button'
		prehear_control.name = 'Prehear_Volume_Control'
		self._mixer.set_crossfader_control(crossfader)
		self._mixer.set_prehear_volume_control(prehear_control)
		self._mixer.master_strip().set_volume_control(master_volume_control)
		self._mixer.master_strip().set_select_button(master_select_button)
	

	def _setup_custom_components(self):
		self._setup_device_and_transport_control()
		self._setup_global_control()
	

	def _setup_device_and_transport_control(self):
		is_momentary = True
		device_bank_buttons = []
		device_param_controls = []
		bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Metronome_Button')
		for index in range(8):
			device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
			device_bank_buttons[-1].name = bank_button_labels[index]
			ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
			ringed_encoder = MonoRingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute, index, self)
			ringed_encoder.set_ring_mode_button(ring_mode_button)
			ringed_encoder.name = 'Device_Control_' + str(index)
			ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
			device_param_controls.append(ringed_encoder)
		device = ShiftableDeviceComponent(self)
		device.name = 'Device_Component'
		device.set_bank_buttons(tuple(device_bank_buttons))
		device.set_shift_button(self._shift_button)
		device.set_parameter_controls(tuple(device_param_controls))
		device.set_on_off_button(device_bank_buttons[1])
		self.set_device_component(device)
		detail_view_toggler = DetailViewCntrlComponent()
		detail_view_toggler.name = 'Detail_View_Control'
		detail_view_toggler.set_shift_button(self._shift_button)
		detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
		detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
		detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])
		transport = ShiftableTransportComponent()
		transport.name = 'Transport'
		self._transport = transport
		play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
		stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
		record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
		nudge_up_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100, self)
		self._nudge_up_button = nudge_up_button
		nudge_down_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101, self)
		self._nudge_down_button = nudge_down_button
		tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
		play_button.name = 'Play_Button'
		stop_button.name = 'Stop_Button'
		record_button.name = 'Record_Button'
		nudge_up_button.name = 'Nudge_Up_Button'
		nudge_down_button.name = 'Nudge_Down_Button'
		tap_tempo_button.name = 'Tap_Tempo_Button'
		transport.set_shift_button(self._shift_button)
		transport.set_play_button(play_button)
		transport.set_stop_button(stop_button)
		transport.set_record_button(record_button)
		transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
		transport.set_tap_tempo_button(tap_tempo_button)
		transport.set_quant_toggle_button(device_bank_buttons[5])
		transport.set_overdub_button(device_bank_buttons[6])
		transport.set_metronome_button(device_bank_buttons[7])
		bank_button_translator = ShiftTranslatorComponent()
		bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons))
		bank_button_translator.set_shift_button(self._shift_button)
	

	def _setup_global_control(self):
		is_momentary = True
		global_bank_buttons = []
		global_param_controls = []
		for index in range(8):
			ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
			ringed_encoder = MonoRingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute, index + 8, self)
			ringed_encoder.name = 'Track_Control_' + str(index)
			ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
			ringed_encoder.set_ring_mode_button(ring_button)
			global_param_controls.append(ringed_encoder)
		global_bank_buttons = []
		global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')
		for index in range(4):
			global_bank_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
			global_bank_buttons[-1].name = global_bank_labels[index]
		encoder_modes = EncModeSelectorComponent(self._mixer)
		encoder_modes.name = 'Track_Control_Modes'
		encoder_modes.set_modes_buttons(global_bank_buttons)
		encoder_modes.set_controls(tuple(global_param_controls))
		global_translation_selector = ChannelTranslationSelector()
		global_translation_selector.name = 'Global_Translations'
		global_translation_selector.set_controls_to_translate(tuple(global_param_controls))
		global_translation_selector.set_mode_buttons(tuple(global_bank_buttons))
	

	def _product_model_id_byte(self):
		return 115
	

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

	def _setup_monomod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self.hosts = [self._host]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for row in range(5):
			button_row = []
			for column in range(8):
				button_row.append(self._matrix.get_button(column, row))
			self._monomod.add_row(tuple(button_row))
		self._monomod.add_row(tuple(self._track_stop_buttons))
		self._monomod.add_row(tuple(self._select_buttons))
		self._monomod.add_row(tuple(self._solo_buttons))
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
	

	def _monomod_mode_update(self):
		if(self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self.flash_status = 0
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._monomod.reset()
			self._session.set_track_bank_buttons(self._right_button, self._left_button)
			self._session.set_scene_bank_buttons(self._down_button, self._up_button)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(self._select_buttons[track])
				self._mixer.channel_strip(track).set_solo_button(self._solo_buttons[track])
			self._transport.set_nudge_buttons(self._nudge_up_button, self._nudge_down_button)
			self._session.set_enabled(True)
			self._session_zoom._is_zoomed_out = False
			self._session_zoom.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_off()
			
		elif(self._monomod_mode._mode_index == 1):
			self._transport.set_nudge_buttons(None, None)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_solo_button(None)
			self._session.set_enabled(False)
			self._session_zoom.set_enabled(False)
			self._session.set_track_bank_buttons(None, None)
			self._session.set_scene_bank_buttons(None, None)
			self.flash_status = 1
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			self._host._set_nav_buttons([self._up_button, self._down_button, self._left_button, self._right_button])
			self._host._set_shift_button(self._shift_button)
			self._host._set_lock_button(self._nudge_up_button)
			self._host._set_alt_button(self._nudge_down_button)
			self._host.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_on()
	

	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		#self.log_message(display_string)
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if (not display_string):
			return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
		if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))):
			display_string = display_string[:-2]
		if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)):
					um_pos = display_string.rfind(um, 1)
					display_string = (display_string[:um_pos] + display_string[(um_pos + 1):])
		else:
			display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1))
		ret = u''
		for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)):
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		if isinstance(sender, (MonoRingedEncoderElement, MonoEncoderElement2)):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

	def touched(self):
		if self._touched is 0:
			self._monobridge._send('touch', 'on')
			self.schedule_message(2, self.check_touch)
		self._touched +=1
	

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)
	

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)##.clip.name)
					return clip_slot._clip_slot
					##self.log_message(str(clip_slot._clip_slot.clip.name))
		return clip_names
	



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

		for callback in self._timer_callbacks:
			callback()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

	def flash(self):
		if(self.flash_status > 0):
			for row in range(8):
				for column in range(8):
					button = self._monomod.get_button(column, row)
					if(button._flash_state > 0):
						button.flash(self._timer)
コード例 #11
0
class SubSelectorComponent(ModeSelectorComponent):

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

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

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

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

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

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

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

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

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

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

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

	def number_of_modes(self):
		return 4

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		self._session.set_stop_track_clip_buttons(None)
		self._session.set_stop_all_clips_button(None)
		self._mixer.set_global_buttons(None, None, None)
コード例 #12
0
class APC40(APC):
    __doc__ = " Script for Akai's APC40 Controller "
    
    def __init__(self, c_instance):
        APC.__init__(self, c_instance)
        self._device_selection_follows_track_selection = True
        
    def _setup_session_control(self):
    	is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)        
        right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        up_button.name = 'Bank_Select_Up_Button'
        down_button.name = 'Bank_Select_Down_Button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        matrix.name = 'Button_Matrix'
        self.scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5) ]
        track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
        for index in range(len(self.scene_launch_buttons)):
            self.scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
        self.stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        self.stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(self.stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        
        ## Quirksmode
        self.newZoom_buttons = []
        
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []

            scene.set_launch_button(self.scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53))
                
                ## Quirksmode - This moves the zoomer to allow for scene launch customisation (Currently not working 100%)
                if(track_index == 4):
                	self.newZoom_buttons.append(button)
                
                button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(3)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)

            matrix.add_row(tuple(button_row))

        self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(self.newZoom_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)
        return None #return session

    def _setup_mixer_control(self):
        is_momentary = True
        
        ## Quirksmode
        self.arm_buttons = []
        
        self._mixer = SpecialMixerComponent(self, 8) #added self for parent
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        for track in range(8):
            self.strip = self._mixer.channel_strip(track)
            self.strip.name = 'Channel_Strip_' + str(track)
            volume_control = SliderElement(MIDI_CC_TYPE, track, 7)
            arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
            select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51)
            volume_control.name = str(track) + '_Volume_Control'
            arm_button.name = str(track) + '_Arm_Button'
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            select_button.name = str(track) + '_Select_Button'
            self.strip.set_volume_control(volume_control)
            
            ##Quirksmode
            self.arm_buttons.append(arm_button)
            
            self.strip.set_arm_button(arm_button)
            self.strip.set_solo_button(solo_button)
            self.strip.set_mute_button(mute_button)
            self.strip.set_select_button(select_button)
            self.strip.set_shift_button(self._shift_button)
            self.strip.set_invert_mute_feedback(True)
        crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        
        
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
        ##self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        master_select_button.name = 'Master_Select_Button'
        ##self._prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_crossfader_control(crossfader)
        ##self._mixer.set_prehear_volume_control(self._prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._mixer.master_strip().set_select_button(master_select_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()
        self._setup_djModeToggle()
        
        
    
    def _setup_djModeToggle(self):
    	self._newDjModeToggle_state = False
    	
    	## How many tracks?
    	self._trackTotal = len(self.song().tracks)
    
    	## Re-Assign Metronome to Dj Mode toggle
        self._newDjModeToggle_button = self.transport._metronome_button
        self.transport.set_metronome_button(None)
        self._newDjModeToggle_button.add_value_listener(self._toggleDjMode)
        
        ## Assign Cue Volume (Temporary hack until I get the correct Api Values)
        self.transport._tempo_encoder_control.connect_to(self.song().master_track.mixer_device.cue_volume)
        
        
        	
    def _toggleDjMode(self, value):
    	if value == 1:
			if(self._newDjModeToggle_state):
				self._newDjModeToggle_button.turn_off()
				self._newDjModeToggle_state = False
				self.show_message("########################################################################################## DJ MODE: OFF ##############################")
				self._disconnect_djMode()
				self.transport._cueLevelMode = 1
				self.device_bank_buttons[4].turn_on()
				self.transport._tempo_encoder_control.connect_to(self.song().master_track.mixer_device.cue_volume)
				
				
				
				
			else:
				self._newDjModeToggle_button.turn_on()
				self._newDjModeToggle_state = True
				self.show_message("########################################################################################## DJ MODE: ON ##############################")
				self._setup_djMode()
				self.transport._cueLevelMode = 2
				self.device_bank_buttons[4].turn_off()
				self.transport._tempo_encoder_control.release_parameter()
				
				
				
    
	
				
    def _setup_djMode(self):
    	## Assign imports
        self.sceneEffect = SceneEffectComponent(self)
        self.reset = ResetComponent(self)
        self.armmode = ArmToggleComponent(self)
        self.trackControl = TrackControlComponent(self)
    
    	is_momentary = True
    	
    	       
        ##### Scene Effect Component
        self.sceneEffect.set_shift_button(self._shift_button)
        
        for scene_index in range(5):
        	self.sceneEffect.newScene_button = self._session.scene(scene_index)._launch_button
        	self._session.scene(scene_index).set_launch_button(None)
        	self.sceneEffect.newScene_button.add_value_listener(self.sceneEffect._device_toggle, True)
        	self.sceneEffect._device_buttons.append(self.sceneEffect.newScene_button)
        
        # Re-assign the stop all clips button
        self.sceneEffect._newStopAll_button = self._session._stop_all_button
        self._session.set_stop_all_clips_button(None)
        self.sceneEffect._newStopAll_button.add_value_listener(self.sceneEffect._masterRepeat)
        
        
          
        ##### Reset Component
        self.reset.set_shift_button(self._shift_button)
        
        #Re-assign Play and Stop buttons to Reset Track and All
        self.reset.reset_button = self.transport._play_button
        self.transport.set_play_button(None)
        self.reset.reset_button.add_value_listener(self.reset.reset_track)
        
        self.reset.resetAll_button = self.transport._stop_button
        self.transport.set_stop_button(None)
        self.reset.resetAll_button.add_value_listener(self.reset.reset_all)
        
        
        	
        ##### Arm Toggle Component
        self.armmode.set_shift_button(self._shift_button)
        
        # Re-Assign Clip/Track Button to Loop/Utility toggle
        self.armmode._newDetailView_button = self.detail_view_toggler._detail_toggle_button
        self.detail_view_toggler.set_detail_toggle_button(None)
        self.armmode._newDetailView_button.add_value_listener(self.armmode._toggleArmMode)
        
        
        
        # Re-assign Arm button functionality
        for track in range(8):
        	self.armmode.newArm_button = self._mixer.channel_strip(track)._arm_button
        	self._mixer.channel_strip(track).set_arm_button(None)
        	self.armmode.newArm_button.add_value_listener(self.armmode._device_toggle, True)
        	self.armmode._arm_buttons.append(self.armmode.newArm_button)
        
        
        ##### Re-assign Track Control Ringed Encoders
        self.trackControl._trackEncoders = []
        for encoder_index in range(8):
        	self.newTrackEncoder_encoder = self.global_param_controls[encoder_index]
        	self.encoder_modes.set_controls(None)
        	self.trackControl._trackEncoders.append(self.newTrackEncoder_encoder)
        
        
        self.get_current_track()	
        if(self.song().view.selected_track != self.song().master_track):
        	for device in self.song().tracks[self.current_track].devices:
				if device.name == "DJ EQ and FX":
					for parameter in range(8):
						self.trackControl._trackEncoders[parameter].connect_to(device.parameters[parameter+1])
						
	
	    
    def _disconnect_djMode(self):
    
    	##### Disconnect Scene Effect Component    	
    	# Re-assign the Scene Start Buttons
    	for scene_index in range(5):
        	self.sceneEffect._device_buttons[scene_index].remove_value_listener(self.sceneEffect._device_toggle)
        	self._session.scene(scene_index).set_launch_button(self.scene_launch_buttons[scene_index])
        self.sceneEffect._device_buttons = []
    	# Re-assign the stop all clips button
    	self.sceneEffect._newStopAll_button.remove_value_listener(self.sceneEffect._masterRepeat)
    	self.sceneEffect._newStopAll_button = None
    	self._session.set_stop_all_clips_button(self.stop_all_button)    	        
        self.song().view.remove_selected_track_listener(self.sceneEffect.sceneLight)
        

          
        ##### Disconnect Reset Component       
        # Re-assign the Play Button
        self.reset.reset_button.remove_value_listener(self.reset.reset_track)
        self.reset.reset_button = None
        self.transport.set_play_button(self.play_button)
        # Re-assign the Stop Button
        self.reset.resetAll_button.remove_value_listener(self.reset.reset_all)
        self.reset.resetAll_button = None
        self.transport.set_stop_button(self.stop_button)
        
        
      
        ##### Disconnect Arm Toggle Component
    	for track in range(8):
        	self.armmode._arm_buttons[track].remove_value_listener(self.armmode._device_toggle)
        	self._mixer.channel_strip(track).set_arm_button(self.arm_buttons[track])
        self.armmode._arm_buttons = []
        
        self.armmode._newDetailView_button.remove_value_listener(self.armmode._toggleArmMode)
    	self.armmode._newDetailView_button = None
        self.detail_view_toggler.set_detail_toggle_button(self.device_bank_buttons[4])
        self.song().view.remove_selected_track_listener(self.armmode._armLightMode)
        
        
        
        ##### Disconnect Track Control Ringed Encoders
        self.trackControl._trackEncoders = []
        self.song().view.remove_selected_track_listener(self.trackControl.get_current_track)
        
	
	##### Link the cutoffs for the Scene Effect Parameters
    def _linkCutoff(self, value):
    	for device in self.song().tracks[self.current_track].devices:
				if device.name == "Scene Launch Effects":
					device.parameters[1].value = value
						
    
    def _setup_device_and_transport_control(self):
        is_momentary = True
        self.device_bank_buttons = []
        self.device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            self.device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            self.device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            
            ## Quirksmode
            ##### Link the cutoffs for the Scene Effect Parameters
            if (index == 0):
            	ringed_encoder.add_value_listener(self._linkCutoff)
            
            self.device_param_controls.append(ringed_encoder)
        self.device = ShiftableDeviceComponent()
        self.device.name = 'Device_Component'
        self.device.set_bank_buttons(tuple(self.device_bank_buttons))
        self.device.set_shift_button(self._shift_button)
        self.device.set_parameter_controls(tuple(self.device_param_controls))
        self.device.set_on_off_button(self.device_bank_buttons[1])
        self.set_device_component(self.device)
        self.detail_view_toggler = DetailViewCntrlComponent()
        self.detail_view_toggler.name = 'Detail_View_Control'
        self.detail_view_toggler.set_shift_button(self._shift_button)
        self.detail_view_toggler.set_device_clip_toggle_button(self.device_bank_buttons[0])
        self.detail_view_toggler.set_detail_toggle_button(self.device_bank_buttons[4])
        self.detail_view_toggler.set_device_nav_buttons(self.device_bank_buttons[2], self.device_bank_buttons[3])
        self.transport = ShiftableTransportComponent(self) ## Quirksmode added self
        self.transport.name = 'Transport'
        self.play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        self.play_button.name = 'Play_Button'
        
        self.stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        self.record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        self.stop_button.name = 'Stop_Button'
        self.record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_Button'
        nudge_down_button.name = 'Nudge_Down_Button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        self.transport.set_shift_button(self._shift_button)
        self.transport.set_play_button(self.play_button)
        self.transport.set_stop_button(self.stop_button)
        self.transport.set_record_button(self.record_button)
        self.transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        self.transport.set_undo_button(nudge_down_button) #shifted nudge
        self.transport.set_redo_button(nudge_up_button) #shifted nudge
        self.transport.set_tap_tempo_button(tap_tempo_button)
        self.transport.set_quant_toggle_button(self.device_bank_buttons[5])
        self.transport.set_overdub_button(self.device_bank_buttons[6])
        self.transport.set_metronome_button(self.device_bank_buttons[7])
        self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        self.transport.set_tempo_encoder(self._prehear_control) #shifted prehear
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(tuple(self.device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        global_bank_buttons = []
        self.global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            self.global_param_controls.append(ringed_encoder)
        global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')
        for index in range(4):
            global_bank_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            global_bank_buttons[-1].name = global_bank_labels[index]
        self.encoder_modes = EncModeSelectorComponent(self._mixer)
        self.encoder_modes.name = 'Track_Control_Modes'
        self.encoder_modes.set_modes_buttons(global_bank_buttons)
        self.encoder_modes.set_controls(tuple(self.global_param_controls))
        self.global_translation_selector = ChannelTranslationSelector()
        self.global_translation_selector.name = 'Global_Translations'
        self.global_translation_selector.set_controls_to_translate(tuple(self.global_param_controls))
        self.global_translation_selector.set_mode_buttons(tuple(global_bank_buttons))

    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        
        ## Quirksmode
        if(self._newDjModeToggle_state):
        
	    	if self.application().view.is_view_visible('Detail/Clip'):
	    		self.application().view.show_view('Detail/DeviceChain')
	    		self.application().view.is_view_visible('Detail/DeviceChain')
	    	else:
	    		self.application().view.show_view('Detail/Clip')
	    		self.application().view.is_view_visible('Detail/Clip')
		
	    	if(self.song().view.selected_track != self.song().master_track):
		    	if (self.song().view.selected_track.playing_slot_index > -1):
		            self.song().view.selected_scene = self.song().scenes[self.song().view.selected_track.playing_slot_index]
	    
        
	        track_index = 0
	        for track in self.song().tracks:
	        	if track == self.song().view.selected_track:
	        		break
	        	track_index += 1
	        self.current_track = track_index
            
        
        
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)
        return None
    
    
    
    
    
    ######################### Utils
    
    # Get the current track    
    def get_current_track(self):
    	track_index = 0
    	for track in self.song().tracks:
    		if track == self.song().view.selected_track:
    			break
    		track_index += 1
    	self.current_track = track_index
    
    
    # Get the device on the given track by the given name.
    def GetDeviceByName(self, trackIndex, deviceName):
        for device in self.song().tracks[trackIndex].devices:
            if (device.name == deviceName):
                return device
        return None

    # Get the value of the given device in the given track by the given parameter name. 
    def GetDeviceParameter(self, device, paramName):
        for deviceParam in device.parameters:
            if (deviceParam.name == paramName):
                return deviceParam.value
            return None

    # Set the given parameter name of the given device to the given value.
    def SetDeviceParameter(self, device, paramName, value):
        for deviceParam in device.parameters:
            if (deviceParam.name == paramName):
                deviceParam.value = value
                pass

    # Toggles the given param of the given device. Usefull for on/off effects, etc.
    def ToggleDeviceParameter(self, device, paramName):
        for deviceParam in device.parameters:
            if (deviceParam.name == paramName):
                if (deviceParam.value == 1):
                    deviceParam.value = 0
                else:
                    deviceParam.value = 1
                pass

    # Returns if the given track has a triggered clip.
    def TrackHasTriggeredClip(self, track):
        for clipSlot in track.clip_slots:
            if (clipSlot.has_clip):
                if (clipSlot.clip.is_triggered):
                    return True
        return False

    # Returns if the given track has a playing clip.
    def TrackHasPlayingClip(self, track):
        for clipSlot in track.clip_slots:
            if (clipSlot.has_clip):
                if (clipSlot.clip.is_playing):
                    return True
        return False

    
    def _product_model_id_byte(self):
        return 115
コード例 #13
0
class Novation_Impulse2(ControlSurface):
    """ Script for Novation's Impulse keyboards """

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.c_instance = c_instance
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'Impulse'
            self._suggested_output_port = 'Impulse'
            self._has_sliders = True
            self._current_midi_map = None
            self._display_reset_delay = -1
            self._string_to_display = None
            self.shift_pressed = False
            # special alternative buttons mode. for now only mixer buttons become record buttons. later we will add something more
            self.alternative_buttons_mode = False
            self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 39)
            self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 41)
            self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8)
            self._shift_button.name = 'Shift_Button'
            self._master_slider.name = 'Master_Volume_Control'
            self._master_slider.add_value_listener(self._slider_value, identify_sender=True)
            self._preview_button.add_value_listener(self._preview_value)
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_name_display()
            device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 10)
            mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9)
            device_button.name = 'Encoder_Device_Mode'
            mixer_button.name = 'Encoder_Mixer_Mode'
            self._encoder_modes = EncoderModeSelector(self._device_component, self._mixer, self._next_bank_button, self._prev_bank_button, self._encoders)
            self._encoder_modes.set_device_mixer_buttons(device_button, mixer_button)
            self._shift_button.add_value_listener(self._shift_button_handler)

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

    # attributes
    def alternative_buttons_mode(self):
        return self.alternative_buttons_mode

    def alternative_buttons_mode(self,value):
        self.log ('alternative_buttons_mode_value ' + str(value))
        self.alternative_buttons_mode = value

    def shift_pressed(self):
        return self.shift_pressed

    def shift_pressed(self,value):
        self.log ('shift_pressed value ' + str(value))
        self.shift_pressed = value

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(3, self._send_midi, SYSEX_START + (6, 1, 1, 1, 247))

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:-2] == SYSEX_START + (7,) and midi_bytes[-2] != 0:
            self._has_sliders = midi_bytes[-2] != 25
            self.schedule_message(1, self._show_startup_message)
            for control in self.controls:
                if isinstance(control, InputControlElement):
                    control.clear_send_cache()

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

            if self._has_sliders:
                self._mixer.master_strip().set_volume_control(self._master_slider)
                self._mixer.update()
            else:
                self._mixer.master_strip().set_volume_control(None)
                self._mixer.selected_strip().set_volume_control(self._master_slider)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    slider = self._sliders[index]
                    slider.release_parameter()
                    if slider.value_has_listener(self._slider_value):
                        slider.remove_value_listener(self._slider_value)

            self._encoder_modes.set_provide_volume_mode(not self._has_sliders)
            self.request_rebuild_midi_map()

    def disconnect(self):
        self.log('starting disconnect 1')
        self._name_display_data_source.set_display_string('  ')
        for encoder in self._encoders:
            encoder.remove_value_listener(self._encoder_value)

        self._master_slider.remove_value_listener(self._slider_value)
        if self._has_sliders:
            for slider in tuple(self._sliders):
                slider.remove_value_listener(self._slider_value)

        for button in self._strip_buttons:
            button.remove_value_listener(self._mixer_button_value)

        self._preview_button.remove_value_listener(self._preview_value)
        self.log('starting disconnect 3')
        ControlSurface.disconnect(self)
        self.log('starting disconnect 3')
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._name_display = None
        self._prev_bank_button = None
        self._next_bank_button = None
        self._encoder_modes = None
        self._transport_view_modes = None
        self.log('starting disconnect 4')
        self._send_midi(SYSEX_START + (6, 0, 0, 0, 247))
        self.log('starting disconnect 5')

        if self._shift_button != None:
            self._shift_button.remove_value_listener(self._shift_button_handler)
            self._shift_button = None
        self.log('starting disconnect 6')

    def build_midi_map(self, midi_map_handle):
        self._current_midi_map = midi_map_handle
        ControlSurface.build_midi_map(self, midi_map_handle)

    def update_display(self):
        ControlSurface.update_display(self)
        if self._string_to_display != None:
            self._name_display_data_source.set_display_string(self._string_to_display)
            self._string_to_display = None
        if self._display_reset_delay >= 0:
            self._display_reset_delay -= 1
            if self._display_reset_delay == -1:
                self._show_current_track_name()

    def _setup_mixer(self):
        self.log('setup mixer')
        mute_solo_flip_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 34)
        self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 37)
        self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 38)
        self._strip_buttons = []
        mute_solo_flip_button.name = 'Mute_Solo_Flip_Button'
        self._next_nav_button.name = 'Next_Track_Button'
        self._prev_nav_button.name = 'Prev_Track_Button'
        self._mixer = SpecialMixerComponent(self, 8, self.c_instance)
        self._mixer.name = 'Mixer'
        self._mixer.set_select_buttons(self._next_nav_button, self._prev_nav_button)
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_volume_control(self._master_slider)
        self._sliders = []
        for index in range(8):
            strip = self._mixer.channel_strip(index)
            strip.name = 'Channel_Strip_' + str(index)
            strip.set_invert_mute_feedback(True)
            self._sliders.append(SliderElement(MIDI_CC_TYPE, 0, index))
            self._sliders[-1].name = str(index) + '_Volume_Control'
            self._sliders[-1].set_feedback_delay(-1)
            self._sliders[-1].add_value_listener(self._slider_value, identify_sender=True)
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + index))
            self._strip_buttons[-1].name = str(index) + '_Mute_Button'
            self._strip_buttons[-1].add_value_listener(self._mixer_button_value, identify_sender=True)

        self._mixer.master_strip().set_mute_button(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 17))
        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons), mute_solo_flip_button)
        #self._mixer.set_shift_button(self._shift_button)
        self._mixer.updateMixerButtons()

        self._button9 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + 8)

    def _setup_session(self):
        num_pads = len(PAD_TRANSLATIONS)
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.set_mixer(self._mixer)
        # for ableton 9.1.1 and lower
        #self._session.set_track_banking_increment(num_pads)
        #self._session.set_track_bank_buttons(ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35), ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36))
        # for ableton 9.1.1 and higher
        self._track_left_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36)
        self._track_right_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35)
        self._session.set_page_left_button(self._track_left_button)
        self._session.set_page_right_button(self._track_right_button)

        pads = []
        for index in range(num_pads):
            pads.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index))
            pads[-1].name = 'Pad_' + str(index)
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_triggered_to_play_value(GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(RED_BLINK)
            clip_slot.set_stopped_value(AMBER_FULL)
            clip_slot.set_started_value(GREEN_FULL)
            clip_slot.set_recording_value(RED_FULL)
            clip_slot.set_launch_button(pads[-1])
            clip_slot.name = str(index) + '_Selected_Clip_Slot'

    def _setup_transport(self):
        rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 27)
        ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 28)
        stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 29)
        play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 30)
        loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 31)
        rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 32)
        ffwd_button.name = 'FFwd_Button'
        rwd_button.name = 'Rwd_Button'
        loop_button.name = 'Loop_Button'
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        rec_button.name = 'Record_Button'
        self._transport = ShiftableTransportComponent(self.c_instance,self._session, self, ffwd_button, rwd_button)
        self._transport.name = 'Transport'
        self._transport.set_stop_buttonOnInit(stop_button)
        self._transport.set_play_button(play_button)
        self._transport.set_record_buttonOnInit(rec_button)
#        self._transport.set_shift_button(self._shift_button)
        self._transport.set_mixer9_button(self._button9)
        self._transport_view_modes = TransportViewModeSelector(self,self.c_instance,self._transport, self._session, ffwd_button, rwd_button, loop_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        encoders = []
        for index in range(8):
            encoders.append(PeekableEncoderElement(MIDI_CC_TYPE, 1, index, Live.MidiMap.MapMode.relative_binary_offset))
            encoders[-1].set_feedback_delay(-1)
            encoders[-1].add_value_listener(self._encoder_value, identify_sender=True)
            encoders[-1].name = 'Device_Control_' + str(index)

        self._encoders = tuple(encoders)
        self._prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 12)
        self._next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 11)
        self._prev_bank_button.name = 'Device_Bank_Down_Button'
        self._next_bank_button.name = 'Device_Bank_Up_Button'
        device = DeviceComponent()
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)
        device.set_bank_nav_buttons(self._prev_bank_button, self._next_bank_button)

    def _setup_name_display(self):
        self._name_display = PhysicalDisplayElement(16, 1)
        self._name_display.name = 'Display'
        self._name_display.set_message_parts(SYSEX_START + (8,), (247,))
        self._name_display_data_source = DisplayDataSource()
        self._name_display.segment(0).set_data_source(self._name_display_data_source)

    def _encoder_value(self, value, sender):
        if not sender in self._encoders:
            raise AssertionError
        if not value in range(128):
            raise AssertionError
#        display_string = self._device_component.is_enabled() and ' - '
#        display_string = sender.mapped_parameter() != None and sender.mapped_parameter().name
        display_string = ''
        if self._device_component.is_enabled():
#            display_string = sender.name
#            track = self.song().view.selected_track
#            display_string = str(list(tracks).index(track) + 1)
            pass
        if (sender.mapped_parameter() != None):
#            display_string = display_string + '-'
            display_string =  display_string + sender.mapped_parameter().name
        self._set_string_to_display(display_string)

    def _slider_value(self, value, sender):
        self.log ('_slider_value ' + str(value) + ' ' +str(sender))
        if not sender in tuple(self._sliders) + (self._master_slider,):
            raise AssertionError
        if not value in range(128):
            raise AssertionError
        if self._mixer.is_enabled():
            display_string = ' - '
            master = self.song().master_track
            tracks = self.song().tracks
            returns = self.song().return_tracks
            track = None
            if sender.mapped_parameter() != None:
                self.log ('1')
                if sender == self._master_slider:
                    self.log ('2')
#                    track = self._has_sliders and master
                    if self._has_sliders:
                        track = master
                    else:
                        self.log ('2.1')
                        track = self.song().view.selected_track
                else:
                    self.log ('3')
                    track = self._mixer.channel_strip(self._sliders.index(sender))._track
            else:
                self.log ('4')
                track = self.song().view.selected_track
            self.log('track='+str(track))
            if track == master:
                display_string  = 'Master'
            elif track in tracks:
                display_string = str(list(tracks).index(track) + 1)
            elif track in returns:
                display_string = str(chr(ord('A') + list(returns).index(track)))
            else:
#            raise False or AssertionError
                raise AssertionError
            display_string += ' Volume'
            self._set_string_to_display(display_string)

    def _mixer_button_value(self, value, sender):
        self.log ('__mixer_button_value ' + str(value) + ' ' +str(sender))
        if not value in range(128):
            raise AssertionError
        #if self._mixer.is_enabled() and value > 0:
        if self._mixer.is_enabled():
            strip = self._mixer.channel_strip(self._strip_buttons.index(sender))
            #self._string_to_display = strip != None and None
            self._name_display.segment(0).set_data_source(strip.track_name_data_source())
            self._name_display.update()
            self._display_reset_delay = STANDARD_DISPLAY_DELAY
        else:
            self._set_string_to_display(' - ')
        # if shift_pressed XOR alternative_mode
        if self.shift_pressed <> self.alternative_buttons_mode:
            self.log("_mixer_button_value")
            self.log(str(value))
            if (value == 0):
                self.select_armed_track_if_only_one()

    def select_armed_track_if_only_one(self):
        self.log("select_armed_track_if_only_one")
        song = self.song()
        armed_tracks = []
        tracks = song.tracks
        self.log("select_armed_track_if_only_one 2")
        for track in tracks:
            if track.can_be_armed and track.arm:
                armed_tracks.append(track)
        self.log(str(len(armed_tracks)))
        if (len(armed_tracks) == 1):
            self.log("selecting the track")
            sel_track = armed_tracks[0]
            self.song().view.selected_track = sel_track
            self._mixer._selected_tracks = []
            self._mixer._selected_tracks.append(sel_track)
            self._mixer.on_selected_track_changed()

    def _preview_value(self, value):
        if not value in range(128):
            raise AssertionError
        for encoder in self._encoders:
            encoder.set_peek_mode(value > 0)

    def _show_current_track_name(self):
        if self._name_display != None and self._mixer != None:
            self._string_to_display = None
            self._name_display.segment(0).set_data_source(self._mixer.selected_strip().track_name_data_source())
            self._name_display.update()

    def _show_startup_message(self):
        self._name_display.display_message('LIVE')
        self._display_reset_delay = INITIAL_DISPLAY_DELAY

    def _set_string_to_display(self, string_to_display):
        if not isinstance(string_to_display, (str, unicode)):
            raise AssertionError
        self._name_display.segment(0).set_data_source(self._name_display_data_source)
        self._string_to_display = string_to_display
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _on_selected_track_changed(self):
        self.log('_on_selected_track_changed')
        ControlSurface._on_selected_track_changed(self)
        self._show_current_track_name()
        #all_tracks = self._has_sliders or self._session.tracks_to_use()
        all_tracks2 = self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks2:
            track_index = list(all_tracks2).index(selected_track)
            self.log('track_index '+ str(track_index))
            new_offset = track_index - track_index % num_strips
            self.log('new_offset '+ str(new_offset))
            if not new_offset / num_strips == int(new_offset / num_strips):
                raise AssertionError
            self._session.set_offsets(new_offset, self._session.scene_offset())


    def _shift_button_handler(self, value):
        self.log("root shift handler : "+ str(value))
        if not self._shift_button != None:
            raise AssertionError
        if not value in range(128):
            raise AssertionError
        self.log("root shift handler 2")
        self.shift_pressed = value > 0
# calling other handlers
        self._mixer._shift_button_handler(value)
        self._transport._shift_button_handler(value)
        self._transport_view_modes._shift_button_handler(value)

#clip stop
        self.log("root shift handler 3")
        num_pads = len(PAD_TRANSLATIONS)
        pads = []
        for index in range(num_pads):
            pads.append(ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index))
            pads[-1].name = 'Pad_' + str(index)
            clip_slot = self._session.selected_scene().clip_slot(index)
            if self.shift_pressed:
                clip_slot.set_launch_button(None)
            else:
                clip_slot.set_launch_button(pads[index])
        if self.shift_pressed:
            self._session.set_stop_track_clip_buttons(tuple(pads))
        else:
            self._session.set_stop_track_clip_buttons(None)

        self.log("root shift handler 4")

    def flipAlternativeButtonMode(self):
        self.alternative_buttons_mode = not self.alternative_buttons_mode
        self.updateAlternativeButtonMode()

    def updateAlternativeButtonMode(self):
        self._mixer.updateMixerButtons()
        self._transport_view_modes.update()

    def log(self, message):
        pass
コード例 #14
0
class APC_64_40_9_vu(APC):
    """ Script for Akai's APC40 Controller """
    def __init__(self, c_instance):
        self._c_instance = c_instance
        self._shift_modes = None
        self._encoder_modes = None
        self._slider_modes = None
        self._sequencer = None
        APC.__init__(self, c_instance)
        self._device_selection_follows_track_selection = True
		
    def disconnect(self):
        self._shift_modes = None
        self._encoder_modes = None
        self._slider_modes = None
        self._sequencer = None
        APC.disconnect(self)  

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)
        self._right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        self._left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        self._up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        self._down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        self._right_button.name = 'Bank_Select_Right_button'
        self._left_button.name = 'Bank_Select_Left_button'
        self._up_button.name = 'Bank_Select_Up_button'
        self._down_button.name = 'Bank_Select_Down_button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._right_button, self._left_button)
        self._session.set_scene_bank_buttons(self._down_button, self._up_button)
        self._matrix = ButtonMatrixElement()
        self._matrix.name = 'Button_Matrix'
        self._scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, index + 82) for index in range(5) ]
        self._track_stop_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
        for index in range(len(self._scene_launch_buttons)):
            self._scene_launch_buttons[index].name = 'Scene_' + str(index) + '_Launch_Button'
        for index in range(len(self._track_stop_buttons)):
            self._track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
        self._stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        self._stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(self._stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        self._session.set_stop_clip_value(0)
        self._session.set_stop_clip_triggered_value(2)

        self._button_rows = []
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53))
                button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)
            self._matrix.add_row(tuple(button_row))
            self._button_rows.append(button_row)
        


        self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))


        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = ShiftableZoomingComponent(self._session, tuple(self._track_stop_buttons))
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(self._matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(self._up_button, self._down_button, self._left_button, self._right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(self._scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)


    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(self, 8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
        master_select_button.name = 'Master_Select_Button'
        self._mixer.master_strip().set_select_button(master_select_button)
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        select_buttons = []
        arm_buttons = []
        solo_buttons = []
        mute_buttons = []
        sliders = []     
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
            solo_buttons.append(solo_button)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
            mute_buttons.append(mute_button)
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)
            select_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51))
            select_buttons[-1].name = str(track) + '_Select_Button'          
            arm_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
            arm_buttons[-1].name = str(track) + '_Arm_Button'
            sliders.append(SliderElement(MIDI_CC_TYPE, track, 7))
            sliders[-1].name = str(track) + '_Volume_Control'

        self._crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        self._crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        self._prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_shift_button(self._shift_button)
        self._mixer.set_crossfader_control(self._crossfader)
        self._mixer.set_prehear_volume_control(self._prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._slider_modes = SliderModesComponent(self._mixer, tuple(sliders))
        self._slider_modes.name = 'Slider_Modes'
        self._matrix_modes = MatrixModesComponent(self._matrix, self._session, self._session_zoom, tuple(self._track_stop_buttons), self)
        self._matrix_modes.name = 'Matrix_Modes'
        self._sequencer = StepSequencerComponent(self, self._session, self._matrix, tuple(self._track_stop_buttons))
        self._sequencer.set_bank_buttons(tuple(select_buttons))
        self._sequencer.set_nav_buttons(self._up_button, self._down_button, self._left_button, self._right_button)
        self._sequencer.set_button_matrix(self._matrix)
        self._sequencer.set_follow_button(master_select_button)
        self._sequencer.set_velocity_buttons(tuple(arm_buttons))
        self._sequencer.set_shift_button(self._shift_button)
        self._sequencer.set_lane_mute_buttons(tuple(self._scene_launch_buttons))
        self._sequencer.set_loop_start_buttons(tuple(mute_buttons))
        self._sequencer.set_loop_length_buttons(tuple(solo_buttons))
        self._shift_modes = ShiftableSelectorComponent(self, tuple(select_buttons), master_select_button, tuple(self._track_stop_buttons), self._stop_all_button, tuple(mute_buttons), tuple(solo_buttons), tuple(arm_buttons), tuple(self._scene_launch_buttons), self._matrix, self._session, self._session_zoom, self._mixer, self._slider_modes, self._matrix_modes, self._sequencer)
        self._shift_modes.name = 'Shift_Modes'
        self._shift_modes.set_mode_toggle(self._shift_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.set_feedback_delay(-1)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)
        self._device = ShiftableDeviceComponent()
        self._device.name = 'Device_Component'
        self._device.set_bank_buttons(tuple(device_bank_buttons))
        self._device.set_shift_button(self._shift_button)
        self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(self._device)
        detail_view_toggler = DetailViewCntrlComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])
        
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_button'
        nudge_down_button.name = 'Nudge_Down_button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_undo_button(nudge_down_button)
        transport.set_redo_button(nudge_up_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        self._device.set_lock_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        transport.set_tempo_encoder(self._prehear_control)
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)


    def _setup_global_control(self):
        is_momentary = True
        self._global_bank_buttons = []
        self._global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ringed_encoder.set_feedback_delay(-1)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            self._global_param_controls.append(ringed_encoder)
        self._global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')
        for index in range(4):
            self._global_bank_buttons.append(ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            self._global_bank_buttons[-1].name = global_bank_labels[index]
        self._encoder_modes = EncModeSelectorComponent(self._mixer)
        self._encoder_modes.name = 'Track_Control_Modes'
        self._encoder_modes.set_controls(tuple(self._global_param_controls))
        self._encoder_device_modes = EncoderDeviceComponent(self._mixer, self._device, self)
        self._encoder_device_modes.name = 'Alt_Device_Control_Modes'
        self._encoder_eq_modes = EncoderEQComponent(self._mixer, self)
        self._encoder_eq_modes.name = 'EQ_Control_Modes'
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(tuple(self._global_param_controls))
        global_translation_selector.set_mode_buttons(tuple(self._global_bank_buttons))
        encoder_user_modes = EncoderUserModesComponent(self, self._encoder_modes, tuple(self._global_param_controls), tuple(self._global_bank_buttons), self._mixer, self._device, self._encoder_device_modes, self._encoder_eq_modes)
        encoder_user_modes.name = 'Encoder_User_Modes' 
        self._encoder_shift_modes = ShiftableEncoderSelectorComponent(self, tuple(self._global_bank_buttons), encoder_user_modes, self._encoder_modes, self._encoder_eq_modes, self._encoder_device_modes)
        self._encoder_shift_modes.name = 'Encoder_Shift_Modes'
        self._encoder_shift_modes.set_mode_toggle(self._shift_button)  


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

    def _on_track_offset_changed(self):
        self._matrix_modes._on_track_offset_changed()

    def _product_model_id_byte(self):
        return 115

		
コード例 #15
0
class Oxygen_3rd_Gen(ControlSurface):
    """ Script for the 3rd generation of M-Audio's Oxygen controllers """

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        with self.component_guard():
            is_momentary = True
            self._suggested_input_port = 'Oxygen'
            self._suggested_output_port = 'Oxygen'
            self._has_slider_section = True
            self._device_selection_follows_track_selection = True
            self._shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 57)
            self._shift_button.add_value_listener(self._shift_value)
            self._mixer = SpecialMixerComponent(NUM_TRACKS)
            self._mute_solo_buttons = []
            self._track_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 111)
            self._track_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 110)
            self._master_slider = SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 41)
            for index in range(NUM_TRACKS):
                self._mute_solo_buttons.append(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 49 + index))
                self._mixer.channel_strip(index).set_volume_control(SliderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 33 + index))

            self._shift_value(0)
            self._mixer.master_strip().set_volume_control(self._master_slider)
            self._mixer.selected_strip().set_volume_control(None)
            device = DeviceComponent()
            device.set_parameter_controls(tuple([ EncoderElement(MIDI_CC_TYPE, GLOBAL_CHANNEL, 17 + index, Live.MidiMap.MapMode.absolute) for index in range(8) ]))
            self.set_device_component(device)
            ffwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 115)
            rwd_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 114)
            loop_button = ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 113)
            transport = TransportComponent()
            transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 116))
            transport.set_play_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 117))
            transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, GLOBAL_CHANNEL, 118))
            session = SessionComponent(0, 0)
            transport_view_modes = TransportViewModeSelector(transport, session, ffwd_button, rwd_button, loop_button)
        return

    def disconnect(self):
        self._shift_button.remove_value_listener(self._shift_value)
        self._shift_button = None
        ControlSurface.disconnect(self)
        return

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

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:5] == IDENTITY_RESPONSE:
            if midi_bytes[10] == 38:
                self._mixer.master_strip().set_volume_control(None)
                self._mixer.selected_strip().set_volume_control(self._master_slider)
        return

    def _shift_value(self, value):
        raise value in range(128) or AssertionError
        for index in range(NUM_TRACKS):
            if value == 0:
                self._mixer.channel_strip(index).set_solo_button(None)
                self._mixer.channel_strip(index).set_mute_button(self._mute_solo_buttons[index])
                self._mixer.set_bank_buttons(None, None)
                self._mixer.set_select_buttons(self._track_up_button, self._track_down_button)
            else:
                self._mixer.channel_strip(index).set_mute_button(None)
                self._mixer.channel_strip(index).set_solo_button(self._mute_solo_buttons[index])
                self._mixer.set_select_buttons(None, None)
                self._mixer.set_bank_buttons(self._track_up_button, self._track_down_button)

        return
コード例 #16
0
ファイル: AumPC40.py プロジェクト: splenda/monomodular
class AumPC40(APC):
    __doc__ = " Script for Akai's APC40 Controller "

    def __init__(self, c_instance):
        APC.__init__(self, c_instance)
        self._device_selection_follows_track_selection = True

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = FlashingButtonElement(is_momentary,
                                                   MIDI_NOTE_TYPE, 0, 98, self)
        right_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             96, self)
        self._right_button = right_button
        left_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                            97, self)
        self._left_button = left_button
        up_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94,
                                          self)
        self._up_button = up_button
        down_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                            95, self)
        self._down_button = down_button
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        up_button.name = 'Bank_Select_Up_Button'
        down_button.name = 'Bank_Select_Down_Button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        self._matrix = matrix  # added a
        matrix.name = 'Button_Matrix'
        scene_launch_buttons = [
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82))
            for index in range(5)
        ]
        track_stop_buttons = [
            FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52,
                                  self) for index in range(8)
        ]
        self._track_stop_buttons = track_stop_buttons  # added a
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_' + str(
                index) + '_Launch_Button'
        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = 'Track_' + str(
                index) + '_Stop_Button'
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                               track_index, (scene_index + 53),
                                               self)
                button.name = str(track_index) + '_Clip_' + str(
                    scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)
            matrix.add_row(tuple(button_row))
        self._session.set_slot_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button,
                                           right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)
        return None

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._solo_buttons = []  # added a
        self._select_buttons = []  # added a
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            volume_control = MonoEncoderElement2(MIDI_CC_TYPE, track, 7,
                                                 Live.MidiMap.MapMode.absolute,
                                                 'Slider_' + str(track), track,
                                                 self)
            arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
            solo_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                track, 50, self)
            self._solo_buttons.append(solo_button)  # added a
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        49)
            select_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                  track, 51, self)
            self._select_buttons.append(select_button)  # added a
            #volume_control.name = str(track) + '_Volume_Control'
            arm_button.name = str(track) + '_Arm_Button'
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            select_button.name = str(track) + '_Select_Button'
            strip.set_volume_control(volume_control)
            strip.set_arm_button(arm_button)
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_select_button(select_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)
        crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             80)
        self._master_select_button = master_select_button
        prehear_control = EncoderElement(
            MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        master_select_button.name = 'Master_Select_Button'
        prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_crossfader_control(crossfader)
        self._mixer.set_prehear_volume_control(prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._mixer.master_strip().set_select_button(master_select_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button',
                              'Previous_Device_Button', 'Next_Device_Button',
                              'Detail_View_Button', 'Rec_Quantization_Button',
                              'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                             24 + index)
            ringed_encoder = MonoRingedEncoderElement(
                MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute,
                index, self)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)
        device = ShiftableDeviceComponent(self)
        device.name = 'Device_Component'
        device.set_bank_buttons(tuple(device_bank_buttons))
        device.set_shift_button(self._shift_button)
        device.set_parameter_controls(tuple(device_param_controls))
        device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(device)
        detail_view_toggler = DetailViewCntrlComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(
            device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2],
                                                   device_bank_buttons[3])
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        self._transport = transport
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                0, 100, self)
        self._nudge_up_button = nudge_up_button
        nudge_down_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                                  0, 101, self)
        self._nudge_down_button = nudge_down_button
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_Button'
        nudge_down_button.name = 'Nudge_Down_Button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(
            tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        global_bank_buttons = []
        global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                        56 + index)
            ringed_encoder = MonoRingedEncoderElement(
                MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute,
                index + 8, self)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            global_param_controls.append(ringed_encoder)
        global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button',
                              'Send_C_Button')
        for index in range(4):
            global_bank_buttons.append(
                ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            global_bank_buttons[-1].name = global_bank_labels[index]
        encoder_modes = EncModeSelectorComponent(self._mixer)
        encoder_modes.name = 'Track_Control_Modes'
        encoder_modes.set_modes_buttons(global_bank_buttons)
        encoder_modes.set_controls(tuple(global_param_controls))
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(
            tuple(global_param_controls))
        global_translation_selector.set_mode_buttons(
            tuple(global_bank_buttons))

    def _product_model_id_byte(self):
        return 115

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

    def _setup_monomod(self):
        self._host = MonomodComponent(self)
        self._host.name = 'Monomod_Host'
        self.hosts = [self._host]
        self._monomod = ButtonMatrixElement()
        self._monomod.name = 'Monomod'
        for row in range(5):
            button_row = []
            for column in range(8):
                button_row.append(self._matrix.get_button(column, row))
            self._monomod.add_row(tuple(button_row))
        self._monomod.add_row(tuple(self._track_stop_buttons))
        self._monomod.add_row(tuple(self._select_buttons))
        self._monomod.add_row(tuple(self._solo_buttons))
        self._monomod_mode = MonomodModeComponent(self._monomod_mode_update,
                                                  self)
        self._monomod_mode.name = "Monomod_Mode_Component"

    def _monomod_mode_update(self):
        if (self._monomod_mode._mode_index == 0) or (self._host._active_client
                                                     == None):
            self.flash_status = 0
            self._host.set_enabled(False)
            self._host._set_button_matrix(None)
            self._host._set_nav_buttons(None)
            self._host._set_lock_button(None)
            self._host._set_alt_button(None)
            self._host._set_shift_button(None)
            self._monomod.reset()
            self._session.set_track_bank_buttons(self._right_button,
                                                 self._left_button)
            self._session.set_scene_bank_buttons(self._down_button,
                                                 self._up_button)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(
                    self._select_buttons[track])
                self._mixer.channel_strip(track).set_solo_button(
                    self._solo_buttons[track])
            self._transport.set_nudge_buttons(self._nudge_up_button,
                                              self._nudge_down_button)
            self._session.set_enabled(True)
            self._session_zoom._is_zoomed_out = False
            self._session_zoom.set_enabled(True)
            self.request_rebuild_midi_map()
            self._master_select_button.turn_off()

        elif (self._monomod_mode._mode_index == 1):
            self._transport.set_nudge_buttons(None, None)
            for track in range(8):
                self._mixer.channel_strip(track).set_select_button(None)
                self._mixer.channel_strip(track).set_solo_button(None)
            self._session.set_enabled(False)
            self._session_zoom.set_enabled(False)
            self._session.set_track_bank_buttons(None, None)
            self._session.set_scene_bank_buttons(None, None)
            self.flash_status = 1
            self._monomod.reset()
            self._host._set_button_matrix(self._monomod)
            self._host._set_nav_buttons([
                self._up_button, self._down_button, self._left_button,
                self._right_button
            ])
            self._host._set_shift_button(self._shift_button)
            self._host._set_lock_button(self._nudge_up_button)
            self._host._set_alt_button(self._nudge_down_button)
            self._host.set_enabled(True)
            self.request_rebuild_midi_map()
            self._master_select_button.turn_on()

    """m4l bridge"""

    def generate_strip_string(self, display_string):
        #self.log_message(display_string)
        NUM_CHARS_PER_DISPLAY_STRIP = 12
        if (not display_string):
            return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
        if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1))
                and (display_string.endswith('dB') and
                     (display_string.find('.') != -1))):
            display_string = display_string[:-2]
        if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
            for um in [' ', 'i', 'o', 'u', 'e', 'a']:
                while ((len(display_string) >
                        (NUM_CHARS_PER_DISPLAY_STRIP - 1))
                       and (display_string.rfind(um, 1) != -1)):
                    um_pos = display_string.rfind(um, 1)
                    display_string = (display_string[:um_pos] +
                                      display_string[(um_pos + 1):])
        else:
            display_string = display_string.center(
                (NUM_CHARS_PER_DISPLAY_STRIP - 1))
        ret = u''
        for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
            if ((ord(display_string[i]) > 127)
                    or (ord(display_string[i]) < 0)):
                ret += ' '
            else:
                ret += display_string[i]

        ret += ' '
        assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
        return ret

    def notification_to_bridge(self, name, value, sender):
        if isinstance(sender, (MonoRingedEncoderElement, MonoEncoderElement2)):
            self._monobridge._send(sender.name, 'lcd_name',
                                   str(self.generate_strip_string(name)))
            self._monobridge._send(sender.name, 'lcd_value',
                                   str(self.generate_strip_string(value)))

    def touched(self):
        if self._touched is 0:
            self._monobridge._send('touch', 'on')
            self.schedule_message(2, self.check_touch)
        self._touched += 1

    def check_touch(self):
        if self._touched > 5:
            self._touched = 5
        elif self._touched > 0:
            self._touched -= 1
        if self._touched is 0:
            self._monobridge._send('touch', 'off')
        else:
            self.schedule_message(2, self.check_touch)

    def get_clip_names(self):
        clip_names = []
        for scene in self._session._scenes:
            for clip_slot in scene._clip_slots:
                if clip_slot.has_clip() is True:
                    clip_names.append(clip_slot._clip_slot)  ##.clip.name)
                    return clip_slot._clip_slot
                    ##self.log_message(str(clip_slot._clip_slot.clip.name))
        return clip_names

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

        for callback in self._timer_callbacks:
            callback()
        self._timer = (self._timer + 1) % 256
        self.flash()

    def flash(self):
        if (self.flash_status > 0):
            for row in range(8):
                for column in range(8):
                    button = self._monomod.get_button(column, row)
                    if (button._flash_state > 0):
                        button.flash(self._timer)
コード例 #17
0
ファイル: LaunchControl.py プロジェクト: cce/buttons
class LaunchControl(ControlSurface):

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

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

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

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

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

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

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

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

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

        self._on_track_offset.subject = self._session

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

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

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

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

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

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

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

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

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

    def _is_user_mode_message(self, midi_bytes):
        """
        True if midi_byes refer to a mode change, but none of the three
        predefined Live modes
        """
        return midi_bytes[:7] == Sysex.MODE_CHANGE_PREFIX and midi_bytes not in SYSEX_MODE_MAP
コード例 #18
0
class Novation_Impulse2(ControlSurface):
    """ Script for Novation's Impulse keyboards """
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self.c_instance = c_instance
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'Impulse'
            self._suggested_output_port = 'Impulse'
            self._has_sliders = True
            self._current_midi_map = None
            self._display_reset_delay = -1
            self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0,
                                               39)
            self._preview_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0,
                                                 41)
            self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 8)
            self._shift_button.name = 'Shift_Button'
            self._master_slider.name = 'Master_Volume_Control'
            self._master_slider.add_value_listener(self._slider_value,
                                                   identify_sender=True)
            self._preview_button.add_value_listener(self._preview_value)
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_name_display()
            device_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1,
                                          10)
            mixer_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 1, 9)
            device_button.name = 'Encoder_Device_Mode'
            mixer_button.name = 'Encoder_Mixer_Mode'
            self._encoder_modes = EncoderModeSelector(self._device_component,
                                                      self._mixer,
                                                      self._next_bank_button,
                                                      self._prev_bank_button,
                                                      self._encoders)
            self._encoder_modes.set_device_mixer_buttons(
                device_button, mixer_button)
            self._string_to_display = None
            self._shift_pressed = False
            self._shift_button.add_value_listener(self._shift_value)

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

    def refresh_state(self):
        ControlSurface.refresh_state(self)
        self.schedule_message(3, self._send_midi,
                              SYSEX_START + (6, 1, 1, 1, 247))

    def handle_sysex(self, midi_bytes):
        if midi_bytes[0:-2] == SYSEX_START + (7, ) and midi_bytes[-2] != 0:
            self._has_sliders = midi_bytes[-2] != 25
            self.schedule_message(1, self._show_startup_message)
            for control in self.controls:
                if isinstance(control, InputControlElement):
                    control.clear_send_cache()

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

            if self._has_sliders:
                self._mixer.master_strip().set_volume_control(
                    self._master_slider)
                self._mixer.update()
            else:
                self._mixer.master_strip().set_volume_control(None)
                self._mixer.selected_strip().set_volume_control(
                    self._master_slider)
                for index in range(len(self._sliders)):
                    self._mixer.channel_strip(index).set_volume_control(None)
                    slider = self._sliders[index]
                    slider.release_parameter()
                    if slider.value_has_listener(self._slider_value):
                        slider.remove_value_listener(self._slider_value)

            self._encoder_modes.set_provide_volume_mode(not self._has_sliders)
            self.request_rebuild_midi_map()

    def disconnect(self):
        self.log('starting disconnect 1')
        self._name_display_data_source.set_display_string('  ')
        for encoder in self._encoders:
            encoder.remove_value_listener(self._encoder_value)

        self._master_slider.remove_value_listener(self._slider_value)
        if self._has_sliders:
            for slider in tuple(self._sliders):
                slider.remove_value_listener(self._slider_value)

        for button in self._strip_buttons:
            button.remove_value_listener(self._mixer_button_value)

        self._preview_button.remove_value_listener(self._preview_value)
        self.log('starting disconnect 3')
        ControlSurface.disconnect(self)
        self.log('starting disconnect 3')
        self._encoders = None
        self._sliders = None
        self._strip_buttons = None
        self._master_slider = None
        self._current_midi_map = None
        self._name_display = None
        self._prev_bank_button = None
        self._next_bank_button = None
        self._encoder_modes = None
        self._transport_view_modes = None
        self.log('starting disconnect 4')
        self._send_midi(SYSEX_START + (6, 0, 0, 0, 247))
        self.log('starting disconnect 5')

        if self._shift_button != None:
            self._shift_button.remove_value_listener(self._shift_value)
            self._shift_button = None
        self.log('starting disconnect 6')

    def build_midi_map(self, midi_map_handle):
        self._current_midi_map = midi_map_handle
        ControlSurface.build_midi_map(self, midi_map_handle)

    def update_display(self):
        ControlSurface.update_display(self)
        if self._string_to_display != None:
            self._name_display_data_source.set_display_string(
                self._string_to_display)
            self._string_to_display = None
        if self._display_reset_delay >= 0:
            self._display_reset_delay -= 1
            if self._display_reset_delay == -1:
                self._show_current_track_name()

    def _setup_mixer(self):
        mute_solo_flip_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE,
                                              0, 34)
        self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0,
                                              37)
        self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0,
                                              38)
        self._strip_buttons = []
        mute_solo_flip_button.name = 'Mute_Solo_Flip_Button'
        self._next_nav_button.name = 'Next_Track_Button'
        self._prev_nav_button.name = 'Prev_Track_Button'
        self._mixer = SpecialMixerComponent(8, self.c_instance)
        self._mixer.name = 'Mixer'
        self._mixer.set_select_buttons(self._next_nav_button,
                                       self._prev_nav_button)
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.master_strip().set_volume_control(self._master_slider)
        self._sliders = []
        for index in range(8):
            strip = self._mixer.channel_strip(index)
            strip.name = 'Channel_Strip_' + str(index)
            strip.set_invert_mute_feedback(True)
            self._sliders.append(SliderElement(MIDI_CC_TYPE, 0, index))
            self._sliders[-1].name = str(index) + '_Volume_Control'
            self._sliders[-1].set_feedback_delay(-1)
            self._sliders[-1].add_value_listener(self._slider_value,
                                                 identify_sender=True)
            strip.set_volume_control(self._sliders[-1])
            self._strip_buttons.append(
                ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + index))
            self._strip_buttons[-1].name = str(index) + '_Mute_Button'
            self._strip_buttons[-1].add_value_listener(
                self._mixer_button_value, identify_sender=True)

        self._mixer.master_strip().set_mute_button(
            ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1, 17))
        self._mixer.set_strip_mute_solo_buttons(tuple(self._strip_buttons),
                                                mute_solo_flip_button)
        #self._mixer.set_shift_button(self._shift_button)
        self._mixer.updateMixerButtons()

        self._button9 = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 9 + 8)

    def _setup_session(self):
        num_pads = len(PAD_TRANSLATIONS)
        self._session = SessionComponent(8, 0)
        self._session.name = 'Session_Control'
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.set_mixer(self._mixer)
        # for ableton 9.1.1 and lower
        #self._session.set_track_banking_increment(num_pads)
        #self._session.set_track_bank_buttons(ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 35), ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE, 0, 36))
        # for ableton 9.1.1 and higher
        self._track_left_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE,
                                                0, 36)
        self._track_right_button = ButtonElement(not IS_MOMENTARY,
                                                 MIDI_CC_TYPE, 0, 35)
        self._session.set_page_left_button(self._track_left_button)
        self._session.set_page_right_button(self._track_right_button)

        pads = []
        for index in range(num_pads):
            pads.append(
                ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index))
            pads[-1].name = 'Pad_' + str(index)
            clip_slot = self._session.selected_scene().clip_slot(index)
            clip_slot.set_triggered_to_play_value(GREEN_BLINK)
            clip_slot.set_triggered_to_record_value(RED_BLINK)
            clip_slot.set_stopped_value(AMBER_FULL)
            clip_slot.set_started_value(GREEN_FULL)
            clip_slot.set_recording_value(RED_FULL)
            clip_slot.set_launch_button(pads[-1])
            clip_slot.name = str(index) + '_Selected_Clip_Slot'

    def _setup_transport(self):
        rwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 27)
        ffwd_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 28)
        stop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 29)
        play_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 30)
        loop_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 31)
        rec_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 32)
        ffwd_button.name = 'FFwd_Button'
        rwd_button.name = 'Rwd_Button'
        loop_button.name = 'Loop_Button'
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        rec_button.name = 'Record_Button'
        self._transport = ShiftableTransportComponent(self.c_instance,
                                                      self._session, self,
                                                      ffwd_button, rwd_button)
        self._transport.name = 'Transport'
        self._transport.set_stop_buttonOnInit(stop_button)
        self._transport.set_play_button(play_button)
        self._transport.set_record_buttonOnInit(rec_button)
        #        self._transport.set_shift_button(self._shift_button)
        self._transport.set_mixer9_button(self._button9)
        self._transport_view_modes = TransportViewModeSelector(
            self.c_instance, self._transport, self._session, ffwd_button,
            rwd_button, loop_button)
        self._transport_view_modes.name = 'Transport_View_Modes'

    def _setup_device(self):
        encoders = []
        for index in range(8):
            encoders.append(
                PeekableEncoderElement(
                    MIDI_CC_TYPE, 1, index,
                    Live.MidiMap.MapMode.relative_binary_offset))
            encoders[-1].set_feedback_delay(-1)
            encoders[-1].add_value_listener(self._encoder_value,
                                            identify_sender=True)
            encoders[-1].name = 'Device_Control_' + str(index)

        self._encoders = tuple(encoders)
        self._prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1,
                                               12)
        self._next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1,
                                               11)
        self._prev_bank_button.name = 'Device_Bank_Down_Button'
        self._next_bank_button.name = 'Device_Bank_Up_Button'
        device = DeviceComponent()
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)
        device.set_bank_nav_buttons(self._prev_bank_button,
                                    self._next_bank_button)

    def _setup_name_display(self):
        self._name_display = PhysicalDisplayElement(16, 1)
        self._name_display.name = 'Display'
        self._name_display.set_message_parts(SYSEX_START + (8, ), (247, ))
        self._name_display_data_source = DisplayDataSource()
        self._name_display.segment(0).set_data_source(
            self._name_display_data_source)

    def _encoder_value(self, value, sender):
        if not sender in self._encoders:
            raise AssertionError
        if not value in range(128):
            raise AssertionError
#        display_string = self._device_component.is_enabled() and ' - '
#        display_string = sender.mapped_parameter() != None and sender.mapped_parameter().name
        display_string = ''
        if self._device_component.is_enabled():
            #            display_string = sender.name
            #            track = self.song().view.selected_track
            #            display_string = str(list(tracks).index(track) + 1)
            pass
        if (sender.mapped_parameter() != None):
            #            display_string = display_string + '-'
            display_string = display_string + sender.mapped_parameter().name
        self._set_string_to_display(display_string)

    def _slider_value(self, value, sender):
        self.log('_slider_value ' + str(value) + ' ' + str(sender))
        if not sender in tuple(self._sliders) + (self._master_slider, ):
            raise AssertionError
        if not value in range(128):
            raise AssertionError
        if self._mixer.is_enabled():
            display_string = ' - '
            master = self.song().master_track
            tracks = self.song().tracks
            returns = self.song().return_tracks
            track = None
            if sender.mapped_parameter() != None:
                self.log('1')
                if sender == self._master_slider:
                    self.log('2')
                    #                    track = self._has_sliders and master
                    if self._has_sliders:
                        track = master
                    else:
                        self.log('2.1')
                        track = self.song().view.selected_track
                else:
                    self.log('3')
                    track = self._mixer.channel_strip(
                        self._sliders.index(sender))._track
            else:
                self.log('4')
                track = self.song().view.selected_track
            self.log('track=' + str(track))
            if track == master:
                display_string = 'Master'
            elif track in tracks:
                display_string = str(list(tracks).index(track) + 1)
            elif track in returns:
                display_string = str(
                    chr(ord('A') + list(returns).index(track)))
            else:
                #            raise False or AssertionError
                raise AssertionError
            display_string += ' Volume'
            self._set_string_to_display(display_string)

    def _mixer_button_value(self, value, sender):
        if not value in range(128):
            raise AssertionError
        #if self._mixer.is_enabled() and value > 0:
        if self._mixer.is_enabled():
            strip = self._mixer.channel_strip(
                self._strip_buttons.index(sender))
            #self._string_to_display = strip != None and None
            self._name_display.segment(0).set_data_source(
                strip.track_name_data_source())
            self._name_display.update()
            self._display_reset_delay = STANDARD_DISPLAY_DELAY
        else:
            self._set_string_to_display(' - ')

    def _preview_value(self, value):
        if not value in range(128):
            raise AssertionError
        for encoder in self._encoders:
            encoder.set_peek_mode(value > 0)

    def _show_current_track_name(self):
        if self._name_display != None and self._mixer != None:
            self._string_to_display = None
            self._name_display.segment(0).set_data_source(
                self._mixer.selected_strip().track_name_data_source())
            self._name_display.update()

    def _show_startup_message(self):
        self._name_display.display_message('LIVE')
        self._display_reset_delay = INITIAL_DISPLAY_DELAY

    def _set_string_to_display(self, string_to_display):
        if not isinstance(string_to_display, (str, unicode)):
            raise AssertionError
        self._name_display.segment(0).set_data_source(
            self._name_display_data_source)
        self._string_to_display = string_to_display
        self._display_reset_delay = STANDARD_DISPLAY_DELAY

    def _on_selected_track_changed(self):
        self.log('_on_selected_track_changed')
        ControlSurface._on_selected_track_changed(self)
        self._show_current_track_name()
        #all_tracks = self._has_sliders or self._session.tracks_to_use()
        all_tracks2 = self._session.tracks_to_use()
        selected_track = self.song().view.selected_track
        num_strips = self._session.width()
        if selected_track in all_tracks2:
            track_index = list(all_tracks2).index(selected_track)
            self.log('track_index ' + str(track_index))
            new_offset = track_index - track_index % num_strips
            self.log('new_offset ' + str(new_offset))
            if not new_offset / num_strips == int(new_offset / num_strips):
                raise AssertionError
            self._session.set_offsets(new_offset, self._session.scene_offset())

    def _shift_value(self, value):
        self.log("root shift handler")
        if not self._shift_button != None:
            raise AssertionError
        if not value in range(128):
            raise AssertionError
        self.log("root shift handler 2")
        self._shift_pressed = value > 0
        # calling other handlers
        self._mixer._shift_value(value)
        self._transport._shift_value(value)
        self._transport_view_modes._shift_value(value)

        #clip stop
        self.log("root shift handler 3")
        num_pads = len(PAD_TRANSLATIONS)
        pads = []
        for index in range(num_pads):
            pads.append(
                ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index))
            pads[-1].name = 'Pad_' + str(index)
            clip_slot = self._session.selected_scene().clip_slot(index)
            if self._shift_pressed:
                clip_slot.set_launch_button(None)
            else:
                clip_slot.set_launch_button(pads[index])
        if self._shift_pressed:
            self._session.set_stop_track_clip_buttons(tuple(pads))
        else:
            self._session.set_stop_track_clip_buttons(None)

        self.log("root shift handler 4")

    def log(self, message):
        pass
コード例 #19
0
class LaunchControl(ControlSurface):

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

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

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

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

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

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

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

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

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

        self._on_track_offset.subject = self._session

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

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

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

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

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

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

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

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

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

    def _is_user_mode_message(self, midi_bytes):
        """
        True if midi_byes refer to a mode change, but none of the three
        predefined Live modes
        """
        return midi_bytes[:7] == Sysex.MODE_CHANGE_PREFIX and midi_bytes not in SYSEX_MODE_MAP
コード例 #20
0
ファイル: FCB1020.py プロジェクト: ajasver/MidiScripts
class FCB1020(ControlSurface):
    __doc__ = " Script for FCB1010 in APC emulation mode "

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

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


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


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


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


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


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

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


    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(8):
            device_param_controls.append(self._ctrl_map[PARAMCONTROL[index]])
            device_bank_buttons.append(self._note_map[DEVICEBANK[index]])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map[DEVICEONOFF])
        self._device.set_bank_nav_buttons(self._note_map[DEVICEBANKNAVLEFT], self._note_map[DEVICEBANKNAVRIGHT])
        self._device.set_lock_button(self._note_map[DEVICELOCK])
        self.set_device_component(self._device)

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

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


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


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


    def _load_MIDI_map(self):
        is_momentary = True
        for note in range(128):
            button = ButtonElement(is_momentary, MESSAGETYPE, BUTTONCHANNEL, note)
            button.name = 'Note_' + str(note)
            self._note_map.append(button)
        self._note_map.append(None) #add None to the end of the list, selectable with [-1]
        if MESSAGETYPE == MIDI_CC_TYPE and BUTTONCHANNEL == SLIDERCHANNEL:
            for ctrl in range(128):
                self._ctrl_map.append(None)
        else:
            for ctrl in range(128):
                control = SliderElement(MIDI_CC_TYPE, SLIDERCHANNEL, ctrl)
                control.name = 'Ctrl_' + str(ctrl)
                self._ctrl_map.append(control)
            self._ctrl_map.append(None)
コード例 #21
0
ファイル: AumPC20.py プロジェクト: splenda/monomodular
class AumPC20(APC):
	__doc__ = " Script for Akai's APC20 Controller "


	def __init__(self, c_instance):
		self._shift_modes = None
		APC.__init__(self, c_instance)
		return None
	

	def disconnect(self):
		self._shift_modes = None
		APC.disconnect(self)
		return None
	

	def _activate_combination_mode(self, track_offset, support_devices):
		APC._activate_combination_mode(self, track_offset, support_devices)
		if support_devices:
			self._shift_modes.invert_assignment()
	

	def _setup_session_control(self):
		is_momentary = True
		self._shift_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81, self)		   
		self._session = APCSessionComponent(8, 5)
		self._session.name = 'Session_Control'
		self._matrix = ButtonMatrixElement()
		self._matrix.name = 'Button_Matrix'
		scene_launch_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82), self) for index in range(5) ]
		self._scene_launch_buttons = scene_launch_buttons
		track_stop_buttons = [ FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52, self) for index in range(8) ]
		self._track_stop_buttons = track_stop_buttons
		for index in range(len(scene_launch_buttons)):
			scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
		for index in range(len(track_stop_buttons)):
			track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
		self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
		self._session.set_stop_track_clip_value(2)
		for scene_index in range(5):
			scene = self._session.scene(scene_index)
			scene.name = 'Scene_' + str(scene_index)
			button_row = []
			scene.set_launch_button(scene_launch_buttons[scene_index])
			scene.set_triggered_value(2)
			for track_index in range(8):
				button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53), self)
				button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
				button_row.append(button)
				clip_slot = scene.clip_slot(track_index)
				clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
				clip_slot.set_triggered_to_play_value(2)
				clip_slot.set_triggered_to_record_value(4)
				clip_slot.set_stopped_value(5)
				clip_slot.set_started_value(1)
				clip_slot.set_recording_value(3)
				clip_slot.set_launch_button(button)

			self._matrix.add_row(tuple(button_row))
		self._session.selected_scene().name = 'Selected_Scene'
		self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
		self._session_zoom = ShiftableZoomingComponent(self._session, tuple(track_stop_buttons))
		self._session_zoom.name = 'Session_Overview'
		self._session_zoom.set_button_matrix(self._matrix)
		self._session_zoom.set_zoom_button(self._shift_button)
		self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
		self._session_zoom.set_stopped_value(3)
		self._session_zoom.set_selected_value(5)
	

	def _setup_mixer_control(self):
		is_momentary = True
		self._mixer = SpecialMixerComponent(8)
		self._mixer.name = 'Mixer'
		self._mixer.master_strip().name = 'Master_Channel_Strip'
		self._mixer.selected_strip().name = 'Selected_Channel_Strip'
		self._solo_buttons = []
		for track in range(8):
			strip = self._mixer.channel_strip(track)
			strip.name = 'Channel_Strip_' + str(track)
			solo_button = FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50, self)
			self._solo_buttons.append(solo_button)
			mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
			solo_button.name = str(track) + '_Solo_Button'
			mute_button.name = str(track) + '_Mute_Button'
			strip.set_solo_button(solo_button)
			strip.set_mute_button(mute_button)
			strip.set_shift_button(self._shift_button)
			strip.set_invert_mute_feedback(True)
		master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
		prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
		master_volume_control.name = 'Master_Volume_Control'
		prehear_control.name = 'Prehear_Volume_Control'
		self._mixer.set_prehear_volume_control(prehear_control)
		self._mixer.master_strip().set_volume_control(master_volume_control)
	

	def _setup_custom_components(self):
		is_momentary = True
		master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
		self._master_select_button = master_select_button
		master_select_button.name = 'Master_Select_Button'
		select_buttons = []
		self._select_buttons = []
		arm_buttons = []
		sliders = []
		for track in range(8):
			select_buttons.append(FlashingButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51, self))
			self._select_buttons.append(select_buttons[track])
			arm_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
			if track is 7:
				self._user3 = arm_buttons[track]
			sliders.append(MonoEncoderElement2(MIDI_CC_TYPE, track, 7, Live.MidiMap.MapMode.absolute, 'Slider_' + str(track), track, self))
			#sliders.append(MonoEncoderElement2(MIDI_CC_TYPE, track, 7))
			select_buttons[-1].name = str(track) + '_Select_Button'
			arm_buttons[-1].name = str(track) + '_Arm_Button'
			#sliders[-1].name = str(track) + '_Volume_Control'
		transport = TransportComponent()
		transport.name = 'Transport'
		slider_modes = SliderModesComponent(self._mixer, tuple(sliders))
		slider_modes.name = 'Slider_Modes'
		self._shift_modes = ShiftableSelectorComponent(tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, transport, slider_modes, self._send_introduction_message, self)
		self._shift_modes.name = 'Shift_Modes'
		self._shift_modes.set_mode_toggle(self._shift_button)
	

	def _product_model_id_byte(self):
		return 123
	

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

	def _setup_monomod(self):
		self._host = MonomodComponent(self)
		self._host.name = 'Monomod_Host'
		self._host._set_nav_buttons = self._mod_set_nav_buttons(self._host)
		self._host._update_nav_buttons = self._mod_update_nav_buttons(self._host)
		self._host._set_nav_buttons = self._mod_set_nav_buttons(self._host)
		self.hosts = [self._host]
		self._monomod = ButtonMatrixElement()
		self._monomod.name = 'Monomod'
		for row in range(5):
			button_row = []
			for column in range(8):
				button_row.append(self._matrix.get_button(column, row))
			self._monomod.add_row(tuple(button_row))
		self._monomod.add_row(tuple(self._track_stop_buttons))
		self._monomod.add_row(tuple(self._select_buttons))
		self._monomod.add_row(tuple(self._solo_buttons))
		self._monomod_mode = MonomodModeComponent(self._monomod_mode_update, self)
		self._monomod_mode.name = "Monomod_Mode_Component"
	

	def _monomod_mode_update(self):
		if(self._monomod_mode._mode_index == 0) or (self._host._active_client == None):
			self.flash_status = 0
			self._host.set_enabled(False)
			self._host._set_button_matrix(None)
			#self._host._set_nav_buttons(None)
			self._host._set_lock_button(None)
			self._host._set_alt_button(None)
			self._host._set_shift_button(None)
			self._host._set_nav_buttons(None)
			self._scene_launch_buttons[2].set_on_off_values(127, 0)	
			self._scene_launch_buttons[3].set_on_off_values(127, 0)	
			self._monomod.reset()
			self._shift_modes.set_enabled(True)
			#self._session.set_track_bank_buttons(self._right_button, self._left_button)
			#self._session.set_scene_bank_buttons(self._down_button, self._up_button)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(self._select_buttons[track])
				self._mixer.channel_strip(track).set_solo_button(self._solo_buttons[track])
			#self._transport.set_nudge_buttons(self._nudge_up_button, self._nudge_down_button)
			self._session.set_enabled(True)
			self._session_zoom._is_zoomed_out = False
			self._session_zoom.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_off()
			
		elif(self._monomod_mode._mode_index == 1):
			if self._shift_modes._note_mode_active is True:
				self._shift_modes._mode_callback(ABLETON_MODE)
				self._shift_modes._note_mode_active = False
				self._session_zoom.set_ignore_buttons(False)
				self._shift_modes._transport.update()
				self._shift_modes._on_note_mode_changed()
			#self._transport.set_nudge_buttons(None, None)
			self._shift_modes.set_enabled(False)
			for track in range(8):
				self._mixer.channel_strip(track).set_select_button(None)
				self._mixer.channel_strip(track).set_solo_button(None)
			for scene in range(5):
				self._scene_launch_buttons[scene].turn_off()
			self._session.set_enabled(False)
			self._session_zoom.set_enabled(False)
			#self._session.set_track_bank_buttons(None, None)
			#self._session.set_scene_bank_buttons(None, None)
			self.flash_status = 1
			self._monomod.reset()
			self._host._set_button_matrix(self._monomod)
			#self._host._set_nav_buttons([self._up_button, self._down_button, self._left_button, self._right_button])
			self._host._set_shift_button(self._shift_button)
			self._host._set_lock_button(self._scene_launch_buttons[0])
			self._host._set_alt_button(self._scene_launch_buttons[1])
			self._host._set_nav_buttons([self._scene_launch_buttons[2], self._scene_launch_buttons[3]])
			self._host.set_enabled(True)
			self.request_rebuild_midi_map()
			self._master_select_button.turn_on()
	

	"""m4l bridge"""
	def generate_strip_string(self, display_string):
		#self.log_message(display_string)
		NUM_CHARS_PER_DISPLAY_STRIP = 12
		if (not display_string):
			return (' ' * NUM_CHARS_PER_DISPLAY_STRIP)
		if ((len(display_string.strip()) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.endswith('dB') and (display_string.find('.') != -1))):
			display_string = display_string[:-2]
		if (len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			for um in [' ',
			 'i',
			 'o',
			 'u',
			 'e',
			 'a']:
				while ((len(display_string) > (NUM_CHARS_PER_DISPLAY_STRIP - 1)) and (display_string.rfind(um, 1) != -1)):
					um_pos = display_string.rfind(um, 1)
					display_string = (display_string[:um_pos] + display_string[(um_pos + 1):])
		else:
			display_string = display_string.center((NUM_CHARS_PER_DISPLAY_STRIP - 1))
		ret = u''
		for i in range((NUM_CHARS_PER_DISPLAY_STRIP - 1)):
			if ((ord(display_string[i]) > 127) or (ord(display_string[i]) < 0)):
				ret += ' '
			else:
				ret += display_string[i]

		ret += ' '
		assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP)
		return ret
	

	def notification_to_bridge(self, name, value, sender):
		if isinstance(sender, MonoEncoderElement2):
			self._monobridge._send(sender.name, 'lcd_name', str(self.generate_strip_string(name)))
			self._monobridge._send(sender.name, 'lcd_value', str(self.generate_strip_string(value)))
	

	def touched(self):
		if self._touched is 0:
			self._monobridge._send('touch', 'on')
			self.schedule_message(2, self.check_touch)
		self._touched +=1
	

	def check_touch(self):
		if self._touched > 5:
			self._touched = 5
		elif self._touched > 0:
			self._touched -= 1
		if self._touched is 0:
			self._monobridge._send('touch', 'off')
		else:
			self.schedule_message(2, self.check_touch)
	

	def get_clip_names(self):
		clip_names = []
		for scene in self._session._scenes:
			for clip_slot in scene._clip_slots:
				if clip_slot.has_clip() is True:
					clip_names.append(clip_slot._clip_slot)##.clip.name)
					return clip_slot._clip_slot
					##self.log_message(str(clip_slot._clip_slot.clip.name))
		return clip_names
	



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

		for callback in self._timer_callbacks:
			callback()
		self._timer = (self._timer + 1) % 256
		self.flash()
	

	def flash(self):
		if(self.flash_status > 0):
			for row in range(8):
				for column in range(8):
					button = self._monomod.get_button(column, row)
					if(button._flash_state > 0):
						button.flash(self._timer)
	


### Mod Overrides ####

	def _mod_set_nav_buttons(self, mod):	
		def _set_nav_buttons(buttons):
			if mod._nav_buttons != None:
				mod._nav_buttons[0].remove_value_listener(mod._nav_up_value)
				mod._nav_buttons[1].remove_value_listener(mod._nav_down_value)
			mod._nav_buttons = buttons
			if buttons != None:
				assert len(buttons) == 2
				for button in buttons:
					assert isinstance(button, FlashingButtonElement)
				mod._nav_buttons[0].set_on_off_values(8, 2)	
				mod._nav_buttons[0].add_value_listener(mod._nav_up_value)
				mod._nav_buttons[1].set_on_off_values(8, 2)	
				mod._nav_buttons[1].add_value_listener(mod._nav_down_value)
		return _set_nav_buttons
	

	def _mod_update_nav_buttons(self, mod):
		def _update_nav_buttons():
			if mod._nav_buttons != None:
				if(mod._y > 0):
					mod._nav_buttons[0].turn_on()
				else:
					mod._nav_buttons[0].turn_off()
				if(mod._y < 8):
					mod._nav_buttons[1].turn_on()
				else:
					mod._nav_buttons[1].turn_off() 
		return _update_nav_buttons
コード例 #22
0
class APC40plus22(APC):
    __doc__ = " Script for Akai's APC40 Controller with extra features added "
    def __init__(self, c_instance):
        self._c_instance = c_instance
        self._shift_modes = None #added from APC20 script
        self._encoder_modes = None #added
        self._slider_modes = None #added
        APC.__init__(self, c_instance)
        self.show_message("APC40_22 script loaded")
        
        # Disabling the scene launch buttons and assigning them to the first 5 repeats on Master
        self._device_buttons = []
        self.setup_device_buttons()

    def disconnect(self): #this is from the APC20 script
        for button in self._device_buttons:
            button.remove_value_listener(self._device_toggle)
        self._device_buttons = None
        self._shift_modes = None
        self._encoder_modes = None
        self._slider_modes = None
        APC.disconnect(self)        

    def setup_device_buttons(self):
      repeat = RepeatComponent(self)
      repeat.set_shift_button(self._shift_button)

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)        
        right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        up_button.name = 'Bank_Select_Up_Button'
        down_button.name = 'Bank_Select_Down_Button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        self._matrix = ButtonMatrixElement() #was: matrix = ButtonMatrixElement()
        self._matrix.name = 'Button_Matrix' #was: matrix.name = 'Button_Matrix'
        scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5) ]
        #self._track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
        self._track_stop_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
        for index in range(len(self._track_stop_buttons)):
            self._track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(self._track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                #button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53)) 
                button = ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53)) #use Launchpad configurable button instead
                button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(3)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(5)
                clip_slot.set_launch_button(button)
            self._matrix.add_row(tuple(button_row)) #matrix.add_row(tuple(button_row))

        # Removing the launch selected clip footpedal option
        #self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))


        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session) #use APC20 Zooming instead      
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(self._matrix) #was: self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button) #set in MatrixModesComponent instead
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)
        return None

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(self, 8) #added self for parent
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
        master_select_button.name = 'Master_Select_Button'
        self._mixer.master_strip().set_select_button(master_select_button) #set in ShiftableSelectorComponent instead if used for Note Mode
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        select_buttons = [] #added
        arm_buttons = [] #added
        sliders = [] #added     
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            #volume_control = SliderElement(MIDI_CC_TYPE, track, 7) #set in ShiftableSelectorComponent instead
            #arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48) #see below
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
            solo_button.name = str(track) + '_Solo_Button'
            strip.set_solo_button(solo_button)

            if track < 4:
              mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
              mute_button.name = str(track) + '_Mute_Button'
              strip.set_mute_button(mute_button)
              strip.set_invert_mute_feedback(True)

            strip.set_shift_button(self._shift_button)
            select_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51)) #added
            select_buttons[-1].name = str(track) + '_Select_Button' #added            
            #strip.set_select_button(select_buttons[-1]) #added 
            arm_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)) #added
            arm_buttons[-1].name = str(track) + '_Arm_Button' #added
            sliders.append(SliderElement(MIDI_CC_TYPE, track, 7)) #added
            sliders[-1].name = str(track) + '_Volume_Control' #added

        self._crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        self._prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        self._crossfader.name = 'Crossfader' #not used in APC20
        master_volume_control.name = 'Master_Volume_Control'
        self._prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_shift_button(self._shift_button) #added for shifting prehear
        self._mixer.set_crossfader_control(self._crossfader) #not used in APC20
        self._mixer.set_prehear_volume_control(self._prehear_control) #functionality overridden in SpecialMixerComponent
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._slider_modes = SliderModesComponent(self._mixer, tuple(sliders)) #added from APC20 script
        self._slider_modes.name = 'Slider_Modes' #added from APC20 script
        matrix_modes = MatrixModesComponent(self._matrix, self._session, self._session_zoom, tuple(self._track_stop_buttons), self) #added new
        matrix_modes.name = 'Matrix_Modes' #added new
        # Original method args for ShiftableSelectorComponent: (self, select_buttons, master_button, arm_buttons, matrix, session, zooming, mixer, transport, slider_modes, mode_callback)
        #self._shift_modes = ShiftableSelectorComponent(tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, transport, slider_modes, self._send_introduction_message)
        self._shift_modes = ShiftableSelectorComponent(self, tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, self._slider_modes, matrix_modes) #, self._send_introduction_message) #also added self for _parent
        self._shift_modes.name = 'Shift_Modes'
        self._shift_modes.set_mode_toggle(self._shift_button)

    def _setup_custom_components(self):
        self._setup_looper_control()
        self._setup_device_and_transport_control()
        self._setup_global_control()    

    def _setup_looper_control(self):
        is_momentary = True
        #pedal = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67)
        loop_on = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 4, 50)
        loop_start = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 5, 50)
        halve = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 6, 50)
        double = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 7, 50)
        looper = LooperComponent(self)
        looper.set_shift_button(self._shift_button)
        looper.set_loop_toggle_button(loop_on)
        looper.set_loop_start_button(loop_start)
        looper.set_loop_double_button(double) 
        looper.set_loop_halve_button(halve) 

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Device_Lock_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.set_feedback_delay(-1) #added from Axiom DirectLink example
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)
        self._device = ShiftableDeviceComponent()
        self._device.name = 'Device_Component'
        self._device.set_bank_buttons(tuple(device_bank_buttons))
        self._device.set_shift_button(self._shift_button)
        self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(self._device)
        detail_view_toggler = DetailViewControllerComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_Button'
        nudge_down_button.name = 'Nudge_Down_Button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_undo_button(nudge_down_button) #shifted nudge
        transport.set_redo_button(nudge_up_button) #shifted nudge
        transport.set_tap_tempo_button(tap_tempo_button)
        self._device.set_lock_button(tap_tempo_button) #shifted tap tempo
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        transport.set_tempo_encoder(self._prehear_control) #shifted prehear
        bank_button_translator = ShiftableTranslatorComponent()
        bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)


    def _setup_global_control(self):
        is_momentary = True
        self._global_bank_buttons = []
        self._global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ringed_encoder.set_feedback_delay(-1)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            self._global_param_controls.append(ringed_encoder)
        self._global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')
        for index in range(4):
            self._global_bank_buttons.append(ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))#(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            self._global_bank_buttons[-1].name = global_bank_labels[index]
        self._encoder_modes = EncoderMixerModeSelectorComponent(self._mixer)
        self._encoder_modes.name = 'Track_Control_Modes'
        #self._encoder_modes.set_modes_buttons(self._global_bank_buttons) # set in ShiftableEncoderSelectorComponent
        self._encoder_modes.set_controls(tuple(self._global_param_controls))
        #self._encoder_device_modes = EncoderDeviceModeSelectorComponent(self._mixer, self._device) #new
        self._encoder_device_modes = EncoderDeviceComponent(self._mixer, self._device, self)
        self._encoder_device_modes.name = 'Alt_Device_Control_Modes' #new
        self._encoder_eq_modes = EncoderEQComponent(self._mixer, self)#EncoderEQModeSelectorComponent(self._mixer) #new
        self._encoder_eq_modes.name = 'EQ_Control_Modes' #new
        global_translation_selector = ChannelTranslationSelector() #translate track encoders to channels 1 through 4, based on button selection (pan = 1, send A = 2, send B = 3, send C = 4)
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(tuple(self._global_param_controls))
        global_translation_selector.set_mode_buttons(tuple(self._global_bank_buttons))
        encoder_user_modes = EncoderUserModesComponent(self, self._encoder_modes, tuple(self._global_param_controls), tuple(self._global_bank_buttons), self._mixer, self._device, self._encoder_device_modes, self._encoder_eq_modes) #self._mixer, tuple(sliders)) #added
        encoder_user_modes.name = 'Encoder_User_Modes' #added   
        self._encoder_shift_modes = ShiftableEncoderSelectorComponent(self, tuple(self._global_bank_buttons), encoder_user_modes, self._encoder_modes, self._encoder_eq_modes, self._encoder_device_modes) #tuple(select_buttons), master_select_button, tuple(arm_buttons), self._matrix, self._session, self._session_zoom, self._mixer, slider_modes, matrix_modes) #, self._send_introduction_message) #also added self for _parent
        self._encoder_shift_modes.name = 'Encoder_Shift_Modes'
        self._encoder_shift_modes.set_mode_toggle(self._shift_button)     


    def _on_selected_track_changed(self):
        ControlSurface._on_selected_track_changed(self)
        #self._slider_modes.update() #added to update alternate slider assignments
        track = self.song().view.selected_track
        device_to_select = track.view.selected_device
        if device_to_select == None and len(track.devices) > 0:
            device_to_select = track.devices[0]
        if device_to_select != None:
            self.song().view.select_device(device_to_select)
        self._device_component.set_device(device_to_select)
        return None

    def _product_model_id_byte(self):
        return 115
コード例 #23
0
class APC40(APC):
    """ Script for Akai's APC40 Controller """
    def __init__(self, c_instance):
        APC.__init__(self, c_instance)
        self._device_selection_follows_track_selection = True

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)
        right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        up_button.name = 'Bank_Select_Up_Button'
        down_button.name = 'Bank_Select_Down_Button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        matrix.name = 'Button_Matrix'
        scene_launch_buttons = [
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, index + 82)
            for index in range(5)
        ]
        track_stop_buttons = [
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52)
            for index in range(8)
        ]
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_' + str(
                index) + '_Launch_Button'

        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = 'Track_' + str(
                index) + '_Stop_Button'

        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE,
                                       track_index, scene_index + 53)
                button.name = str(track_index) + '_Clip_' + str(
                    scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)

            matrix.add_row(tuple(button_row))

        self._session.set_slot_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button,
                                           right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            volume_control = SliderElement(MIDI_CC_TYPE, track, 7)
            arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        49)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        50)
            select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                          51)
            volume_control.name = str(track) + '_Volume_Control'
            arm_button.name = str(track) + '_Arm_Button'
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            select_button.name = str(track) + '_Select_Button'
            strip.set_volume_control(volume_control)
            strip.set_arm_button(arm_button)
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_select_button(select_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)

        crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             80)
        prehear_control = EncoderElement(
            MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        master_select_button.name = 'Master_Select_Button'
        prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_crossfader_control(crossfader)
        self._mixer.set_prehear_volume_control(prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._mixer.master_strip().set_select_button(master_select_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button',
                              'Previous_Device_Button', 'Next_Device_Button',
                              'Detail_View_Button', 'Rec_Quantization_Button',
                              'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                             24 + index)
            ringed_encoder = RingedEncoderElement(
                MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)

        device = ShiftableDeviceComponent()
        device.name = 'Device_Component'
        device.set_bank_buttons(tuple(device_bank_buttons))
        device.set_shift_button(self._shift_button)
        device.set_parameter_controls(tuple(device_param_controls))
        device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(device)
        detail_view_toggler = DetailViewCntrlComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(
            device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2],
                                                   device_bank_buttons[3])
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_Button'
        nudge_down_button.name = 'Nudge_Down_Button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(
            tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        global_bank_buttons = []
        global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                        56 + index)
            ringed_encoder = RingedEncoderElement(
                MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            global_param_controls.append(ringed_encoder)

        global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button',
                              'Send_C_Button')
        for index in range(4):
            global_bank_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            global_bank_buttons[-1].name = global_bank_labels[index]

        encoder_modes = EncModeSelectorComponent(self._mixer)
        encoder_modes.name = 'Track_Control_Modes'
        encoder_modes.set_modes_buttons(global_bank_buttons)
        encoder_modes.set_controls(tuple(global_param_controls))
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(
            tuple(global_param_controls))
        global_translation_selector.set_mode_buttons(
            tuple(global_bank_buttons))

    def _product_model_id_byte(self):
        return 115
コード例 #24
0
class APC_64_40_9(APC):
    """ Script for Akai's APC40 Controller """
    def __init__(self, c_instance):
        self._c_instance = c_instance
        self._shift_modes = None
        self._encoder_modes = None
        self._slider_modes = None
        self._sequencer = None
        APC.__init__(self, c_instance)
        self._device_selection_follows_track_selection = True

    def disconnect(self):
        self._shift_modes = None
        self._encoder_modes = None
        self._slider_modes = None
        self._sequencer = None
        APC.disconnect(self)

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)
        self._right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        self._left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        self._up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        self._down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        self._right_button.name = 'Bank_Select_Right_button'
        self._left_button.name = 'Bank_Select_Left_button'
        self._up_button.name = 'Bank_Select_Up_button'
        self._down_button.name = 'Bank_Select_Down_button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(self._right_button,
                                             self._left_button)
        self._session.set_scene_bank_buttons(self._down_button,
                                             self._up_button)
        self._matrix = ButtonMatrixElement()
        self._matrix.name = 'Button_Matrix'
        self._scene_launch_buttons = [
            ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, index + 82)
            for index in range(5)
        ]
        self._track_stop_buttons = [
            ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52)
            for index in range(8)
        ]
        for index in range(len(self._scene_launch_buttons)):
            self._scene_launch_buttons[index].name = 'Scene_' + str(
                index) + '_Launch_Button'
        for index in range(len(self._track_stop_buttons)):
            self._track_stop_buttons[index].name = 'Track_' + str(
                index) + '_Stop_Button'
        self._stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                              81)
        self._stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(self._stop_all_button)
        self._session.set_stop_track_clip_buttons(
            tuple(self._track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(self._scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = ConfigurableButtonElement(is_momentary,
                                                   MIDI_NOTE_TYPE, track_index,
                                                   (scene_index + 53))
                button.name = str(track_index) + '_Clip_' + str(
                    scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(
                    scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)
            self._matrix.add_row(tuple(button_row))
        self._session.set_slot_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = ShiftableZoomingComponent(
            self._session, tuple(self._track_stop_buttons))
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(self._matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(self._up_button, self._down_button,
                                           self._left_button,
                                           self._right_button)
        self._session_zoom.set_scene_bank_buttons(
            tuple(self._scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(self, 8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                             80)
        master_select_button.name = 'Master_Select_Button'
        self._mixer.master_strip().set_select_button(master_select_button)
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        select_buttons = []
        arm_buttons = []
        solo_buttons = []
        mute_buttons = []
        sliders = []
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        49)
            solo_buttons.append(solo_button)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                        50)
            mute_buttons.append(mute_button)
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)
            select_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51))
            select_buttons[-1].name = str(track) + '_Select_Button'
            arm_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48))
            arm_buttons[-1].name = str(track) + '_Arm_Button'
            sliders.append(SliderElement(MIDI_CC_TYPE, track, 7))
            sliders[-1].name = str(track) + '_Volume_Control'

        self._crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        self._prehear_control = EncoderElement(
            MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        self._crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        self._prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_shift_button(self._shift_button)
        self._mixer.set_crossfader_control(self._crossfader)
        self._mixer.set_prehear_volume_control(self._prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._slider_modes = SliderModesComponent(self._mixer, tuple(sliders))
        self._slider_modes.name = 'Slider_Modes'
        matrix_modes = MatrixModesComponent(self._matrix, self._session,
                                            self._session_zoom,
                                            tuple(self._track_stop_buttons),
                                            self)
        matrix_modes.name = 'Matrix_Modes'
        self._sequencer = StepSequencerComponent(
            self, self._session, self._matrix, tuple(self._track_stop_buttons))
        self._sequencer.set_bank_buttons(tuple(select_buttons))
        self._sequencer.set_nav_buttons(self._up_button, self._down_button,
                                        self._left_button, self._right_button)
        self._sequencer.set_button_matrix(self._matrix)
        self._sequencer.set_follow_button(master_select_button)
        self._sequencer.set_velocity_buttons(tuple(arm_buttons))
        self._sequencer.set_shift_button(self._shift_button)
        self._sequencer.set_lane_mute_buttons(tuple(
            self._scene_launch_buttons))
        self._sequencer.set_loop_start_buttons(tuple(mute_buttons))
        self._sequencer.set_loop_length_buttons(tuple(solo_buttons))
        self._shift_modes = ShiftableSelectorComponent(
            self, tuple(select_buttons), master_select_button,
            tuple(self._track_stop_buttons), self._stop_all_button,
            tuple(mute_buttons), tuple(solo_buttons), tuple(arm_buttons),
            tuple(self._scene_launch_buttons), self._matrix, self._session,
            self._session_zoom, self._mixer, self._slider_modes, matrix_modes,
            self._sequencer)
        self._shift_modes.name = 'Shift_Modes'
        self._shift_modes.set_mode_toggle(self._shift_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):
        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button',
                              'Previous_Device_Button', 'Next_Device_Button',
                              'Detail_View_Button', 'Rec_Quantization_Button',
                              'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                             24 + index)
            ringed_encoder = RingedEncoderElement(
                MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.set_feedback_delay(-1)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)
        self._device = ShiftableDeviceComponent()
        self._device.name = 'Device_Component'
        self._device.set_bank_buttons(tuple(device_bank_buttons))
        self._device.set_shift_button(self._shift_button)
        self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(self._device)
        detail_view_toggler = DetailViewCntrlComponent()
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(
            device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2],
                                                   device_bank_buttons[3])
        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_button'
        nudge_down_button.name = 'Nudge_Down_button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_undo_button(nudge_down_button)
        transport.set_redo_button(nudge_up_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        self._device.set_lock_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        transport.set_tempo_encoder(self._prehear_control)
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(
            tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        self._global_bank_buttons = []
        self._global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0,
                                        56 + index)
            ringed_encoder = RingedEncoderElement(
                MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ringed_encoder.set_feedback_delay(-1)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            self._global_param_controls.append(ringed_encoder)
        self._global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button',
                              'Send_C_Button')
        for index in range(4):
            self._global_bank_buttons.append(
                ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0,
                                          87 + index))
            self._global_bank_buttons[-1].name = global_bank_labels[index]
        self._encoder_modes = EncModeSelectorComponent(self._mixer)
        self._encoder_modes.name = 'Track_Control_Modes'
        self._encoder_modes.set_controls(tuple(self._global_param_controls))
        self._encoder_device_modes = EncoderDeviceComponent(
            self._mixer, self._device, self)
        self._encoder_device_modes.name = 'Alt_Device_Control_Modes'
        self._encoder_eq_modes = EncoderEQComponent(self._mixer, self)
        self._encoder_eq_modes.name = 'EQ_Control_Modes'
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(
            tuple(self._global_param_controls))
        global_translation_selector.set_mode_buttons(
            tuple(self._global_bank_buttons))
        encoder_user_modes = EncoderUserModesComponent(
            self, self._encoder_modes, tuple(self._global_param_controls),
            tuple(self._global_bank_buttons), self._mixer, self._device,
            self._encoder_device_modes, self._encoder_eq_modes)
        encoder_user_modes.name = 'Encoder_User_Modes'
        self._encoder_shift_modes = ShiftableEncoderSelectorComponent(
            self, tuple(self._global_bank_buttons), encoder_user_modes,
            self._encoder_modes, self._encoder_eq_modes,
            self._encoder_device_modes)
        self._encoder_shift_modes.name = 'Encoder_Shift_Modes'
        self._encoder_shift_modes.set_mode_toggle(self._shift_button)

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

    def _product_model_id_byte(self):
        return 115
コード例 #25
0
class Axiom_AIR_25_49_61(ControlSurface):
    """ Script for the M-Audio Axiom A.I.R. 25, 49 and 61 """
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._alt_device_component = None
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._device_selection_follows_track_selection = True
            self._suggested_input_port = 'HyperControl'
            self._suggested_output_port = 'HyperControl'
            self._single_fader_button_modes = None
            self._has_faders = True
            self._display_reset_delay = -1
            self._hc_byte = HC_BYTE
            self._waiting_for_first_response = True
            self._setup_controls()
            self._setup_displays()
            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_modes()
            self._drum_group_midi_button = None
            self._drum_group_hyper_button = None
            for component in self.components:
                component.set_enabled(False)

        return

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def _install_mapping(self, midi_map_handle, control, parameter,
                         feedback_delay, feedback_map):
        if not self._in_build_midi_map:
            raise AssertionError
            raise midi_map_handle != None or AssertionError
            raise control != None and parameter != None or AssertionError
            raise isinstance(
                parameter,
                Live.DeviceParameter.DeviceParameter) or AssertionError
            raise isinstance(control, InputControlElement) or AssertionError
            raise isinstance(feedback_delay, int) or AssertionError
            if not isinstance(feedback_map, tuple):
                raise AssertionError
                success = False
                feedback_rule = None
                feedback_rule = control.message_type(
                ) is MIDI_NOTE_TYPE and Live.MidiMap.NoteFeedbackRule()
                feedback_rule.note_no = 0
                feedback_rule.vel_map = (0, )
            elif control.message_type() is MIDI_CC_TYPE:
                feedback_rule = Live.MidiMap.CCFeedbackRule()
                feedback_rule.cc_no = 0
                feedback_rule.cc_value_map = (0, )
            elif control.message_type() is MIDI_PB_TYPE:
                feedback_rule = Live.MidiMap.PitchBendFeedbackRule()
                feedback_rule.value_pair_map = feedback_map
            raise feedback_rule != None or AssertionError
            feedback_rule.channel = control.message_channel()
            feedback_rule.delay_in_ms = feedback_delay
            success = control.message_type(
            ) is MIDI_NOTE_TYPE and Live.MidiMap.map_midi_note_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(),
                control.message_identifier(), feedback_rule)
        elif control.message_type() is MIDI_CC_TYPE:
            success = Live.MidiMap.map_midi_cc_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(),
                control.message_identifier(), control.message_map_mode(),
                feedback_rule, not control.needs_takeover())
        elif control.message_type() is MIDI_PB_TYPE:
            success = Live.MidiMap.map_midi_pitchbend_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(),
                feedback_rule, not control.needs_takeover())
        return success
コード例 #26
0
class Axiom_AIR_25_49_61(ControlSurface):
    """ Script for the M-Audio Axiom A.I.R. 25, 49 and 61 """

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def _install_mapping(self, midi_map_handle, control, parameter, feedback_delay, feedback_map):
        if not self._in_build_midi_map:
            raise AssertionError
            raise midi_map_handle != None or AssertionError
            raise control != None and parameter != None or AssertionError
            raise isinstance(parameter, Live.DeviceParameter.DeviceParameter) or AssertionError
            raise isinstance(control, InputControlElement) or AssertionError
            raise isinstance(feedback_delay, int) or AssertionError
            if not isinstance(feedback_map, tuple):
                raise AssertionError
                success = False
                feedback_rule = None
                feedback_rule = control.message_type() is MIDI_NOTE_TYPE and Live.MidiMap.NoteFeedbackRule()
                feedback_rule.note_no = 0
                feedback_rule.vel_map = (0,)
            elif control.message_type() is MIDI_CC_TYPE:
                feedback_rule = Live.MidiMap.CCFeedbackRule()
                feedback_rule.cc_no = 0
                feedback_rule.cc_value_map = (0,)
            elif control.message_type() is MIDI_PB_TYPE:
                feedback_rule = Live.MidiMap.PitchBendFeedbackRule()
                feedback_rule.value_pair_map = feedback_map
            raise feedback_rule != None or AssertionError
            feedback_rule.channel = control.message_channel()
            feedback_rule.delay_in_ms = feedback_delay
            success = control.message_type() is MIDI_NOTE_TYPE and Live.MidiMap.map_midi_note_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(), control.message_identifier(), feedback_rule
            )
        elif control.message_type() is MIDI_CC_TYPE:
            success = Live.MidiMap.map_midi_cc_with_feedback_map(
                midi_map_handle,
                parameter,
                control.message_channel(),
                control.message_identifier(),
                control.message_map_mode(),
                feedback_rule,
                not control.needs_takeover(),
            )
        elif control.message_type() is MIDI_PB_TYPE:
            success = Live.MidiMap.map_midi_pitchbend_with_feedback_map(
                midi_map_handle, parameter, control.message_channel(), feedback_rule, not control.needs_takeover()
            )
        return success
コード例 #27
0
class SubSelectorComponent(ModeSelectorComponent):
    """ Class that handles different mixer modes """

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

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

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

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

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

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

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

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

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

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

    def number_of_modes(self):
        return 4

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
コード例 #28
0
class Orsi(ControlSurface):
    __doc__ = " Script for FCB1010 in APC emulation mode "

    _active_instances = []

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

    _combine_active_instances = staticmethod(_combine_active_instances)

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

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

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

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

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

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

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

    def _setup_device_and_transport_control(self):
        is_momentary = True
        self._device = DeviceComponent()
        self._device.name = 'Device_Component'
        device_bank_buttons = []
        device_param_controls = []
        for index in range(PARAMS_NUMBER):
            device_param_controls.append(self._ctrl_map_parameter[index])
        for index in range(BANKS_NUMBER):
            device_bank_buttons.append(self._note_map_bank_buttons[index])
        if None not in device_bank_buttons:
            self._device.set_bank_buttons(tuple(device_bank_buttons))
        if None not in device_param_controls:
            self._device.set_parameter_controls(tuple(device_param_controls))
        self._device.set_on_off_button(self._note_map_buttons[17])
        self._device.set_bank_nav_buttons(self._note_map_buttons[20],
                                          self._note_map_buttons[21])
        self._device.set_lock_button(self._note_map_buttons[16])
        self.set_device_component(self._device)

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

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

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

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

    def _load_MIDI_map(self):
        is_momentary = True
        # SCENELAUNCH Buttons
        for scene_id in range(MATRIX_DEPTH):
            if (SCENELAUNCH[scene_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary,
                                       SCENELAUNCH_TYPE[scene_id],
                                       SCENELAUNCH_CH[scene_id],
                                       SCENELAUNCH[scene_id])
                button.name = 'Scene_' + str(scene_id)
            self._note_map_scenes.append(button)
        # BUTTON_VECTOR Buttons
        for button_id in range(NUMBER_BUTTONS):
            if (BUTTON_VECTOR[button_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary,
                                       BUTTON_VECTOR_TYPE[button_id],
                                       BUTTON_VECTOR_CH[button_id],
                                       BUTTON_VECTOR[button_id])
                button.name = 'Global_Button_' + str(button_id)
            self._note_map_buttons.append(button)
        # SLIDER_VECTOR Sliders
        for slider_id in range(NUMBER_SLIDERS):
            if (SLIDER_VECTOR[slider_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE,
                                        SLIDER_VECTOR_CH[slider_id],
                                        SLIDER_VECTOR[slider_id])
                control.name = 'Global_Slider_' + str(slider_id)
            self._ctrl_map_sliders.append(control)
        # TRACKSTOP Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSTOP[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSTOP_TYPE[track_id],
                                       TRACKSTOP_CH[track_id],
                                       TRACKSTOP[track_id])
                button.name = 'Trk_Stop_Button_' + str(track_id)
            self._note_map_trk_stop_buttons.append(button)
        # TRACKSEL Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSEL[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSEL_TYPE[track_id],
                                       TRACKSEL_CH[track_id],
                                       TRACKSEL[track_id])
                button.name = 'Trk_Sel_Button_' + str(track_id)
            self._note_map_trk_sel_buttons.append(button)
        # TRACKMUTE Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKMUTE[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKMUTE_TYPE[track_id],
                                       TRACKMUTE_CH[track_id],
                                       TRACKMUTE[track_id])
                button.name = 'Trk_Mute_Button_' + str(track_id)
            self._note_map_trk_mute_buttons.append(button)
        # TRACKSOLO Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKSOLO[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKSOLO_TYPE[track_id],
                                       TRACKSOLO_CH[track_id],
                                       TRACKSOLO[track_id])
                button.name = 'Trk_Solo_Button_' + str(track_id)
            self._note_map_trk_solo_buttons.append(button)
        # TRACKREC Buttons
        for track_id in range(TRACK_NUMBER):
            if (TRACKREC[track_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, TRACKREC_TYPE[track_id],
                                       TRACKREC_CH[track_id],
                                       TRACKREC[track_id])
                button.name = 'Trk_Rec_Button_' + str(track_id)
            self._note_map_trk_rec_buttons.append(button)
        # TRACKVOL Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKVOL[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKVOL_CH[track_id],
                                        TRACKVOL[track_id])
                control.name = 'Trk_Vol_Slider_' + str(track_id)
            self._ctrl_map_trk_volume.append(control)
        # TRACKPAN Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKPAN[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKPAN_CH[track_id],
                                        TRACKPAN[track_id])
                control.name = 'Trk_Pan_Slider_' + str(track_id)
            self._ctrl_map_trk_pan.append(control)
        # TRACKSENDA Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDA[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDA_CH[track_id],
                                        TRACKSENDA[track_id])
                control.name = 'Trk_SendA_Slider_' + str(track_id)
            self._ctrl_map_senda.append(control)
        # TRACKSENDB Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDB[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDB_CH[track_id],
                                        TRACKSENDB[track_id])
                control.name = 'Trk_SendB_Slider_' + str(track_id)
            self._ctrl_map_sendb.append(control)
        # TRACKSENDC Sliders
        for track_id in range(TRACK_NUMBER):
            if (TRACKSENDC[track_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE, TRACKSENDC_CH[track_id],
                                        TRACKSENDC[track_id])
                control.name = 'Trk_SendC_Slider_' + str(track_id)
            self._ctrl_map_sendc.append(control)
        # DEVICEBANK Buttons
        for bank_id in range(BANKS_NUMBER):
            if (DEVICEBANK[bank_id] == -1):
                button = None
            else:
                button = ButtonElement(is_momentary, DEVICEBANK_TYPE[bank_id],
                                       DEVICEBANK_CH[bank_id],
                                       DEVICEBANK[bank_id])
                button.name = 'Bank_Button_' + str(bank_id)
            self._note_map_bank_buttons.append(button)
        # PARAMCONTROL Sliders
        for param_id in range(PARAMS_NUMBER):
            if (PARAMCONTROL[param_id] == -1):
                control = None
            else:
                control = SliderElement(MIDI_CC_TYPE,
                                        PARAMCONTROL_CH[param_id],
                                        PARAMCONTROL[param_id])
                control.name = 'Slider_Param_' + str(param_id)
            self._ctrl_map_parameter.append(control)
コード例 #29
0
    def _init_mixer_component(self, volume_controls, trackarm_controls, mixer_options, global_channel, volume_map_mode):
        if volume_controls != None and trackarm_controls != None:
            num_strips = max(len(volume_controls), len(trackarm_controls))
            send_info = []
            momentary_buttons = False
            mixer = SpecialMixerComponent(num_strips)
            mixer.name = 'Mixer'
            mixer.master_strip().name = 'Master_Channel_Strip'
            mixer.selected_strip().name = 'Selected_Channel_Strip'
            if mixer_options != None:
                if 'MASTERVOLUME' in mixer_options.keys() and mixer_options['MASTERVOLUME'] in range(128):
                    encoder = EncoderElement(MIDI_CC_TYPE, global_channel, mixer_options['MASTERVOLUME'], volume_map_mode)
                    encoder.name = 'Master_Volume_Control'
                    mixer.master_strip().set_volume_control(encoder)
                if 'NUMSENDS' in mixer_options.keys() and mixer_options['NUMSENDS'] > 0:
                    for send in range(mixer_options['NUMSENDS']):
                        key = 'SEND' + str(send + 1)
                        raise key in mixer_options.keys() or AssertionError
                        send_info.append(mixer_options[key])

                momentary_buttons = 'NOTOGGLE' in mixer_options.keys()
                next_bank_button = None
                prev_bank_button = None
                if 'NEXTBANK' in mixer_options.keys() and mixer_options['NEXTBANK'] in range(128):
                    next_bank_button = ButtonElement(momentary_buttons, MIDI_CC_TYPE, global_channel, mixer_options['NEXTBANK'])
                    next_bank_button.name = 'Mixer_Next_Bank_Button'
                if 'PREVBANK' in mixer_options.keys() and mixer_options['PREVBANK'] in range(128):
                    prev_bank_button = ButtonElement(momentary_buttons, MIDI_CC_TYPE, global_channel, mixer_options['PREVBANK'])
                    prev_bank_button.name = 'Mixer_Previous_Bank_Button'
                mixer.set_bank_buttons(next_bank_button, prev_bank_button)
            for track in range(num_strips):
                strip = mixer.channel_strip(track)
                strip.name = 'Channel_Strip_' + str(track)
                if track in range(len(volume_controls)):
                    channel = global_channel
                    cc = volume_controls[track]
                    if isinstance(volume_controls[track], (tuple, list)):
                        cc = volume_controls[track][0]
                        if volume_controls[track][1] in range(16):
                            channel = volume_controls[track][1]
                    if cc in range(128) and channel in range(16):
                        encoder = EncoderElement(MIDI_CC_TYPE, channel, cc, volume_map_mode)
                        encoder.name = str(track) + '_Volume_Control'
                        strip.set_volume_control(encoder)
                if track in range(len(trackarm_controls)) and trackarm_controls[track] in range(128):
                    button = ButtonElement(momentary_buttons, MIDI_CC_TYPE, global_channel, trackarm_controls[track])
                    button.name = str(track) + '_Arm_Button'
                    strip.set_arm_button(button)
                send_controls = []
                for send in send_info:
                    encoder = None
                    if track in range(len(send)):
                        channel = global_channel
                        cc = send[track]
                        if isinstance(send[track], (tuple, list)):
                            cc = send[track][0]
                            if send[track][1] in range(16):
                                channel = send[track][1]
                        if cc in range(128) and channel in range(16):
                            encoder = EncoderElement(MIDI_CC_TYPE, channel, cc, volume_map_mode)
                            encoder.name = str(track) + '_Send_' + str(list(send_info).index(send)) + '_Control'
                    send_controls.append(encoder)

                strip.set_send_controls(tuple(send_controls))
コード例 #30
0
class APC40(APC):
    __doc__ = " Script for Akai's APC40 Controller "
    
    def __init__(self, c_instance):
        APC.__init__(self, c_instance)
        self._device_selection_follows_track_selection = True

    def _setup_session_control(self):
        is_momentary = True
        self._shift_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 98)        
        right_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 96)
        left_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 97)
        up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 94)
        down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 95)
        right_button.name = 'Bank_Select_Right_Button'
        left_button.name = 'Bank_Select_Left_Button'
        up_button.name = 'Bank_Select_Up_Button'
        down_button.name = 'Bank_Select_Down_Button'
        self._session = PedaledSessionComponent(8, 5)
        self._session.name = 'Session_Control'
        self._session.set_track_bank_buttons(right_button, left_button)
        self._session.set_scene_bank_buttons(down_button, up_button)
        matrix = ButtonMatrixElement()
        matrix.name = 'Button_Matrix'
        self._matrix = matrix
        scene_launch_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, (index + 82)) for index in range(5) ]
        track_stop_buttons = [ ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 52) for index in range(8) ]
        self._track_stop_buttons = track_stop_buttons
        for index in range(len(scene_launch_buttons)):
            scene_launch_buttons[index].name = 'Scene_'+ str(index) + '_Launch_Button'
        for index in range(len(track_stop_buttons)):
            track_stop_buttons[index].name = 'Track_' + str(index) + '_Stop_Button'
        stop_all_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 81)
        stop_all_button.name = 'Stop_All_Clips_Button'
        self._session.set_stop_all_clips_button(stop_all_button)
        self._session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
        self._session.set_stop_track_clip_value(2)
        self._button_rows = []
        for scene_index in range(5):
            scene = self._session.scene(scene_index)
            scene.name = 'Scene_' + str(scene_index)
            button_row = []
            scene.set_launch_button(scene_launch_buttons[scene_index])
            scene.set_triggered_value(2)
            for track_index in range(8):
                button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track_index, (scene_index + 53))
                button.name = str(track_index) + '_Clip_' + str(scene_index) + '_Button'
                button_row.append(button)
                clip_slot = scene.clip_slot(track_index)
                clip_slot.name = str(track_index) + '_Clip_Slot_' + str(scene_index)
                clip_slot.set_triggered_to_play_value(2)
                clip_slot.set_triggered_to_record_value(4)
                clip_slot.set_stopped_value(5)
                clip_slot.set_started_value(1)
                clip_slot.set_recording_value(3)
                clip_slot.set_launch_button(button)
            matrix.add_row(tuple(button_row))
            self._button_rows.append(button_row)

        self._session.set_slot_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 67))
        self._session.selected_scene().name = 'Selected_Scene'
        self._session.selected_scene().set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 64))
        self._session_zoom = SessionZoomingComponent(self._session)
        self._session_zoom.name = 'Session_Overview'
        self._session_zoom.set_button_matrix(matrix)
        self._session_zoom.set_zoom_button(self._shift_button)
        self._session_zoom.set_nav_buttons(up_button, down_button, left_button, right_button)
        self._session_zoom.set_scene_bank_buttons(tuple(scene_launch_buttons))
        self._session_zoom.set_stopped_value(3)
        self._session_zoom.set_selected_value(5)
        return None   

    def _setup_mixer_control(self):
        is_momentary = True
        self._mixer = SpecialMixerComponent(8)
        self._mixer.name = 'Mixer'
        self._mixer.master_strip().name = 'Master_Channel_Strip'
        self._mixer.selected_strip().name = 'Selected_Channel_Strip'
        self._select_buttons = []
        for track in range(8):
            strip = self._mixer.channel_strip(track)
            strip.name = 'Channel_Strip_' + str(track)
            volume_control = SliderElement(MIDI_CC_TYPE, track, 7)
            arm_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 48)
            solo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 49)
            mute_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 50)
            select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 51)
            self._select_buttons.append(select_button)
            volume_control.name = str(track) + '_Volume_Control'
            arm_button.name = str(track) + '_Arm_Button'
            solo_button.name = str(track) + '_Solo_Button'
            mute_button.name = str(track) + '_Mute_Button'
            select_button.name = str(track) + '_Select_Button'
            strip.set_volume_control(volume_control)
            strip.set_arm_button(arm_button)
            strip.set_solo_button(solo_button)
            strip.set_mute_button(mute_button)
            strip.set_select_button(select_button)
            strip.set_shift_button(self._shift_button)
            strip.set_invert_mute_feedback(True)
        crossfader = SliderElement(MIDI_CC_TYPE, 0, 15)
        master_volume_control = SliderElement(MIDI_CC_TYPE, 0, 14)
        master_select_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 80)
        prehear_control = EncoderElement(MIDI_CC_TYPE, 0, 47, Live.MidiMap.MapMode.relative_two_compliment)
        crossfader.name = 'Crossfader'
        master_volume_control.name = 'Master_Volume_Control'
        master_select_button.name = 'Master_Select_Button'
        prehear_control.name = 'Prehear_Volume_Control'
        self._mixer.set_crossfader_control(crossfader)
        self._mixer.set_prehear_volume_control(prehear_control)
        self._mixer.master_strip().set_volume_control(master_volume_control)
        self._mixer.master_strip().set_select_button(master_select_button)

    def _setup_custom_components(self):
        self._setup_device_and_transport_control()
        self._setup_global_control()

    def _setup_device_and_transport_control(self):

        is_momentary = True
        device_bank_buttons = []
        device_param_controls = []
        bank_button_labels = ('Clip_Track_Button', 'Device_On_Off_Button', 'Previous_Device_Button', 'Next_Device_Button', 'Detail_View_Button', 'Rec_Quantization_Button', 'Midi_Overdub_Button', 'Metronome_Button')
        for index in range(8):
            device_bank_buttons.append(ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 58 + index))
            device_bank_buttons[-1].name = bank_button_labels[index]
            ring_mode_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 24 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 16 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.set_ring_mode_button(ring_mode_button)
            ringed_encoder.name = 'Device_Control_' + str(index)
            ring_mode_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            device_param_controls.append(ringed_encoder)
        device = ShiftableDeviceComponent()
        device.name = 'Device_Component'
        device.set_bank_buttons(tuple(device_bank_buttons))
        device.set_shift_button(self._shift_button)
        device.set_parameter_controls(tuple(device_param_controls))
        device.set_on_off_button(device_bank_buttons[1])
        self.set_device_component(device)
        detail_view_toggler = DetailViewCntrlComponent(self)
        detail_view_toggler.name = 'Detail_View_Control'
        detail_view_toggler.set_shift_button(self._shift_button)
        detail_view_toggler.set_device_clip_toggle_button(device_bank_buttons[0])
        detail_view_toggler.set_detail_toggle_button(device_bank_buttons[4])
        detail_view_toggler.set_device_nav_buttons(device_bank_buttons[2], device_bank_buttons[3])

        # VU Meters
        vu = VUMeters(self)

        transport = ShiftableTransportComponent()
        transport.name = 'Transport'
        play_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 91)
        stop_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 92)
        record_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 93)
        nudge_up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 100)
        nudge_down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 101)
        tap_tempo_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, 99)
        play_button.name = 'Play_Button'
        stop_button.name = 'Stop_Button'
        record_button.name = 'Record_Button'
        nudge_up_button.name = 'Nudge_Up_Button'
        nudge_down_button.name = 'Nudge_Down_Button'
        tap_tempo_button.name = 'Tap_Tempo_Button'
        transport.set_shift_button(self._shift_button)
        transport.set_play_button(play_button)
        transport.set_stop_button(stop_button)
        transport.set_record_button(record_button)
        transport.set_nudge_buttons(nudge_up_button, nudge_down_button)
        transport.set_tap_tempo_button(tap_tempo_button)
        transport.set_quant_toggle_button(device_bank_buttons[5])
        transport.set_overdub_button(device_bank_buttons[6])
        transport.set_metronome_button(device_bank_buttons[7])
        bank_button_translator = ShiftTranslatorComponent()
        bank_button_translator.set_controls_to_translate(tuple(device_bank_buttons))
        bank_button_translator.set_shift_button(self._shift_button)

    def _setup_global_control(self):
        is_momentary = True
        global_bank_buttons = []
        global_param_controls = []
        for index in range(8):
            ring_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, 0, 56 + index)
            ringed_encoder = RingedEncoderElement(MIDI_CC_TYPE, 0, 48 + index, Live.MidiMap.MapMode.absolute)
            ringed_encoder.name = 'Track_Control_' + str(index)
            ring_button.name = ringed_encoder.name + '_Ring_Mode_Button'
            ringed_encoder.set_ring_mode_button(ring_button)
            global_param_controls.append(ringed_encoder)
        global_bank_buttons = []
        global_bank_labels = ('Pan_Button', 'Send_A_Button', 'Send_B_Button', 'Send_C_Button')
        for index in range(4):
            global_bank_buttons.append(ButtonElement(not is_momentary, MIDI_NOTE_TYPE, 0, 87 + index))
            global_bank_buttons[-1].name = global_bank_labels[index]
        encoder_modes = EncModeSelectorComponent(self._mixer)
        encoder_modes.name = 'Track_Control_Modes'
        encoder_modes.set_modes_buttons(global_bank_buttons)
        encoder_modes.set_controls(tuple(global_param_controls))
        global_translation_selector = ChannelTranslationSelector()
        global_translation_selector.name = 'Global_Translations'
        global_translation_selector.set_controls_to_translate(tuple(global_param_controls))
        global_translation_selector.set_mode_buttons(tuple(global_bank_buttons))

    def _product_model_id_byte(self):
        return 115