コード例 #1
0
ファイル: OhmModesHH.py プロジェクト: amuntner/m4m7
	def _setup_mixer_control(self):
		is_momentary = True
		self._num_tracks = (7) #A mixer is one-dimensional; 
		global mixer
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])
		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True
		self.song().view.selected_track = mixer.channel_strip(0)._track #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
コード例 #2
0
	def _setup_mixer_control(self):
		global mixer
		is_momentary = True
		self._num_tracks = 7
		mixer = SpecialMixerComponent(7, 0, True, False)
		mixer.name = 'Mixer'
		self._mixer = mixer
		for index in range(7):
			mixer.channel_strip(index).set_volume_control(self._fader[index])

		for index in range(7):
			mixer.channel_strip(index).name = 'Mixer_ChannelStrip_' + str(index)
			mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
			mixer.channel_strip(index)._invert_mute_feedback = True

		self.song().view.selected_track = mixer.channel_strip(0)._track
コード例 #3
0
 def _setup_mixer_control(self):
     is_momentary = True
     self._num_tracks = (7)  #A mixer is one-dimensional;
     global mixer
     mixer = SpecialMixerComponent(7, 0, True, False)
     mixer.name = 'Mixer'
     self._mixer = mixer
     mixer.set_track_offset(
         0)  #Sets start point for mixer strip (offset from left)
     for index in range(7):
         mixer.channel_strip(index).set_volume_control(self._fader[index])
     for index in range(7):
         mixer.channel_strip(
             index).name = 'Mixer_ChannelStrip_' + str(index)
         mixer.track_eq(index).name = 'Mixer_EQ_' + str(index)
         mixer.channel_strip(index)._invert_mute_feedback = True
     self.song().view.selected_track = mixer.channel_strip(
         0
     )._track  #set the selected strip to the first track, so that we don't, for example, try to assign a button to arm the master track, which would cause an assertion error
コード例 #4
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)
コード例 #5
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)
コード例 #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)
        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
コード例 #7
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)
コード例 #8
0
class NanoKontrolShift(ControlSurface):
    __module__ = __name__
    __doc__ = " NanoKontrolShift controller script "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn off rebuild MIDI map until after we're done setting up
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= NanoKontrolShift log opened =--------------"
        )  # Writes message into Live's main log file. This is a ControlSurface method.
        with self.component_guard():
            # OBJECTS
            self.session = None  # session object
            self.mixer = None  # mixer object
            self.view = None  # clip/device view object
            self.device = None  # device object
            self.transport = None  # transport object
            # MODES
            self._shift_button = None
            self._shift_button_pressed = False
            self._alt_button = None
            self._alt_button_pressed = False
            self._ctrl_button = None
            self._ctrl_button_pressed = False
            # INITIALIZE MIXER, SESSIONS
            self._setup_session_control()  # Setup the session object
            self._setup_mixer_control()  # Setup the mixer object
            self._setup_view_control()  # Setup the clip/view toggler
            self.session.set_mixer(self.mixer)  # Bind mixer to session
            self._setup_device_control()  # Setup the device object
            self._setup_transport_control()  # Setup transport object
            self.set_device_component(
                self.device)  # Bind device to control surface
            # SET INITIAL SESSION/MIXER AND MODIFIERS BUTTONS
            self._set_modifiers_buttons()
            self.__update_matrix()
            self.set_highlighting_session_component(self.session)

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

        # self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn rebuild back on, once we're done setting up

    def _setup_session_control(self):
        self.show_message(
            "#################### SESSION: ON ##############################")
        is_momentary = True
        # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX
        self.session = SessionComponent(num_tracks,
                                        num_scenes)  # (num_tracks, num_scenes)
        self.session.set_offsets(0, 0)
        # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_down), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_up))
        self.session.set_track_bank_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_right),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_left)
        )  # (right_button, left_button) This moves the "red box" selection set left & right. We'll use the mixer track selection instead...

    def _setup_mixer_control(self):
        is_momentary = True
        # CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON)
        self.mixer = SpecialMixerComponent(
            num_tracks, 0, False,
            False)  # 4 tracks, 2 returns, no EQ, no filters
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(
            0)  # Sets start point for mixer strip (offset from left)

    def _setup_view_control(self):
        # CREATES OBJECT SO WE CAN TOGGLE DEVICE/CLIP, LOCK DEVICE
        self.view = ViewTogglerComponent(num_tracks, self)

    def _setup_device_control(self):
        # CREATE DEVICE TO ASSIGN PARAMETERS BANK
        self.device = DeviceComponent()
        self.device.name = 'Device_Component'

    def _setup_transport_control(self):
        # CREATE TRANSPORT DEVICE
        self.transport = SpecialTransportComponent(self)

    def _on_selected_scene_changed(self):
        # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        if (track.devices is not None):
            self._ignore_track_selection = True
            device_to_select = track.devices[0]
            self.song().view.select_device(device_to_select)
            self._device_component.set_device(device_to_select)
        self._ignore_track_selection = False

    """                                 LED ON, OFF, FLASH WITH SESSION CLIPS                                             """

    # UPDATING BUTTONS FROM CLIP MATRIX IN NK AS SESSION MOVES
    def __update_matrix(self):
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                button = clip_slot._launch_button_value.subject
                value_to_send = -1
                if clip_slot._clip_slot != None:
                    if clip_slot.has_clip():
                        value_to_send = 127
                        if clip_slot._clip_slot.clip.is_triggered:
                            if clip_slot._clip_slot.clip.will_record_on_start:
                                value_to_send = clip_slot._triggered_to_record_value
                            else:
                                value_to_send = clip_slot._triggered_to_play_value
                        '''
                        elif clip_slot._clip_slot.clip.is_playing:
                            if clip_slot._clip_slot.clip.is_recording:
                                value_to_send = 127
                                #########      CLIPS PLAYING WILL FLASH
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                            else:
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                        '''
                    elif clip_slot._clip_slot.is_triggered:
                        if clip_slot._clip_slot.will_record_on_start:
                            value_to_send = clip_slot._triggered_to_record_value
                        else:
                            value_to_send = clip_slot._triggered_to_play_value
                    elif clip_slot._clip_slot.is_playing:
                        if clip_slot._clip_slot.is_recording:
                            value_to_send = clip_slot._recording_value
                        else:
                            value_to_send = clip_slot._started_value
                    elif clip_slot._clip_slot.controls_other_clips:
                        value_to_send = 0
                '''
                if value_to_send in range(128):
                    button.send_value(value_to_send)
                else:
                    button.turn_off()
                '''

    """                                 MODIFIERS, MODES, KEYS CONFIG                                             """

    # MODES ARE HERE: INITIALIZATIONS, DISCONNECTS BUTTONS, SLIDERS, ENCODERS
    def _clear_controls(self):
        # TURNING OFF ALL LEDS IN MATRIX
        self._turn_off_matrix()
        # SESSION
        resetsend_controls = []
        self.mixer.send_controls = []
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            scene.set_launch_button(None)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_launch_button(None)
        self.session.set_stop_track_clip_buttons(None)
        self.session.set_stop_all_clips_button(None)
        # REMOVE LISTENER TO SESSION MOVES
        if self.session.offset_has_listener(self.__update_matrix):
            self.session.remove_offset_listener(self.__update_matrix)
        self.session.set_stop_all_clips_button(None)
        # MIXER
        self.mixer._set_send_nav(None, None)
        for track_index in range(num_tracks):
            strip = self.mixer.channel_strip(track_index)
            strip.set_solo_button(None)
            strip.set_mute_button(None)
            strip.set_arm_button(None)
            resetsend_controls.append(None)
            strip.set_select_button(None)
            for i in range(12):
                self.mixer.send_controls.append(None)
            strip.set_send_controls(tuple(self.mixer.send_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        # VIEW
        self.view.set_device_nav_buttons(None, None)
        detailclip_view_controls = []
        for track_index in range(num_tracks):
            detailclip_view_controls.append(None)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE PARAMETERS
        device_param_controls = []
        self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(None)
        self.device.set_lock_button(None)
        # TRANSPORT
        self.transport.set_stop_button(None)
        self.transport.set_play_button(None)
        self.transport.set_record_button(None)
        self.transport._set_quant_toggle_button(None)
        self.transport.set_metronome_button(None)
        self.transport._set_tempo_buttons(None, None)

        self.log_message("Controls Cleared")

    def _set_normal_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.name = 'Mixer_ChannelStrip_' + str(index)
            self.mixer._update_send_index(self.mixer.sends_index)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, CHANNEL,
                              mixer_volumefader_cc[index]))
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(
                MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index],
                Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        ### SET ARM, SOLO, MUTE
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip.set_solo_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_solo_cc[index]))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_mute_cc[index]))
            strip.set_arm_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_arm_cc[index]))
            # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
            for i in range(12):
                self.mixer.send_controls.append(None)
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(
                MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index],
                Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        self.mixer._update_send_index(self.mixer.sends_index)

    def _set_alt_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        stop_track_controls = []
        resetsend_controls = []
        button = None
        buttons = None
        # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_select_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              track_select_cc[index]))
            button = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                   stop_track_cc[index])
            stop_track_controls.append(button)
            buttons = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                    track_resetsend_cc[index])
            resetsend_controls.append(buttons)
        self.session.set_stop_track_clip_buttons(tuple(stop_track_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self.mixer._update_send_index(self.mixer.sends_index)

    def _set_ctrl_mode(self):
        # CLIP/DEVICE VIEW TOGGLE
        is_momentary = True
        self.view.set_device_nav_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_left_cc),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          device_right_cc))
        button = None
        detailclip_view_controls = []
        for index in range(num_tracks):
            button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL,
                                   detailclip_view_cc[index])
            detailclip_view_controls.append(button)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE ON/OFF, LOCK AND PARAMETERS
        device_param_controls = []
        onoff_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                      onoff_device_cc)
        setlock_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                                        lock_device_cc)
        for index in range(num_tracks):
            knob = None
            knob = EncoderElement(MIDI_CC_TYPE, CHANNEL,
                                  device_param_cc[index],
                                  Live.MidiMap.MapMode.absolute)
            device_param_controls.append(knob)
        if None not in device_param_controls:
            self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(onoff_control)
        self.device.set_lock_button(setlock_control)
        # TRANSPORT
        # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
        # self.transport.set_play_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_play_cc))
        # self.transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_record_cc))
        self.transport._set_quant_toggle_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_quantization_cc))
        self.transport.set_metronome_button(
            ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_metronome_cc))
        self.transport._set_tempo_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_tempodown_cc),
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          transport_tempoup_cc))
        # SESSION STOP ALL CLIPS AND SCENE LAUNCH
        self.session.set_stop_all_clips_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                          session_stopall_cc))
        for index in range(num_scenes):
            self.session.scene(index).set_launch_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL,
                              session_scenelaunch_cc[index]))

    def _set_modifiers_buttons(self):
        is_momentary = True
        self._shift_button = ButtonElement(not is_momentary, MIDI_CC_TYPE,
                                           CHANNEL, shift_mod)
        self._alt_button = ButtonElement(not is_momentary, MIDI_CC_TYPE,
                                         CHANNEL, alt_mod)
        self._ctrl_button = ButtonElement(not is_momentary, MIDI_CC_TYPE,
                                          CHANNEL, ctrl_mod)

        if (self._shift_button != None):
            self._shift_button.add_value_listener(self._shift_value)

        if (self._alt_button != None):
            self._alt_button.add_value_listener(self._alt_value)

        if (self._ctrl_button != None):
            self._ctrl_button.add_value_listener(self._ctrl_value)
        # INIT NORMAL MODE
        self._manage_modes(0)

    # MODIFIERS LISTENERS FUNCS ARE HERE
    def _shift_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._shift_button, ButtonElement)
        if value == 127:
            if self._shift_button_pressed is False:
                self._unpress_modes()
                self._shift_button_pressed = True
                self._manage_modes(0)

    def _alt_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._alt_button, ButtonElement)
        if value == 127:
            if self._alt_button_pressed is False:
                self._unpress_modes()
                self._alt_button_pressed = True
                self._manage_modes(2)

    def _ctrl_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._ctrl_button, ButtonElement)
        if value == 127:
            if self._ctrl_button_pressed is False:
                self._unpress_modes()
                self._ctrl_button_pressed = True
                self._manage_modes(3)

    def _manage_modes(self, mode_index):
        if mode_index == 0:
            self._clear_controls()
            self._set_normal_mode()
            # self._shift_button.turn_on()
            self._alt_button.turn_on()
            self._ctrl_button.turn_on()
            self.log_message("NORMAL ON")
        elif mode_index == 2:
            self._clear_controls()
            self._set_alt_mode()
            self._alt_button.turn_on()
            self._shift_button.turn_off()
            self._ctrl_button.turn_off()
            self.log_message("ALT ON")
        elif mode_index == 3:
            self._clear_controls()
            self._set_ctrl_mode()
            self._ctrl_button.turn_on()
            self._shift_button.turn_off()
            self._alt_button.turn_off()
            self.log_message("CTRL ON")

    def _unpress_modes(self):
        self._shift_button_pressed = False
        self._alt_button_pressed = False
        self._ctrl_button_pressed = False

    def _turn_off_matrix(self):
        for index in range(24):
            self._send_midi(tuple([176, index + 16, 0]))

    def disconnect(self):
        """clean things up on disconnect"""
        self.log_message(
            time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) +
            "--------------= NanoKontrolShift log closed =--------------"
        )  # Create entry in log file
        self._clear_controls()
        self.session = None
        self.mixer = None
        self.view = None
        self.device = None
        self.transport = None
        # MODES
        self._shift_button = None
        self._alt_button = None
        self._ctrl_button = None
        # SENDS
        self.send_button_up = None
        self.send_button_down = None
        self.send_controls = []
        self.send_reset = []

        self.set_device_component(None)
        ControlSurface.disconnect(self)
        return None
コード例 #9
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
コード例 #10
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
コード例 #11
0
class NanoKontrolShift(ControlSurface):
    __module__ = __name__
    __doc__ = " NanoKontrolShift controller script "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn off rebuild MIDI map until after we're done setting up
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        with self.component_guard():
            # OBJECTS
            self.session = None #session object
            self.mixer = None #mixer object
            self.view = None #clip/device view object
            self.device = None #device object
            self.transport = None #transport object
            # MODES
            self._shift_button = None
            self._shift_button_pressed = False
            self._alt_button = None
            self._alt_button_pressed = False
            self._ctrl_button = None
            self._ctrl_button_pressed = False
            # INITIALIZE MIXER, SESSIONS
            self._setup_session_control()  # Setup the session object
            self._setup_mixer_control() # Setup the mixer object
            self._setup_view_control() # Setup the clip/view toggler
            self.session.set_mixer(self.mixer) # Bind mixer to session
            self._setup_device_control() # Setup the device object
            self._setup_transport_control() # Setup transport object
            self.set_device_component(self.device) # Bind device to control surface
            # SET INITIAL SESSION/MIXER AND MODIFIERS BUTTONS
            self._set_modifiers_buttons()
            self.__update_matrix()
            # self.set_highlighting_session_component(self.session)

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

        # self._suppress_session_highlight = True
        self._suppress_send_midi = True # Turn rebuild back on, once we're done setting up

    def _setup_session_control(self):
        self.show_message("#################### SESSION: ON ##############################")
        is_momentary = True
        # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX
        self.session = SessionComponent(num_tracks, num_scenes) #(num_tracks, num_scenes)
        self.session.set_offsets(0, 0)
        # self.session.set_scene_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_down), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_up))
        # self.session.set_track_bank_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_right), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_left)) # (right_button, left_button) This moves the "red box" selection set left & right. We'll use the mixer track selection instead...

    def _setup_mixer_control(self):
        is_momentary = True
        #CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON)
        self.mixer = SpecialMixerComponent(num_tracks, 0, False, False) # 4 tracks, 2 returns, no EQ, no filters
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)

    def _setup_view_control(self):
        # CREATES OBJECT SO WE CAN TOGGLE DEVICE/CLIP, LOCK DEVICE
        self.view = ViewTogglerComponent(num_tracks, self)

    def _setup_device_control(self):
        # CREATE DEVICE TO ASSIGN PARAMETERS BANK
        self.device = DeviceComponent()
        self.device.name = 'Device_Component'

    def _setup_transport_control(self):
        # CREATE TRANSPORT DEVICE
        self.transport = SpecialTransportComponent(self)


    def _on_selected_scene_changed(self):
        # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY
        ControlSurface._on_selected_track_changed(self)
        track = self.song().view.selected_track
        if (track.devices is not None):
            self._ignore_track_selection = True
            device_to_select = track.devices[0]
            self.song().view.select_device(device_to_select)
            self._device_component.set_device(device_to_select)
        self._ignore_track_selection = False

    """                                 LED ON, OFF, FLASH WITH SESSION CLIPS                                             """

    # UPDATING BUTTONS FROM CLIP MATRIX IN NK AS SESSION MOVES
    def __update_matrix(self):
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                button = clip_slot._launch_button_value.subject
                value_to_send = -1
                if clip_slot._clip_slot != None:
                    if clip_slot.has_clip():
                        value_to_send = 127
                        if clip_slot._clip_slot.clip.is_triggered:
                            if clip_slot._clip_slot.clip.will_record_on_start:
                                value_to_send = clip_slot._triggered_to_record_value
                            else:
                                value_to_send = clip_slot._triggered_to_play_value
                        '''
                        elif clip_slot._clip_slot.clip.is_playing:
                            if clip_slot._clip_slot.clip.is_recording:
                                value_to_send = 127
                                #########      CLIPS PLAYING WILL FLASH
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                            else:
                                for i in range(2000):
                                    if i % 50 == 0:
                                        button.send_value(127)
                                    else:
                                        button.send_value(0)
                        '''
                    elif clip_slot._clip_slot.is_triggered:
                        if clip_slot._clip_slot.will_record_on_start:
                            value_to_send = clip_slot._triggered_to_record_value
                        else:
                            value_to_send = clip_slot._triggered_to_play_value
                    elif clip_slot._clip_slot.is_playing:
                        if clip_slot._clip_slot.is_recording:
                            value_to_send = clip_slot._recording_value
                        else:
                            value_to_send = clip_slot._started_value
                    elif clip_slot._clip_slot.controls_other_clips:
                        value_to_send = 0
                '''
                if value_to_send in range(128):
                    button.send_value(value_to_send)
                else:
                    button.turn_off()
                '''

    """                                 MODIFIERS, MODES, KEYS CONFIG                                             """

    #MODES ARE HERE: INITIALIZATIONS, DISCONNECTS BUTTONS, SLIDERS, ENCODERS
    def _clear_controls(self):
        # TURNING OFF ALL LEDS IN MATRIX
        self._turn_off_matrix()
        # SESSION
        resetsend_controls = []
        self.mixer.send_controls = []
        for scene_index in range(num_scenes):
            scene = self.session.scene(scene_index)
            scene.set_launch_button(None)
            for track_index in range(num_tracks):
                clip_slot = scene.clip_slot(track_index)
                clip_slot.set_launch_button(None)
        self.session.set_stop_track_clip_buttons(None)
        self.session.set_stop_all_clips_button(None)
            # REMOVE LISTENER TO SESSION MOVES
        if self.session.offset_has_listener(self.__update_matrix):
            self.session.remove_offset_listener(self.__update_matrix)
        self.session.set_stop_all_clips_button(None)
        # MIXER
        self.mixer._set_send_nav(None, None)
        for track_index in range(num_tracks):
            strip = self.mixer.channel_strip(track_index)
            strip.set_solo_button(None)
            strip.set_mute_button(None)
            strip.set_arm_button(None)
            resetsend_controls.append(None)
            strip.set_select_button(None)
            for i in range(12):
                self.mixer.send_controls.append(None)
            strip.set_send_controls(tuple(self.mixer.send_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        # VIEW
        self.view.set_device_nav_buttons(None, None)
        detailclip_view_controls = []
        for track_index in range(num_tracks):
            detailclip_view_controls.append(None)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE PARAMETERS
        device_param_controls = []
        self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(None)
        self.device.set_lock_button(None)
        # TRANSPORT
        self.transport.set_stop_button(None)
        self.transport.set_play_button(None)
        self.transport.set_record_button(None)
        self.transport._set_quant_toggle_button(None)
        self.transport.set_metronome_button(None)
        self.transport._set_tempo_buttons(None, None)

        self.log_message("Controls Cleared")

    def _set_normal_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.name = 'Mixer_ChannelStrip_' + str(index)
            self.mixer._update_send_index(self.mixer.sends_index)
            strip.set_volume_control(SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_volumefader_cc[index]))
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        ### SET ARM, SOLO, MUTE
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip.set_solo_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_solo_cc[index]))
            strip.set_mute_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_mute_cc[index]))
            strip.set_arm_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_arm_cc[index]))
            # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
            for i in range(12):
                self.mixer.send_controls.append(None)
            self.mixer.send_controls[self.mixer.sends_index] = EncoderElement(MIDI_CC_TYPE, CHANNEL, mixer_sendknob_cc[index], Live.MidiMap.MapMode.absolute)
            strip.set_send_controls(tuple(self.mixer.send_controls))
            strip._invert_mute_feedback = True
        self.mixer._update_send_index(self.mixer.sends_index)


    def _set_alt_mode(self):
        is_momentary = True
        self.mixer._set_send_nav(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_up), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, send_down))
        stop_track_controls = []
        resetsend_controls = []
        button = None
        buttons = None
        # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB
        for index in range(num_tracks):
            strip = self.mixer.channel_strip(index)
            strip.set_select_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_select_cc[index]))
            button = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, stop_track_cc[index])
            stop_track_controls.append(button)
            buttons = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, track_resetsend_cc[index])
            resetsend_controls.append(buttons)
        self.session.set_stop_track_clip_buttons(tuple(stop_track_controls))
        self.mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self.mixer._update_send_index(self.mixer.sends_index)


    def _set_ctrl_mode(self):
        # CLIP/DEVICE VIEW TOGGLE
        is_momentary = True
        self.view.set_device_nav_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_left_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, device_right_cc))
        button = None
        detailclip_view_controls = []
        for index in range(num_tracks):
            button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, detailclip_view_cc[index])
            detailclip_view_controls.append(button)
        self.view.set_buttons(tuple(detailclip_view_controls))
        # DEVICE ON/OFF, LOCK AND PARAMETERS
        device_param_controls = []
        onoff_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, onoff_device_cc)
        setlock_control = ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, lock_device_cc)
        for index in range(num_tracks):
            knob = None
            knob = EncoderElement(MIDI_CC_TYPE, CHANNEL, device_param_cc[index], Live.MidiMap.MapMode.absolute)
            device_param_controls.append(knob)
        if None not in device_param_controls:
            self.device.set_parameter_controls(tuple(device_param_controls))
        self.device.set_on_off_button(onoff_control)
        self.device.set_lock_button(setlock_control)
        # TRANSPORT
        # self.transport.set_stop_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_stop_cc))
        # self.transport.set_play_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_play_cc))
        # self.transport.set_record_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_record_cc))
        self.transport._set_quant_toggle_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_quantization_cc))
        self.transport.set_metronome_button(ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, transport_metronome_cc))
        self.transport._set_tempo_buttons(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempodown_cc), ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, transport_tempoup_cc))
        # SESSION STOP ALL CLIPS AND SCENE LAUNCH
        self.session.set_stop_all_clips_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_stopall_cc))
        for index in range(num_scenes):
            self.session.scene(index).set_launch_button(ButtonElement(is_momentary, MIDI_CC_TYPE, CHANNEL, session_scenelaunch_cc[index]))

    def _set_modifiers_buttons(self):
        is_momentary = True
        self._shift_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, shift_mod)
        self._alt_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, alt_mod)
        self._ctrl_button = ButtonElement(not is_momentary, MIDI_CC_TYPE, CHANNEL, ctrl_mod)

        if (self._shift_button != None):
            self._shift_button.add_value_listener(self._shift_value)

        if (self._alt_button != None):
            self._alt_button.add_value_listener(self._alt_value)

        if (self._ctrl_button != None):
            self._ctrl_button.add_value_listener(self._ctrl_value)
        #INIT NORMAL MODE
        self._manage_modes(0)

    # MODIFIERS LISTENERS FUNCS ARE HERE
    def _shift_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._shift_button, ButtonElement)
        if value == 127:
            if self._shift_button_pressed is False:
                self._unpress_modes()
                self._shift_button_pressed = True
                self._manage_modes(0)

    def _alt_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._alt_button, ButtonElement)
        if value == 127:
            if self._alt_button_pressed is False:
                self._unpress_modes()
                self._alt_button_pressed = True
                self._manage_modes(2)

    def _ctrl_value(self, value):
        assert isinstance(value, int)
        assert isinstance(self._ctrl_button, ButtonElement)
        if value == 127:
            if self._ctrl_button_pressed is False:
                self._unpress_modes()
                self._ctrl_button_pressed = True
                self._manage_modes(3)

    def _manage_modes(self, mode_index):
        if mode_index == 0:
            self._clear_controls()
            self._set_normal_mode()
            # self._shift_button.turn_on()
            self._alt_button.turn_on()
            self._ctrl_button.turn_on()
            self.log_message("NORMAL ON")
        elif mode_index == 2:
            self._clear_controls()
            self._set_alt_mode()
            self._alt_button.turn_on()
            self._shift_button.turn_off()
            self._ctrl_button.turn_off()
            self.log_message("ALT ON")
        elif mode_index == 3:
            self._clear_controls()
            self._set_ctrl_mode()
            self._ctrl_button.turn_on()
            self._shift_button.turn_off()
            self._alt_button.turn_off()
            self.log_message("CTRL ON")

    def _unpress_modes(self):
        self._shift_button_pressed = False
        self._alt_button_pressed = False
        self._ctrl_button_pressed = False

    def _turn_off_matrix(self):
        for index in range(24):
            self._send_midi(tuple([176,index+16,0]))

    def disconnect(self):
        """clean things up on disconnect"""
        self.log_message(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolShift log closed =--------------") #Create entry in log file
        self._clear_controls()
        self.session = None
        self.mixer = None
        self.view = None
        self.device = None
        self.transport = None
        # MODES
        self._shift_button = None
        self._alt_button = None
        self._ctrl_button = None
        # SENDS
        self.send_button_up = None
        self.send_button_down = None
        self.send_controls = []
        self.send_reset = []

        self.set_device_component(None)
        ControlSurface.disconnect(self)
        return None
コード例 #12
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
コード例 #13
0
class NanoKontrolLP95(ControlSurface):
    __module__ = __name__
    __doc__ = " NanoKontrolLP95 controller script "

    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)
        #self._suppress_session_highlight = True
        self._suppress_send_midi = True  # Turn off rebuild MIDI map until after we're done setting up
        Live.Base.log(time.strftime("%d.%m.%Y %H:%M:%S", time.localtime()) + "--------------= NanoKontrolLP95 log opened =--------------") # Writes message into Live's main log file. This is a ControlSurface method.
        with self.component_guard():
            # OBJECTS
            self._session = None #session object
            self._mixer = None #mixer object
            self._transport = None #transport object
            self._last_button_time = time.time()
            self._io_list_index = 0
            
            self._setup_controls()

            self._setup_session_control()  # Setup the session object
            self._setup_mixer_control() # Setup the mixer object
            self._session.set_mixer(self._mixer) # Bind mixer to session
            self._setup_transport_control() # Setup transport object

            self._set_mode_button()
            self._set_normal_mode()
            self._track = self.song().view.selected_track
            
            self.set_highlighting_session_component(self._session)

            self._flash_counter = 0
            self._flash_on = True
            
            for component in self.components:
                component.set_enabled(True)

        self._suppress_send_midi = True # Turn rebuild back on, once we're done setting up
        Live.Base.log("NanoKontrolLP95 Loaded !")

    def disconnect(self):
        """clean things up on disconnect"""
        if self._cycle_button != None:
            self._cycle_button.remove_value_listener(self._cycle_button_value)
        self._clear_controls()
        self._transport.set_stop_button(None)
        self._transport.set_play_button(None)
        self._transport.set_rec_button(None)

        self._solo_buttons = None 
        self._mute_buttons = None 
        self._arm_buttons = None 
        self._knobs = None 
        self._faders = None 

        self._ff_button = None
        self._rwd_button = None
        self._play_button = None
        self._stop_button = None
        self._rec_button = None
        
        self._track_left_button = None
        self._track_right_button = None
        self._cycle_button = None
        
        self._set_button = None    
        self._mrk_left_button = None
        self._mrk_right_button = None
        
        self._session = None
        self._mixer = None
        self._transport = None

        ControlSurface.disconnect(self)
    
    def _setup_controls(self):
        self._track_left_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_left_btn)
        self._track_right_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_right_btn)    
        self._cycle_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, cycle_btn)
        self._cycle_button_active = False             
        
        self._set_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, set_btn)        
        self._mrk_left_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, mrk_left_btn)
        self._mrk_right_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, mrk_right_btn)

        self._ff_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, ff_btn)
        self._rwd_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, rwd_btn)        
        self._play_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, play_btn)
        self._stop_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, stop_btn)
        self._rec_button = ButtonElement(True, MIDI_CC_TYPE, CHANNEL, rec_btn)
        
        self._solo_buttons = [ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_solo_cc[index]) for index in range(num_tracks)] 
        self._mute_buttons = [ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_mute_cc[index]) for index in range(num_tracks)] 
        self._arm_buttons = [ButtonElement(True, MIDI_CC_TYPE, CHANNEL, track_arm_cc[index]) for index in range(num_tracks)] 
        self._knobs = [SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_knob_cc[index]) for index in range(num_tracks)] 
        self._faders = [SliderElement(MIDI_CC_TYPE, CHANNEL, mixer_fader_cc[index]) for index in range(num_tracks)] 
    
    
    def _setup_session_control(self):
        # CREATE SESSION, SET OFFSETS, BUTTONS NAVIGATION AND BUTTON MATRIX
        self._session = SpecialSessionComponent(num_tracks, num_scenes) #(num_tracks, num_scenes)
        self._session.set_offsets(0, 0)

    def _setup_mixer_control(self):
        #CREATE MIXER, SET OFFSET (SPECIALMIXERCOMPONENT USES SPECIALCHANNELSTRIP THAT ALLOWS US TO UNFOLD TRACKS WITH TRACK SELECT BUTTON)
        self._mixer = SpecialMixerComponent(self, num_tracks, 0, False, False) # 8 tracks, 2 returns, no EQ, no filters
        self._mixer.name = 'Mixer'
        self._mixer.set_track_offset(0) #Sets start point for mixer strip (offset from left)
        self._mixer.set_select_buttons(self._track_right_button,self._track_left_button)
        self._mixer.set_knobs(self._knobs)
    def _setup_transport_control(self):
        # CREATE TRANSPORT DEVICE
        self._transport = SpecialTransportComponent(self)
        self._transport.set_stop_button(self._stop_button)
        self._transport.set_play_button(self._play_button)
        self._transport.set_rec_button(self._rec_button)
        
    def connect_script_instances(self, instanciated_scripts):
        #Live.Base.log("connect_script_instances - Start")
        #Live.Base.log("connect_script_instances - self._control_surfaces()=" + str(self._control_surfaces()))
        if(linked):
            for control_surface in self._control_surfaces():
                control_surface_type = str(control_surface)
                for sync_master in SYNC_TO_LIST:
                    if(control_surface_type.count(sync_master)>0):
                        control_surface_session = control_surface.highlighting_session_component()
                        if control_surface_session:
                            self._session.sync_to(control_surface_session)
                            self._on_track_list_changed()
                            break


    def _clear_controls(self):
            
        if (self._ff_button != None):
            self._ff_button.remove_value_listener(self._out_value)
            self._ff_button.turn_off()
    
        if (self._rwd_button != None):
            self._rwd_button.remove_value_listener(self._in_value)
            self._rwd_button.turn_off()           
            
        if (self._set_button != None):
            self._set_button.remove_value_listener(self._monitor_value)
            self._set_button.remove_value_listener(self._dup_track_value)           
            
        if (self._mrk_left_button != None):
            self._mrk_left_button.remove_value_listener(self._sub_in_value)
            self._mrk_left_button.remove_value_listener(self._new_midi_value)            
            
        if (self._mrk_right_button != None):
            self._mrk_right_button.remove_value_listener(self._sub_out_value)
            self._mrk_right_button.remove_value_listener(self._new_audio_value)            

        # SESSION
        resetsend_controls = []
        self._mixer.send_controls = []
        self._session.set_stop_track_clip_buttons(None)

        # MIXER
        self._mixer._set_send_nav(None, None)
        for track_index in range(num_tracks):
            strip = self._mixer.channel_strip(track_index)
            strip.set_solo_button(None)
            strip.set_mute_button(None)
            strip.set_arm_button(None)
            resetsend_controls.append(None)
            strip.set_select_button(None)
            for i in range(12):
                self._mixer.send_controls.append(None)
            strip.set_send_controls(tuple(self._mixer.send_controls))
        self._mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self.log_message("Controls Cleared")

    def _set_mode_button(self):
        if self._cycle_button != None:
            self._cycle_button.remove_value_listener(self._cycle_button_value)
            self._cycle_button.add_value_listener(self._cycle_button_value)
            self._cycle_button.set_light(self._cycle_button_active)

    def _cycle_button_value(self, value):
        assert (value in range(128))        
        if self._cycle_button != None:
            if value is not 0:
                self._cycle_button_active = not self._cycle_button_active
                self._clear_controls()
                if self._cycle_button_active:
                    self._set_alt_mode()
                else:
                    self._set_normal_mode()
                self.update()   
            
    def _set_normal_mode(self):
        for index in range(num_tracks):
            strip = self._mixer.channel_strip(index)
            strip.set_solo_button(self._solo_buttons[index])
            strip.set_mute_button(self._mute_buttons[index])
            strip.set_arm_button(self._arm_buttons[index])
            strip.set_pan_control(self._knobs[index])
            strip.set_volume_control(self._faders[index])
        self._set_in_out_nav_listeners()    
        self.show_message("IN/OUT SETUP - MUTE SOLO ARM")
                        
    def _set_alt_mode(self):
        self._mixer._set_send_nav(self._ff_button, self._rwd_button)
        stop_track_controls = []
        resetsend_controls = []
        # SET SESSION TRACKSTOP, TRACK SELECT, RESET SEND KNOB
        for index in range(num_tracks):
            strip = self._mixer.channel_strip(index)
            strip.set_select_button(self._solo_buttons[index])
            stop_track_controls.append(self._arm_buttons[index])
            resetsend_controls.append(self._mute_buttons[index])
        self._session.set_stop_track_clip_buttons(tuple(stop_track_controls))
        self._mixer.set_resetsend_buttons(tuple(resetsend_controls))
        self._mixer._update_send_index()
        self._set_create_track_listeners()
        self.show_message("TRACK CREATE DEL DUPE - SEL STOP RESET SEND")
        
    def _set_in_out_nav_listeners(self):
        if (self._ff_button != None):
            self._ff_button.add_value_listener(self._out_value)
    
        if (self._rwd_button != None):
            self._rwd_button.add_value_listener(self._in_value)
            
        if (self._set_button != None):
            self._set_button.add_value_listener(self._monitor_value)
            
        if (self._mrk_left_button != None):
            self._mrk_left_button.add_value_listener(self._sub_in_value)
            
        if (self._mrk_right_button != None):
            self._mrk_right_button.add_value_listener(self._sub_out_value)                                                
        self.update()
           
    def _monitor_value(self, value):
        now = time.time()
        if(value is not 0):
            self._last_button_time = now
        else:
            song = self.song()
            if self._track in song.tracks:
                if now - self._last_button_time < LONG_PRESS:            
                    if not self._track.is_foldable:
                        self._track.current_monitoring_state = (self._track.current_monitoring_state + 1) % 3
                else:  
                    self._set_default_io()            

    def _set_default_io(self):
        if self._track.has_midi_input:
                self._track.input_routing_type = list(self._track.available_input_routing_types)[0]
                if self._track.has_audio_output:
                    if self._track.is_grouped:
                        self._track.output_routing_type = list(self._track.available_output_routing_types)[2]       
                    else:
                        self._track.output_routing_type = list(self._track.available_output_routing_types)[1]
                else:
                    self._track.output_routing_type = list(self._track.available_output_routing_types)[-1]
        else:
                self._track.input_routing_type = list(self._track.available_input_routing_types)[-1]
                if self._track.is_grouped:
                    self._track.output_routing_type = list(self._track.available_output_routing_types)[2]       
                else:
                    self._track.output_routing_type = list(self._track.available_output_routing_types)[1]
                    
        self._track.input_routing_channel = list(self._track.available_input_routing_channels)[0]            
        self._track.output_routing_channel = list(self._track.available_output_routing_channels)[0]  
        self.show_message("TRACK: " + str(self._track.name) + ' INPUT - OUTPUT RESET ')                             
                                     
    def _in_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_input_routing_types)
            current_routing = self._track.input_routing_type
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.input_routing_type = routings[new_index]
                route = ' INPUT: ' +  str(self._track.input_routing_type.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)
            self.update()
            
    def _out_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_output_routing_types)
            current_routing = self._track.output_routing_type
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.output_routing_type = routings[new_index]
                route = ' OUTPUT: ' +  str(self._track.output_routing_type.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)
        self.update()

    def _sub_in_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_input_routing_channels)
            current_routing = self._track.input_routing_channel
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.input_routing_channel = routings[new_index]
                route = ' SUB_INPUT: ' +  str(self._track.input_routing_channel.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)
            self.update()
     
    def _sub_out_value(self, value):
        if(value is not 0):
            routings = list(self._track.available_output_routing_channels)
            current_routing = self._track.output_routing_channel
            if current_routing in routings:
                new_index = (routings.index(current_routing) + 1) % len(routings)
                self._track.output_routing_channel = routings[new_index]
                route = ' SUB_OUTPUT: ' +  str(self._track.output_routing_channel.display_name)
                self.show_message("TRACK: " + str(self._track.name) + route)                       
            self.update()


    def _on_selected_track_changed(self):
        # ALLOWS TO GRAB THE FIRST DEVICE OF A SELECTED TRACK IF THERE'S ANY
        ControlSurface._on_selected_track_changed(self)
        self._track = self.song().view.selected_track
              
    def update(self):
        ControlSurface.update(self)
        self._cycle_button.set_light(self._cycle_button_active)
        
        
    def _set_create_track_listeners(self):
        if (self._set_button != None):
            self._set_button.add_value_listener(self._dup_track_value)
            
        if (self._mrk_left_button != None):
            self._mrk_left_button.add_value_listener(self._new_midi_value)
            
        if (self._mrk_right_button != None):
            self._mrk_right_button.add_value_listener(self._new_audio_value)                                                
        self.update()            
        
    def _dup_track_value(self, value):
        now = time.time()
        if(value is not 0):
            self._last_button_time = now
        else:
            song = self.song()
            if self._track in song.tracks:
                if now - self._last_button_time < LONG_PRESS:            
                    song.duplicate_track(list(song.tracks).index(self._track))
                else:  
                    song.delete_track(list(song.tracks).index(self._track))

    def _new_audio_value(self, value):
        if(value is not 0):
            self._add_track(self.song().create_audio_track)
            
    def _new_midi_value(self, value):
        if(value is not 0):
            self._add_track(self.song().create_midi_track)
            
    def _add_track(self, func):
        song = self.song()
        index = list(song.tracks).index(self._track) + 1
        if index < len(song.tracks) and index >0:
            track = song.tracks[index]
            if track.is_foldable or track.is_grouped:
                while index < len(song.tracks) and song.tracks[index].is_grouped:
                    index += 1
        func(index)
        
    @profile
    def update_display(self):
        super(NanoKontrolLP95, self).update_display()
        self._flash_counter = self._flash_counter + 1
        if self._cycle_button_active  == True:
            if(self._flash_counter % 2  == 0):
                if (self._flash_on == True):
                    self._cycle_button.send_value(127) 
                else:
                    self._cycle_button.send_value(0) 
                self._flash_on = not self._flash_on
                self._flash_counter = self._flash_counter % 4                                                  
コード例 #14
0
class QuNeo(ControlSurface):
    __doc__ = " Minimal Script for Volume control via _Framework by @djnsm / Data Mafia "
    __module__ = __name__
    
    # INIT FUNCTION FOR QUNEO   
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance) # in aaa
        with self.component_guard(): # new for Live9 / Py
          self._suppress_session_highlight = True
          self._suppress_send_midi = True
       #   self.session = None #===========
          self.mixer = None
          self.box_width = box_width
         # self.transport = None -----marwei
         # self.led_value = None ------marwei
          #self._note_input = [] -------marwei
          
          # marwei added for web app++
          self.gutter = gutter # see param info
 
          self.volume_control = None
 
          self._setup_mixer_control() #------- needed
          #self._setup_session_control() # -----------
          #self.session.set_mixer(self.mixer) #----------
 
          # @marwei --- needed? 8apr
          self._suppress_session_highlight = False
                  
    # DISCONNECT FUNCTION
    def disconnect(self):
        self.mixer
        self.session
            
       #self._note_input = None
        ControlSurface.disconnect(self)
        return None

    
    # CREATE A SLIDER @marwei reqd
    def slider(self, channel, value):
        if (value != -1):
            return SliderElement(MIDI_CC_TYPE, channel, value)
        else:
            return None
            
            
    # REASSIGN MIXER
    def _reassign_mixer_control(self, shift_value):
        self.volume_control = self.slider(midi_channel, SELECTED_VOL)
        if (self.volume_control != None):
            self.mixer.selected_strip().set_volume_control(self.volume_control)
        else:
            self.mixer.selected_strip().set_volume_control(None)
    
    # SETUP MIXER
    def _setup_mixer_control(self):
        
        self.mixer = SpecialMixerComponent(self.box_width, self) # get a local mixer object ready
        self.mixer.name = 'Mixer' # name
        self.mixer.set_track_offset(self.gutter)  # gutter ----marwei
        # compare width with track vol count to qualify -- put somewhere else 
        for index in range(self.box_width): # @marwei must kill this style and count
            self.mixer.channel_strip(index).set_volume_control(self.slider(midi_channel, track_volume[index]))
            
コード例 #15
0
ファイル: QuNeo.py プロジェクト: uniphonic/MidiScripts
class QuNeo(ControlSurface):
    """ Script for Keith McMillen's QuNeo Multi-Touchpad Controller """
    __module__ = __name__
    _active_instances = []

    def _combine_active_instances():
        support_devices = False
        for instance in QuNeo._active_instances:
            support_devices |= instance._device_component != None

        track_offset = 0
        for instance in QuNeo._active_instances:
            instance._activate_combination_mode(track_offset, support_devices)
            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)
        self._suppress_session_highlight = True
        self._suppress_send_midi = True
        self._suggested_input_port = 'QUNEO'
        self._suggested_output_port = 'QUNEO'
        self.num_tracks = 7
        self.num_scenes = 4
        self.session = None
        self.mixer = None
        self.transport = None
        self.led_value = None
        self._note_input = []
        self.shift_button = None
        self.sequencer_button = None
        self.launch_button = None
        self.seq_offset_down = None
        self.seq_offset_up = None
        self.seq_offset_left = None
        self.seq_offset_right = None
        self.stop_all_clips = None
        self.track_bank_right = None
        self.track_bank_left = None
        self.scene_bank_down = None
        self.scene_bank_up = None
        self.beat_table = []
        self.sends = []
        self.arm_buttons = None
        self.mute_buttons = None
        self.solo_buttons = None
        self.shift_buttons = []
        self.sequencer_buttons = None
        self.scene_launch_buttons = None
        self.stop_track_buttons = None
        self.clip_slot_buttons = None
        self.instrument_buttons = None
        self.volume_control = None
        self.pan_control = None
        self.current_mode = 0
        self.set_shift_button(ConfigurableButtonElement(True, MIDI_NOTE_TYPE, PAD_CHANNEL, SHIFT_BUTTON, 127))
        self._setup_transport_control()
        self._setup_mixer_control()
        self._setup_session_control()
        self.session.set_mixer(self.mixer)
        self._shift_mode(0)
        self._set_mode(0)
        app = Live.Application.get_application()
        maj = app.get_major_version()
        min = app.get_minor_version()
        bug = app.get_bugfix_version()
        self.show_message(str(maj) + '.' + str(min) + '.' + str(bug))
        self.set_suppress_rebuild_requests(False)

    def disconnect(self):
        self.mixer
        self.session
        if self.shift_button != None:
            self.shift_button.remove_value_listener(self._shift_value)
            self.shift_button = None
        if self.shift_buttons != None:
            for button in self.shift_buttons:
                button.remove_value_listener(self._shift_buttons_value)

            self.shift_buttons = None
        self._note_input = None
        ControlSurface.disconnect(self)

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

    def set_shift_button(self, button):
        if not (button == None or isinstance(button, ButtonElement)):
            raise AssertionError
            if self.shift_button != button:
                if self.shift_button != None:
                    self.shift_button.remove_value_listener(self._shift_value)
                self.shift_button = button
                self.shift_button != None and self.shift_button.add_value_listener(self._shift_value)

    def update_mode(self, mode):
        if mode != None:
            self._set_mode(mode)
            self.current_mode = mode

    def set_shift_buttons(self, buttons):
        if buttons != None:
            if self.shift_buttons != buttons:
                self.shift_buttons.remove_value_listener(self._shift_buttons_value)
            self.shift_buttons = buttons
            if self.shift_buttons != None:
                for button in self.shift_buttons:
                    raise isinstance(button, ButtonElement) or AssertionError
                    button.add_value_listener(self._shift_buttons_value, identify_sender=True)

        else:
            if self.shift_buttons != None:
                for button in self.shift_buttons:
                    button.remove_value_listener(self._shift_buttons_value)

            self.shift_buttons = None

    def _shift_buttons_value(self, value, sender):
        raise self.shift_buttons != None or AssertionError
        raise value in range(128) or AssertionError
        mode = int(sender._note * 0.5)
        self.update_mode(mode)

    def _shift_value(self, value):
        if not value in range(128):
            raise AssertionError
            raise self.shift_button != None or AssertionError
            value != 0 and self._shift_mode(1)
            self.shift_button.turn_on()
        else:
            self._shift_mode(0)
            self.shift_button.turn_off()

    def _shift_mode(self, value):
        if value != 0:
            self.set_suppress_rebuild_requests(True)
            self._reassign_grid(0)
            self._reassign_mixer_control(1)
            self.set_suppress_rebuild_requests(False)
        else:
            None
            self._set_mode(self.current_mode)
            self._reassign_mixer_control(1)

    def _update_grid(self):
        if self.sequencer_buttons != None:
            self.session.set_sequencer_buttons(self.sequencer_buttons)
        else:
            self.session.set_sequencer_buttons(None)
        if self.seq_offset_left != None and self.seq_offset_right != None:
            self.session.set_seq_measure_offset(self.seq_offset_left, self.seq_offset_right)
        else:
            self.session.set_seq_measure_offset(None, None)
        if self.seq_offset_up != None and self.seq_offset_down != None:
            self.session.set_seq_note_offset(self.seq_offset_up, self.seq_offset_down)
        else:
            self.session.set_seq_note_offset(None, None)
        if self.launch_button != None:
            self.session.set_slot_launch_button(self.launch_button)
        else:
            self.session.set_slot_launch_button(None)
        if self.scene_launch_buttons != None:
            for index in range(len(self.scene_launch_buttons)):
                self.session.scene(index).set_launch_button(self.scene_launch_buttons[index])

        else:
            for index in range(4):
                self.session.scene(index).set_launch_button(None)

        if self.stop_track_buttons != None:
            self.session.set_stop_track_clip_buttons(tuple(self.stop_track_buttons))
        else:
            self.session.set_stop_track_clip_buttons(None)
        if self.stop_all_clips != None:
            self.session.set_stop_all_clips_button(self.stop_all_clips)
        else:
            self.session.set_stop_all_clips_button(None)
        if self.track_bank_right != None and self.track_bank_left != None:
            self.session.set_track_bank_buttons(self.track_bank_right, self.track_bank_left)
        else:
            self.session.set_track_bank_buttons(None, None)
        if self.scene_bank_up != None and self.scene_bank_down != None:
            self.session.set_scene_bank_buttons(self.scene_bank_up, self.scene_bank_down)
        else:
            self.session.set_scene_bank_buttons(None, None)
        for row in range(4):
            for col in range(7):
                self.clip = self.session.scene(row).clip_slot(col)
                if self.clip_slot_buttons != None:
                    self.clip.set_triggered_to_play_value(30)
                    self.clip.set_triggered_to_record_value(RED_HI)
                    self.clip.set_started_value(30)
                    self.clip.set_recording_value(RED_HI)
                    self.clip.set_stopped_value(80)
                    self.clip.set_triggered_to_record_value(6)
                    self.clip.set_launch_button(self.clip_slot_buttons[row][col])
                else:
                    self.clip.set_launch_button(None)

    def turn_off_all_buttons(self):
        self.arm_buttons = None
        self.mute_buttons = None
        self.solo_buttons = None
        self.scene_launch_buttons = None
        self.stop_track_buttons = None
        if self.clip_slot_buttons != None:
            for row in range(4):
                for col in range(7):
                    button = self.clip_slot_buttons[row][col]
                    button.turn_off()

        self.clip_slot_buttons = None
        if self.shift_buttons != None:
            for button in self.shift_buttons:
                button.turn_off()
                button.remove_value_listener(self._shift_buttons_value)

        if self.sequencer_buttons != None:
            for button in self.sequencer_buttons:
                button.count = 0
                button.note_on()

        self.instrument_buttons = None
        self.shift_buttons = None
        self.sequencer_buttons = None
        self.clip_slot_buttons = None
        self.launch_button = None
        self.stop_all_clips = None
        self.track_bank_left = None
        self.track_bank_right = None
        self.scene_bank_up = None
        self.scene_bank_down = None
        self.seq_offset_left = None
        self.seq_offset_right = None
        self.seq_offset_up = None
        self.seq_offset_down = None

    def _set_mode(self, mode):
        self.turn_off_all_buttons()
        if mode == 0:
            self.stop_track_buttons = []
            self.scene_launch_buttons = []
            self.track_bank_left = self.button(PAD_CHANNEL, SESSION_LEFT)
            self.track_bank_right = self.button(PAD_CHANNEL, SESSION_RIGHT)
            self.scene_bank_up = self.button(PAD_CHANNEL, SESSION_UP)
            self.scene_bank_down = self.button(PAD_CHANNEL, SESSION_DOWN)
            self.stop_all_clips = self.led_button(GRID_CHANNEL, STOP_ALL_CLIPS, 100)
            self.launch_button = self.led_button(GRID_CHANNEL, SLOT_LAUNCH, RED_HI)
            self.clip_slot_buttons = []
            for row in range(4):
                self.clip_slot_buttons.append([])
                for col in range(7):
                    self.clip_slot_buttons[row].append(self.button(GRID_CHANNEL, CLIP_NOTE_MAP[row][col]))

            self.mute_buttons = []
            self.solo_buttons = []
            self.arm_buttons = []
            for index in range(7):
                self.mute_buttons.append(self.led_button(GRID_CHANNEL, TRACK_MUTE[index], GREEN_HI))
                self.solo_buttons.append(self.led_button(GRID_CHANNEL, TRACK_SOLO[index], ORANGE_HI))
                self.arm_buttons.append(self.led_button(GRID_CHANNEL, TRACK_ARM[index], RED_HI))
                self.stop_track_buttons.append(self.led_button(GRID_CHANNEL, STOP_TRACK[index], 100))

            for scene in range(4):
                self.scene_launch_buttons.append(self.led_button(GRID_CHANNEL, SCENE_LAUNCH[scene], GREEN_LO))

            self._update_session()
            self._update_grid()
        elif mode == 1:
            self.seq_offset_left = self.button(PAD_CHANNEL, SESSION_LEFT)
            self.seq_offset_right = self.button(PAD_CHANNEL, SESSION_RIGHT)
            self.seq_offset_up = self.button(PAD_CHANNEL, SESSION_UP)
            self.seq_offset_down = self.button(PAD_CHANNEL, SESSION_DOWN)
            self.sequencer_buttons = []
            for row in range(8):
                for col in range(8):
                    self.sequencer_buttons.append(self.led_button(GRID_CHANNEL, CLIP_NOTE_MAP[row][col], GREEN_HI))

            self._update_session()
            self._update_grid()
            self.session.clear_led()
            self.session.update_notes()
            self.session.on_device_changed()
        else:
            self.track_bank_left = self.button(PAD_CHANNEL, SESSION_LEFT)
            self.track_bank_right = self.button(PAD_CHANNEL, SESSION_RIGHT)
            self.scene_bank_up = self.button(PAD_CHANNEL, SESSION_UP)
            self.scene_bank_down = self.button(PAD_CHANNEL, SESSION_DOWN)
            self._update_session()
            self._update_grid()

    def _reassign_grid(self, value):
        if value == 0:
            self.turn_off_all_buttons()
            self.shift_buttons = []
            for index in range(2):
                self.shift_buttons.append(self.led_button(GRID_CHANNEL, TRACK_ARM[index], 127))
                if index == self.current_mode:
                    self.shift_buttons[index].send_value(127, True)
                else:
                    self.shift_buttons[index].send_value(40, True)

            self._update_session()
            self._update_grid()
        else:
            None

    def button(self, channel, value):
        is_momentary = True
        if value != -1:
            return ButtonElement(is_momentary, MIDI_NOTE_TYPE, channel, value)
        else:
            return None

    def led_button(self, channel, value, vel):
        is_momentary = True
        if value != -1:
            return ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, channel, value, vel)
        else:
            return None

    def slider(self, channel, value):
        if value != -1:
            return SliderElement(MIDI_CC_TYPE, channel, value)
        else:
            return None

    def assign_encoder(self, channel, value):
        if value != -1:
            return EncoderElement(MIDI_CC_TYPE, channel, value, Live.MidiMap.MapMode.relative_two_compliment)
        else:
            return None

    def _reassign_mixer_control(self, shift_value):
        if shift_value == 1:
            for index in range(2):
                self.sends.append(self.slider(SLIDER_CHANNEL, SELECTED_SENDS[index]))

            self.volume_control = self.slider(SLIDER_CHANNEL, SELECTED_VOL)
            self.pan_control = self.slider(SLIDER_CHANNEL, SELECTED_PAN)
        if self.sends != None:
            self.mixer.selected_strip().set_send_controls(tuple(self.sends))
        else:
            self.mixer.selected_strip().set_send_controls(tuple(None))
        if self.volume_control != None:
            self.mixer.selected_strip().set_volume_control(self.volume_control)
        else:
            self.mixer.selected_strip().set_volume_control(None)
        if self.pan_control != None:
            self.mixer.selected_strip().set_pan_control(self.pan_control)
        else:
            self.mixer.selected_strip().set_pan_control(None)

    def _update_session(self):
        if self.shift_buttons != None:
            self.set_shift_buttons(self.shift_buttons)
        else:
            self.set_shift_buttons(None)
        for index in range(7):
            if self.arm_buttons != None:
                self.mixer.channel_strip(index).set_arm_button(self.arm_buttons[index])
            else:
                self.mixer.channel_strip(index).set_arm_button(None)
            if self.solo_buttons != None:
                self.mixer.channel_strip(index).set_solo_button(self.solo_buttons[index])
            else:
                self.mixer.channel_strip(index).set_solo_button(None)
            if self.mute_buttons != None:
                self.mixer.channel_strip(index).set_invert_mute_feedback(True)
                self.mixer.channel_strip(index).set_mute_button(self.mute_buttons[index])
            else:
                self.mixer.channel_strip(index).set_mute_button(None)

    def _setup_transport_control(self):
        self.transport = SpecialTransportComponent()
        self.transport.set_metronome_button(self.led_button(PAD_CHANNEL, METRONOME, 127))
        self.transport.set_play_button(self.led_button(PAD_CHANNEL, PLAY, 127))
        self.transport.set_stop_button(self.led_button(PAD_CHANNEL, STOP, 127))
        self.transport.set_record_button(self.led_button(PAD_CHANNEL, REC, 127))
        self.transport.set_overdub_button(self.led_button(PAD_CHANNEL, OVERDUB, 127))
        self.transport.set_tempo_buttons(self.led_button(PAD_CHANNEL, TEMPO_UP, 127), self.led_button(PAD_CHANNEL, TEMPO_DOWN, 127))

    def _setup_mixer_control(self):
        self.mixer = SpecialMixerComponent(self.num_tracks, self)
        self.mixer.name = 'Mixer'
        self.mixer.set_track_offset(0)
        self.mixer.set_select_buttons(self.button(PAD_CHANNEL, TRACK_RIGHT), self.button(PAD_CHANNEL, TRACK_LEFT))
        self.mixer.set_crossfader_control(self.slider(SLIDER_CHANNEL, CROSSFADER))
        for index in range(4):
            self.mixer.channel_strip(index).set_volume_control(self.slider(SLIDER_CHANNEL, TRACK_VOL[index]))

        self.num_o_tracks = self.song().visible_tracks
        if self.num_o_tracks != None:
            index_count = -1
            index_table = []
            for index in self.song().visible_tracks:
                index_count += 1
                if index.has_midi_output != True:
                    index_table.append(index_count)
                else:
                    None

            if index_table != None:
                for index in range(len(index_table)):
                    x = index_table[index]
                    if x > 3:
                        None
                    else:
                        None

    def _setup_session_control(self):
        self.session = SpecialSessionComponent(self.num_tracks, self.num_scenes, self)
        self.session.set_offsets(0, 0)
        self.session.set_select_buttons(self.button(PAD_CHANNEL, SCENE_DOWN), self.button(PAD_CHANNEL, SCENE_UP))
        self.session.set_clip_loop_start(self.slider(SLIDER_CHANNEL, 6))
        self.session.set_clip_loop_length(self.slider(SLIDER_CHANNEL, 7))

    def _on_selected_scene_changed(self):
        ControlSurface._on_selected_scene_changed(self)

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

    def _activate_combination_mode(self, track_offset, support_devices):
        self._session.link_with_track_offset(track_offset)
コード例 #16
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

		
コード例 #17
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)
コード例 #18
0
class MainSelectorComponent(ModeSelectorComponent):
	""" Class that reassigns the buttons on the Spark to different functions """

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

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

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

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

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

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

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

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

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

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

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

	def number_of_modes(self):
		return 4

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

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

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

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

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

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

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

			#self._parent.log_message("Updated")
			

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

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

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

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

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

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

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

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


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


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

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

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

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



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

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

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



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

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

	def on_selected_track_changed(self):
		all_tracks = ((self.song().tracks + self.song().return_tracks))
		selected_track = self.song().view.selected_track
		self._previous_track_index = self._selected_track_index
		self._selected_track_index = list(all_tracks).index(selected_track)
		self.update()
コード例 #19
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
コード例 #20
0
class SubSelectorComponent(ModeSelectorComponent):
    __module__ = __name__
    __doc__ = ' Class that handles different mixer modes '

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

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



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

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

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



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



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

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




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



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



    def number_of_modes(self):
        return 4



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

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



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

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

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



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

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

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

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



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

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

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

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



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

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

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



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

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

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



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

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

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



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

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

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
コード例 #21
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())
コード例 #22
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)
コード例 #23
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
コード例 #24
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)
コード例 #25
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)
コード例 #26
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
コード例 #27
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
コード例 #28
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
コード例 #29
0
class QuNeo(ControlSurface):
    __doc__ = " Minimal Script for Volume control via _Framework by @djnsm / Data Mafia "
    __module__ = __name__

    # INIT FUNCTION FOR QUNEO
    def __init__(self, c_instance):
        ControlSurface.__init__(self, c_instance)  # in aaa
        with self.component_guard():  # new for Live9 / Py
            self._suppress_session_highlight = True
            self._suppress_send_midi = True
            #   self.session = None #===========
            self.mixer = None
            self.box_width = box_width
            # self.transport = None -----marwei
            # self.led_value = None ------marwei
            #self._note_input = [] -------marwei

            # marwei added for web app++
            self.gutter = gutter  # see param info

            self.volume_control = None

            self._setup_mixer_control()  #------- needed
            #self._setup_session_control() # -----------
            #self.session.set_mixer(self.mixer) #----------

            # @marwei --- needed? 8apr
            self._suppress_session_highlight = False

    # DISCONNECT FUNCTION
    def disconnect(self):
        self.mixer
        self.session

        #self._note_input = None
        ControlSurface.disconnect(self)
        return None

    # CREATE A SLIDER @marwei reqd
    def slider(self, channel, value):
        if (value != -1):
            return SliderElement(MIDI_CC_TYPE, channel, value)
        else:
            return None

    # REASSIGN MIXER
    def _reassign_mixer_control(self, shift_value):
        self.volume_control = self.slider(midi_channel, SELECTED_VOL)
        if (self.volume_control != None):
            self.mixer.selected_strip().set_volume_control(self.volume_control)
        else:
            self.mixer.selected_strip().set_volume_control(None)

    # SETUP MIXER
    def _setup_mixer_control(self):

        self.mixer = SpecialMixerComponent(
            self.box_width, self)  # get a local mixer object ready
        self.mixer.name = 'Mixer'  # name
        self.mixer.set_track_offset(self.gutter)  # gutter ----marwei
        # compare width with track vol count to qualify -- put somewhere else
        for index in range(
                self.box_width):  # @marwei must kill this style and count
            self.mixer.channel_strip(index).set_volume_control(
                self.slider(midi_channel, track_volume[index]))
コード例 #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
コード例 #31
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())
コード例 #32
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])
コード例 #33
0
class Serato(ControlSurface):

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

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

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

    def build_midi_map(self, midi_map_handle):
        pass

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

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

            self._matrix.add_row(tuple(button_row))

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

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

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

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

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

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

    def _move_device_focus(self, increment):
        if not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain'):
            self.application().view.show_view('Detail')
            self.application().view.show_view('Detail/DeviceChain')
        else:
            modifier_pressed = True
            direction = Live.Application.Application.View.NavDirection.left
            if increment > 0:
                direction = Live.Application.Application.View.NavDirection.right
            self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed)
コード例 #34
0
class SubSelectorComponent(ModeSelectorComponent):
    __module__ = __name__
    __doc__ = ' Class that handles different mixer modes '

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

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

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

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

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

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

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

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

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

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

    def number_of_modes(self):
        return 4

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self._session.set_stop_track_clip_buttons(None)
        self._session.set_stop_all_clips_button(None)
        self._mixer.set_global_buttons(None, None, None)
コード例 #35
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
コード例 #36
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
コード例 #37
0
ファイル: Serato.py プロジェクト: cce/buttons
class Serato(ControlSurface):

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

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

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

    def build_midi_map(self, midi_map_handle):
        pass

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

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

            self._matrix.add_row(tuple(button_row))

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

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

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

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

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

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

    def _move_device_focus(self, increment):
        if not self.application().view.is_view_visible('Detail') or not self.application().view.is_view_visible('Detail/DeviceChain'):
            self.application().view.show_view('Detail')
            self.application().view.show_view('Detail/DeviceChain')
        else:
            modifier_pressed = True
            direction = Live.Application.Application.View.NavDirection.left
            if increment > 0:
                direction = Live.Application.Application.View.NavDirection.right
            self.application().view.scroll_view(direction, 'Detail/DeviceChain', not modifier_pressed)
コード例 #38
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)
コード例 #39
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())
コード例 #40
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
コード例 #41
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)
コード例 #42
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)
コード例 #43
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))
コード例 #44
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