def set_enabled(self, enabled): if not enabled: self._do_implicit_arm(enabled) ControlSurfaceComponent.set_enabled(self, enabled) ModesComponent.set_enabled(self._modes, enabled) if enabled: self._do_implicit_arm(enabled)
class Launchpad_Pro(IdentifiableControlSurface, OptimizedControlSurface): def __init__(self, c_instance, *a, **k): product_id_bytes = consts.MANUFACTURER_ID + consts.DEVICE_CODE super(Launchpad_Pro, self).__init__(c_instance=c_instance, product_id_bytes=product_id_bytes, *a, **k) self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143 with self.component_guard(): self._skin = make_default_skin() with inject(skin=const(self._skin)).everywhere(): self._midimap = MidiMap() self._target_track_component = TargetTrackComponent(name='Target_Track') self._create_background() self._create_global_component() self._last_sent_mode_byte = None with inject(layout_setup=const(self._layout_setup), should_arm=const(self._should_arm_track)).everywhere(): self._create_session() self._create_recording() self._create_actions() self._create_drums() self._create_mixer() self._create_device() self._create_modes() self._create_m4l_interface() self._on_session_record_changed.subject = self.song() self.set_highlighting_session_component(self._session) self.set_device_component(self._device) self._device_selection_follows_track_selection = True self._on_session_record_changed() def disconnect(self): self._send_midi(consts.TURN_OFF_LEDS) self._send_midi(consts.QUIT_MESSAGE) super(Launchpad_Pro, self).disconnect() def _create_background(self): self._modifier_background_component = ModifierBackgroundComponent(name='Background_Component', is_enabled=False, layer=Layer(shift_button=self._midimap['Shift_Button'])) self._shifted_background = BackgroundComponent(name='No_Op_Shifted_Buttons', is_enabled=False, layer=Layer(click_bitton=self._midimap.with_shift('Click_Button'), delete_button=self._midimap.with_shift('Delete_Button'), duplicate_button=self._midimap.with_shift('Duplicate_Button'), double_button=self._midimap.with_shift('Double_Loop_Button'), session_record_button=self._midimap.with_shift('Session_Record_Button'))) def _create_global_component(self): self._actions_component = ActionsComponent(name='Global_Actions', is_enabled=False, layer=Layer(undo_button=self._midimap['Undo_Button'], redo_button=self._midimap.with_shift('Undo_Button'), metronome_button=self._midimap['Click_Button'], quantization_on_button=self._midimap.with_shift('Quantize_Button'))) def _create_session(self): self._session = SessionComponent(NUM_TRACKS, NUM_SCENES, auto_name=True, is_enabled=False, enable_skinning=True, layer=Layer(track_bank_left_button=self._midimap['Arrow_Left_Button'], track_bank_right_button=self._midimap['Arrow_Right_Button'], scene_bank_up_button=self._midimap['Arrow_Up_Button'], scene_bank_down_button=self._midimap['Arrow_Down_Button'])) self._session.set_enabled(True) self._session.set_rgb_mode(CLIP_COLOR_TABLE, RGB_COLOR_TABLE) SpecialClipSlotComponent.quantization_component = self._actions_component for scene_index in xrange(NUM_SCENES): scene = self._session.scene(scene_index) scene.layer = Layer(select_button=self._midimap['Shift_Button'], delete_button=self._midimap['Delete_Button'], duplicate_button=self._midimap['Duplicate_Button']) for track_index in xrange(NUM_TRACKS): slot = scene.clip_slot(track_index) slot.layer = Layer(select_button=self._midimap['Shift_Button'], delete_button=self._midimap['Delete_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_loop_button=self._midimap['Double_Loop_Button'], quantize_button=self._midimap['Quantize_Button']) self._session_zoom = SessionZoomingComponent(self._session, name='Session_Overview', is_enabled=True, enable_skinning=True) def _create_recording(self): self._session_record = SpecialSessionRecordingComponent(self._target_track_component, name='Session_Recording', is_enabled=False, layer=Layer(record_button=self._midimap['Session_Record_Button'])) def _create_actions(self): self._clip_actions_component = ClipActionsComponent(self._target_track_component, name='Clip_Actions', is_enabled=False, layer=Layer(duplicate_button=self._midimap['Duplicate_Button'], double_button=self._midimap['Double_Loop_Button'], quantize_button=self._midimap['Quantize_Button'])) ClipActionsComponent.quantization_component = self._actions_component def _create_drums(self): self._drum_group_finder = DrumGroupFinderComponent(self._target_track_component, name='Drum_Group_Finder', is_enabled=False, layer=None) self._on_drum_group_changed.subject = self._drum_group_finder self._drum_group_finder.set_enabled(True) self._drum_group = DrumGroupComponent(self._clip_actions_component, name='Drum_Group_Control', translation_channel=consts.DR_MAP_CHANNEL) self._drum_group.set_enabled(True) def _create_mixer(self): self._mixer = SpecialMixerComponent(NUM_TRACKS, auto_name=True, is_enabled=True, invert_mute_feedback=True) self._mixer.name = 'Mixer_Control' self._session.set_mixer(self._mixer) def _create_device(self): self._device = SpecialDeviceComponent(name='Device_Control', is_enabled=False) self._device_navigation = DeviceNavigationComponent(name='Device_Navigation') self._device_background = BackgroundComponent(name='Device_Background_Component') def _setup_drum_group(self): self._drum_group.set_drum_group_device(self._drum_group_finder.drum_group) def _create_translation(self, comp_name, channel, button_layer, should_enable = True, should_reset = True): translation_component = TranslationComponent(name=comp_name, translated_channel=channel, should_enable=should_enable, should_reset=should_reset, is_enabled=False, layer=button_layer) setattr(self, '_' + comp_name.lower(), translation_component) return translation_component def _create_modes(self): self._modes = ModesComponent(name='Launchpad_Modes', is_enabled=False) self._session_layer_mode = AddLayerMode(self._session, Layer(scene_launch_buttons=self._midimap['Scene_Launch_Button_Matrix'], clip_launch_buttons=self._midimap['Main_Button_Matrix'], delete_button=self._midimap['Delete_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_button=self._midimap['Double_Loop_Button'], quantize_button=self._midimap['Quantize_Button'])) action_button_background = BackgroundComponent(name='No_Op_Buttons') self._action_button_background_layer_mode = LayerMode(action_button_background, Layer(delete_button=self._midimap['Delete_Button'], quantize_button=self._midimap['Quantize_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_button=self._midimap['Double_Loop_Button'])) self._clip_delete_layer_mode = AddLayerMode(self._clip_actions_component, layer=Layer(delete_button=self._midimap['Delete_Button'])) self._create_session_zooming_modes() self._create_session_mode() self._create_note_modes() self._create_device_mode() self._create_user_mode() self._create_record_arm_mode() self._create_track_select_mode() self._create_mute_mode() self._create_solo_mode() self._create_volume_mode() self._create_pan_mode() self._create_sends_mode() self._create_stop_clips_mode() self._modes.layer = Layer(session_mode_button=self._midimap['Session_Mode_Button'], note_mode_button=self._midimap['Note_Mode_Button'], device_mode_button=self._midimap['Device_Mode_Button'], user_mode_button=self._midimap['User_Mode_Button'], record_arm_mode_button=self._midimap['Record_Arm_Mode_Button'], track_select_mode_button=self._midimap['Track_Select_Mode_Button'], mute_mode_button=self._midimap['Mute_Mode_Button'], solo_mode_button=self._midimap['Solo_Mode_Button'], volume_mode_button=self._midimap['Volume_Mode_Button'], pan_mode_button=self._midimap['Pan_Mode_Button'], sends_mode_button=self._midimap['Sends_Mode_Button'], stop_clip_mode_button=self._midimap['Stop_Clip_Mode_Button']) self._modes.selected_mode = 'session_mode' self._on_layout_changed.subject = self._modes def _create_session_zooming_modes(self): session_zoom_layer = Layer(button_matrix=self._midimap['Main_Button_Matrix'], nav_left_button=self._midimap['Arrow_Left_Button'], nav_right_button=self._midimap['Arrow_Right_Button'], nav_up_button=self._midimap['Arrow_Up_Button'], nav_down_button=self._midimap['Arrow_Down_Button']) session_zooming_layer_mode = LayerMode(self._session_zoom, session_zoom_layer) self._session_zooming_manager = SessionZoomingManagerComponent(self._modes, is_enabled=False) session_zooming_button_layer_mode = LayerMode(self._session_zooming_manager, Layer(session_zooming_button=self._midimap['Session_Mode_Button'])) self._prioritized_session_zooming_button_layer_mode = LayerMode(self._session_zooming_manager, Layer(session_zooming_button=self._midimap['Session_Mode_Button'], priority=1)) self._session_zooming_background = BackgroundComponent(name='Session_Zooming_Background') session_zooming_background_layer_mode = LayerMode(self._session_zooming_background, Layer(scene_launch_buttons=self._midimap['Scene_Launch_Button_Matrix'], delete_button=self._midimap['Delete_Button'], quantize_button=self._midimap['Quantize_Button'], duplicate_button=self._midimap['Duplicate_Button'], double_loop_button=self._midimap['Double_Loop_Button'])) self._modes.add_mode('session_zooming_mode', [self._session_zooming_manager, session_zooming_button_layer_mode, session_zooming_layer_mode, session_zooming_background_layer_mode]) self._modes.add_mode('prioritized_session_zooming_mode', [partial(self._layout_switch, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, session_zooming_layer_mode, session_zooming_background_layer_mode, self.update]) def _create_session_mode(self): self._modes.add_mode('session_mode', [partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, self._session.update_navigation_buttons], behaviour=CancelingReenterBehaviour('session_zooming_mode')) def _create_note_modes(self): note_mode_matrix_translation = self._create_translation('Note_Mode_Matrix_Translation', consts.CHROM_MAP_CHANNEL, Layer(button_matrix=self._midimap['Main_Button_Matrix'], note_button_matrix=self._midimap['Note_Button_Matrix'], drum_matrix=self._midimap['Drum_Button_Matrix'], mixer_button_matrix=self._midimap['Mixer_Button_Matrix']), should_enable=False) note_mode_scene_launch_translation = self._create_translation('Note_Mode_Scene_Launch_Translation', consts.CHROM_MAP_CHANNEL, Layer(scene_launch_buttons=self._midimap['Scene_Launch_Button_Matrix'])) drum_mode_note_matrix_translation = self._create_translation('Drum_Mode_Note_Button_Translation', 0, Layer(note_button_matrix=self._midimap['Note_Button_Matrix']), should_enable=False, should_reset=False) drum_group_layer_mode = LayerMode(self._drum_group, layer=Layer(scroll_up_button=self._midimap['Arrow_Left_Button'], scroll_down_button=self._midimap['Arrow_Right_Button'], scroll_page_up_button=self._midimap['Arrow_Up_Button'], scroll_page_down_button=self._midimap['Arrow_Down_Button'], drum_matrix=self._midimap['Drum_Button_Matrix'], select_button=self._midimap['Shift_Button'], delete_button=self._midimap['Delete_Button'])) self._note_modes = SpecialModesComponent(name='Note_Modes') self._note_modes.add_mode('chromatic_mode', [partial(self._layout_setup, consts.NOTE_LAYOUT_SYSEX_BYTE), self._clip_delete_layer_mode, note_mode_matrix_translation]) self._note_modes.add_mode('drum_mode', [partial(self._layout_setup, consts.DRUM_LAYOUT_SYSEX_BYTE), self._setup_drum_group, drum_group_layer_mode, drum_mode_note_matrix_translation]) self._note_modes.add_mode('audio_mode', [partial(self._layout_setup, consts.AUDIO_LAYOUT_SYSEX_BYTE), self._clip_delete_layer_mode]) self._note_modes.set_enabled(False) self._modes.add_mode('note_mode', [note_mode_scene_launch_translation, self._note_modes, self._select_note_mode, self._select_target_track, self._clip_actions_component, self._show_playing_clip, self._set_clip_actions_type], behaviour=ReenterBehaviour(self.toggle_detail_view)) self._session_record.set_modes_component(self._modes) self._session_record.set_note_mode_name('note_mode') def _create_device_mode(self): device_mode_scene_launch_translation = self._create_translation('Device_Mode_Scene_Launch_Translation', consts.DEVICE_MAP_CHANNEL, Layer(scene_launch_buttons=self._midimap['Scene_Launch_Button_Matrix'])) device_layer_mode = LayerMode(self._device, layer=Layer(parameter_controls=self._midimap['Slider_Button_Matrix'])) device_nav_layer_mode = LayerMode(self._device_navigation, layer=Layer(device_nav_left_button=self._midimap['Arrow_Left_Button'], device_nav_right_button=self._midimap['Arrow_Right_Button'])) device_background_layer_mode = LayerMode(self._device_background, layer=Layer(arrow_up_button=self._midimap['Arrow_Up_Button'], arrow_down_button=self._midimap['Arrow_Down_Button'])) self._modes.add_mode('device_mode', [partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), self._device, device_layer_mode, device_nav_layer_mode, device_background_layer_mode, self._clip_actions_component, self._clip_delete_layer_mode, device_mode_scene_launch_translation, self._show_playing_clip, self._set_clip_actions_type], behaviour=ReenterBehaviour(self.toggle_detail_view)) def _create_user_mode(self): self._modes.add_mode('user_mode', [partial(self._layout_setup, consts.USER_LAYOUT_SYSEX_BYTE)]) def _create_record_arm_mode(self): arm_layer_mode = LayerMode(self._mixer, layer=Layer(arm_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('record_arm_mode', [partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, arm_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_track_select_mode(self): track_select_layer_mode = LayerMode(self._mixer, layer=Layer(track_select_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('track_select_mode', [partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, track_select_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_mute_mode(self): mute_layer_mode = LayerMode(self._mixer, layer=Layer(mute_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('mute_mode', [partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, mute_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_solo_mode(self): solo_layer_mode = LayerMode(self._mixer, layer=Layer(solo_buttons=self._midimap['Mixer_Button_Matrix'])) self._modes.add_mode('solo_mode', [partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, solo_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_volume_mode(self): volume_mode_scene_launch_translation = self._create_translation('Volume_Mode_Scene_Launch_Translation', consts.VOLUME_MAP_CHANNEL, Layer(scene_launch_buttons=self._midimap['Scene_Launch_Button_Matrix'])) volume_layer_mode = LayerMode(self._mixer, layer=Layer(volume_controls=self._midimap['Slider_Button_Matrix'])) self._modes.add_mode('volume_mode', [partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), volume_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, volume_mode_scene_launch_translation, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_pan_mode(self): pan_mode_scene_launch_translation = self._create_translation('Pan_Mode_Scene_Launch_Translation', consts.PAN_MAP_CHANNEL, Layer(scene_launch_buttons=self._midimap['Scene_Launch_Button_Matrix'])) pan_layer_mode = LayerMode(self._mixer, layer=Layer(pan_controls=self._midimap['Slider_Button_Matrix'])) self._modes.add_mode('pan_mode', [partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), pan_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, pan_mode_scene_launch_translation, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_sends_mode(self): send_layer_mode = LayerMode(self._mixer, layer=Layer(send_controls=self._midimap['Slider_Button_Matrix'], send_select_buttons=self._midimap['Scene_Launch_Button_Matrix'])) self._modes.add_mode('sends_mode', [partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), send_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_stop_clips_mode(self): stop_layer_mode = AddLayerMode(self._session, Layer(stop_track_clip_buttons=self._midimap['Mixer_Button_Matrix'], stop_scene_clip_buttons=self._midimap['Scene_Stop_Button_Matrix'], stop_all_clips_button=self._midimap['Stop_All_Clips_Button'])) self._modes.add_mode('stop_clip_mode', [partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, stop_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons], behaviour=SpecialReenterBehaviour('session_mode')) def _create_m4l_interface(self): self._m4l_interface = M4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard, priority=1) self.get_control_names = self._m4l_interface.get_control_names self.get_control = self._m4l_interface.get_control self.grab_control = self._m4l_interface.grab_control self.release_control = self._m4l_interface.release_control def toggle_detail_view(self): view = self.application().view if view.is_view_visible('Detail'): if view.is_view_visible('Detail/DeviceChain'): view.show_view('Detail/Clip') else: view.show_view('Detail/DeviceChain') @subject_slot('drum_group') def _on_drum_group_changed(self): if self._note_modes.selected_mode == 'drum_mode': self._drum_group.set_drum_group_device(self._drum_group_finder.drum_group) if self._modes.selected_mode == 'note_mode': self._select_note_mode() else: self.release_controlled_track() self._update_note_mode_button(self._drum_group_finder.drum_group is not None) def _select_note_mode(self): """ Selects which note mode to use depending on the kind of current target track and its device chain. Will also select the target if specified. """ track = self._target_track_component.target_track drum_device = self._drum_group_finder.drum_group if track is None or track.is_foldable or track in self.song().return_tracks or track == self.song().master_track or track.is_frozen or track.has_audio_input: self._note_modes.selected_mode = 'audio_mode' elif drum_device: self._note_modes.selected_mode = 'drum_mode' else: self._note_modes.selected_mode = 'chromatic_mode' self._modes.update() if self._note_modes.selected_mode == 'audio_mode': self.release_controlled_track() else: self.set_controlled_track(self._target_track_component.target_track) def _select_target_track(self): track = self._target_track_component.target_track if track != self.song().view.selected_track: self.song().view.selected_track = track def _update_note_mode_button(self, focused_track_is_drum_track): button = self._midimap['Note_Mode_Button'] if focused_track_is_drum_track: button.default_states = {True: 'Mode.Drum.On', False: 'Mode.Drum.Off'} else: button.default_states = {True: 'Mode.Chromatic.On', False: 'Mode.Chromatic.Off'} button.reset_state() self._modes.update() def _show_playing_clip(self): track = None if self._use_sel_track(): track = self.song().view.selected_track else: track = self._target_track_component.target_track if track in self.song().tracks: slot_index = track.fired_slot_index if slot_index < 0: slot_index = track.playing_slot_index if slot_index >= 0: clip_slot = track.clip_slots[slot_index] self.song().view.highlighted_clip_slot = clip_slot def _set_clip_actions_type(self): self._clip_actions_component.use_selected_track(self._use_sel_track()) self._clip_actions_component.update() def _use_sel_track(self): return self._modes.selected_mode == 'device_mode' def _should_arm_track(self): return self._modes.selected_mode == 'record_arm_mode' @subject_slot('selected_mode') def _on_layout_changed(self, mode): if mode == 'note_mode': self.set_controlled_track(self._target_track_component.target_track) else: self.release_controlled_track() self._session_record.set_enabled(mode != 'user_mode') @subject_slot('session_record') def _on_session_record_changed(self): status = self.song().session_record feedback_color = int(self._skin['Instrument.FeedbackRecord'] if status else self._skin['Instrument.Feedback']) self._c_instance.set_feedback_velocity(feedback_color) def _clear_send_cache(self): with self.component_guard(): for control in self.controls: control.clear_send_cache() def _update_global_components(self): self._actions_component.update() self._session_record.update() self._modifier_background_component.update() def _layout_setup(self, mode): self._layout_switch(mode) self._clear_send_cache() self._update_global_components() def _layout_switch(self, mode): prefix = consts.SYSEX_STANDARD_PREFIX + consts.SYSEX_PARAM_BYTE_LAYOUT suffix = consts.SYSEX_STANDARD_SUFFIX self._send_midi(prefix + mode + suffix) self._last_sent_mode_byte = mode def _send_identity_request(self): self._send_midi(consts.SYSEX_IDENTITY_REQUEST) def on_identified(self): self._send_challenge() def _send_challenge(self): challenge_bytes = [] for index in range(4): challenge_bytes.append(self._challenge >> 8 * index & 127) challenge = consts.CHALLENGE_PREFIX + tuple(challenge_bytes) + (247,) self._send_midi(challenge) def _on_handshake_successful(self): self._do_send_midi(consts.LIVE_MODE_SWITCH_REQUEST) with self.component_guard(): self._modes.set_enabled(True) self._actions_component.set_enabled(True) self._session_record.set_enabled(True) self._modifier_background_component.set_enabled(True) self._shifted_background.set_enabled(True) self.release_controlled_track() self.set_feedback_channels(consts.FEEDBACK_CHANNELS) if self._last_sent_mode_byte is not None: self._layout_setup(self._last_sent_mode_byte) self.update() def _is_challenge_response(self, midi_bytes): return len(midi_bytes) == 10 and midi_bytes[:7] == consts.SYSEX_STANDARD_PREFIX + consts.SYSEX_CHALLENGE_RESPONSE_BYTE def _is_response_valid(self, midi_bytes): response = long(midi_bytes[7]) response += long(midi_bytes[8] << 8) return response == Live.Application.encrypt_challenge2(self._challenge) def handle_sysex(self, midi_bytes): if len(midi_bytes) < 7: pass if self._is_challenge_response(midi_bytes) and self._is_response_valid(midi_bytes): self._on_handshake_successful() elif midi_bytes[6] in (consts.SYSEX_STATUS_BYTE_MODE, consts.SYSEX_STATUS_BYTE_LAYOUT): pass else: super(Launchpad_Pro, self).handle_sysex(midi_bytes)
class Cntrlr(ControlSurface): __module__ = __name__ __doc__ = " Monomodular controller script for Livid CNTRLR " def __init__(self, *a, **k): super(Cntrlr, self).__init__(*a, **k) self._version_check = 'b996' self._host_name = 'Cntrlr' self._color_type = 'OhmRGB' self._client = [None for index in range(4)] self._active_client = None self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 self._skin = Skin(CntrlrColors) self._device_selection_follows_track_selection = FOLLOW with self.component_guard(): self._setup_monobridge() self._setup_controls() self._define_sysex() self._setup_transport_control() self._setup_autoarm() self._setup_session_recording_component() self._setup_mixer_control() self._setup_send_resets() self._setup_session_control() self._setup_device_control() self._setup_device_selector() self._setup_translations() self._setup_viewcontrol() self._setup_mod() self._setup_instrument() self._setup_modswitcher() self._setup_modes() self._setup_m4l_interface() self._on_device_changed.subject = self.song() self.set_feedback_channels(range(14, 15)) self._main_modes.selected_mode = 'MixMode' self.schedule_message(1, self._open_log) def _open_log(self): self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") self.show_message(str(self._host_name) + ' Control Surface Loaded') def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_controls(self): is_momentary = True self._fader = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_FADERS[index], Live.MidiMap.MapMode.absolute, 'Fader_' + str(index), index, self) for index in range(8)] self._dial_left = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_KNOBS_LEFT[index], Live.MidiMap.MapMode.absolute, 'Dial_Left_' + str(index), CNTRLR_KNOBS_LEFT[index], self) for index in range(12)] self._dial_right = [MonoEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_KNOBS_RIGHT[index], Live.MidiMap.MapMode.absolute, 'Dial_Right_' + str(index), CNTRLR_KNOBS_RIGHT[index], self) for index in range(12)] self._encoder = [CodecEncoderElement(MIDI_CC_TYPE, CHANNEL, CNTRLR_DIALS[index], Live.MidiMap.MapMode.absolute, 'Encoder_' + str(index), CNTRLR_DIALS[index], self) for index in range(12)] self._encoder_button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_DIAL_BUTTONS[index], name = 'Encoder_Button_' + str(index), script = self, skin = self._skin) for index in range(12)] self._grid = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_GRID[index], name = 'Grid_' + str(index), script = self, skin = self._skin) for index in range(16)] self._button = [MonoButtonElement(is_momentary, MIDI_NOTE_TYPE, CHANNEL, CNTRLR_BUTTONS[index], name = 'Button_' + str(index), script = self, skin = self._skin) for index in range(32)] self._knobs = self._dial_left + self._dial_right self._fader_matrix = ButtonMatrixElement(name = 'Fader_Matrix', rows = [self._fader]) self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [self._grid[index*4:(index*4)+4] for index in range(4)]) self._knob_left_matrix = ButtonMatrixElement(name = 'Knob_Left_Matrix', rows = [self._dial_left[index*4:(index*4)+4] for index in range(3)]) self._knob_right_matrix = ButtonMatrixElement(name = 'Knob_Right_Matrix', rows = [self._dial_right[index*4:(index*4)+4] for index in range(3)]) self._dial_matrix = ButtonMatrixElement(name = 'Dial_Matrix', rows = [self._encoder[index*4:(index*4)+4] for index in range(3)]) self._dial_button_matrix = ButtonMatrixElement(name = 'Dial_Button_Matrix', rows = [self._encoder_button[index*4:(index*4)+4] for index in range(1,3)]) self._key_matrix = ButtonMatrixElement(name = 'Key_Matrix', rows = [self._button[0:16], self._button[16:32]]) self._translated_controls = self._fader + self._knobs + self._encoder[4:] + self._grid + self._button def _define_sysex(self): self.encoder_navigation_on = SendSysexMode(script = self, sysex = (240, 0, 1, 97, 8, 17, 15, 0, 0, 0, 0, 0, 0, 0, 247)) self.encoder_navigation_off = SendSysexMode(script = self, sysex = (240, 0, 1, 97, 8, 17, 0, 0, 0, 0, 0, 0, 0, 0, 247)) def _setup_transport_control(self): self._transport = CntrlrTransportComponent() self._transport.name = 'Transport' self._transport.layer = Layer(priority = 4, play_button = self._button[28], record_button = self._button[30], stop_button = self._button[29]) def _setup_autoarm(self): self._auto_arm = AutoArmComponent(name='Auto_Arm') self._auto_arm.can_auto_arm_track = self._can_auto_arm_track def _setup_session_recording_component(self): self._clip_creator = ClipCreator() self._clip_creator.name = 'ClipCreator' self._recorder = CntrlrSessionRecordingComponent(self._clip_creator, ViewControlComponent()) # is_enabled = False) self._recorder.layer = Layer(priority = 4, new_button = self._button[28], record_button = self._button[29], automation_button = self._button[30]) self._recorder.set_enabled(False) def _setup_mixer_control(self): is_momentary = True self._num_tracks = (4) self._mixer = MixerComponent(num_tracks = 4, num_returns = 2, name = 'Mixer', auto_name = True, invert_mute_feedback = True) self._mixer.set_track_offset(0) if self._mixer.channel_strip(0)._track: self.song().view.selected_track = self._mixer.channel_strip(0)._track self._mixer.main_faders_layer = AddLayerMode(self._mixer, Layer(priority = 4, volume_controls = self._fader_matrix.submatrix[:4, :], return_controls = self._fader_matrix.submatrix[4:6, :], prehear_volume_control = self._fader[6],)) self._mixer.main_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4, mute_buttons = self._key_matrix.submatrix[:4, 1:], arm_buttons = self._key_matrix.submatrix[4:8, :1], solo_buttons = self._key_matrix.submatrix[:4, :1], track_select_buttons = self._key_matrix.submatrix[4:8, 1:],)) self._mixer.stop_layer = AddLayerMode(self._mixer, Layer(priority = 4, stop_clip_buttons = self._key_matrix.submatrix[8:12, 1:],)) self._mixer.main_knobs_layer = AddLayerMode(self._mixer, Layer(priority = 4, send_controls = self._knob_left_matrix.submatrix[:, :2], pan_controls = self._knob_left_matrix.submatrix[:, 2:], eq_gain_controls = self._knob_right_matrix)) self._mixer.master_fader_layer = AddLayerMode(self._mixer.master_strip(), Layer(priority = 4, volume_control = self._fader[7])) self._mixer.instrument_buttons_layer = AddLayerMode(self._mixer, Layer(priority = 4, mute_buttons = self._key_matrix.submatrix[:4, 1:], track_select_buttons = self._key_matrix.submatrix[4:8, 1:],)) self._mixer.dial_nav_layer = AddLayerMode(self._mixer, Layer(priority = 4, track_select_dial = self._encoder[3])) def _setup_send_resets(self): self._send_reset = CntrlrResetSendsComponent(self) self._send_reset.name = 'Sends_Reset' self._send_reset.layer = Layer(buttons = self._key_matrix.submatrix[8:12, :1]) def _setup_session_control(self): self._session = CntrlrSessionComponent(num_tracks = 4, num_scenes = 4, name = 'Session', enable_skinning = True, auto_name = True) self._session.set_mixer(self._mixer) self.set_highlighting_session_component(self._session) self._session.layer = Layer(priority = 4, clip_launch_buttons = self._matrix) self._session.nav_layer = AddLayerMode(self._session, Layer(priority = 4, scene_bank_down_button = self._button[14], scene_bank_up_button = self._button[15], track_bank_left_button = self._button[12], track_bank_right_button = self._button[13])) self._session.dial_nav_layer = AddLayerMode(self._session, Layer(priority = 4, scene_select_dial = self._encoder[2])) self._session_zoom = SessionZoomingComponent(session = self._session, name = 'Session_Overview', enable_skinning = True) # is_enabled = False) # self._session_zoom.buttons_layer = AddLayerMode(self._session_zoom, Layer(priority = 4, button_matrix = self._matrix)) self._session.set_offsets(0, 0) def _setup_device_control(self): self._device_selection_follows_track_selection = FOLLOW self._device = DeviceComponent() self._device.name = 'Device_Component' self._device._is_banking_enabled = self.device_is_banking_enabled(self._device) self.set_device_component(self._device) self._device.layer = Layer(priority = 4, parameter_controls = self._dial_matrix.submatrix[:, 1:3], lock_button = self._encoder_button[5], on_off_button = self._encoder_button[4], bank_prev_button = self._encoder_button[6], bank_next_button = self._encoder_button[7]) self._device_navigator = DeviceNavigator(self._device, self._mixer, self) self._device_navigator.name = 'Device_Navigator' self._device_navigator.layer = Layer(priority = 4, prev_button = self._encoder_button[8], next_button = self._encoder_button[9], prev_chain_button = self._encoder_button[10], next_chain_button = self._encoder_button[11],) def _setup_device_selector(self): self._device_selector = DeviceSelectorComponent(self) # is_enabled = False) self._device_selector.name = 'Device_Selector' self._device_selector.layer = Layer(matrix = self._matrix.submatrix[:, :3]) self._device_selector.set_enabled(False) def _setup_translations(self): self._translations = TranslationComponent(self._translated_controls, user_channel_offset = 4, channel = 4) # is_enabled = False) self._translations.name = 'TranslationComponent' self._translations.layer = Layer(priority = 10,) self._translations.selector_layer = AddLayerMode(self._translations, Layer(priority = 10, channel_selector_buttons = self._dial_button_matrix)) self._translations.set_enabled(False) self._optional_translations = CompoundMode(TranslationComponent(controls = self._fader, user_channel_offset = 4, channel = 4, name = 'FaderTranslation', is_enabled = False, layer = Layer(priority = 10)) if FADER_BANKING else None, TranslationComponent(controls = self._knobs, user_channel_offset = 4, channel = 4, name = 'DialTranslation', is_enabled = False, layer = Layer(priority = 10)) if DIAL_BANKING else None) def _setup_mod(self): self.monomodular = get_monomodular(self) self.monomodular.name = 'monomodular_switcher' self.modhandler = CntrlrModHandler(self) # is_enabled = False) self.modhandler.name = 'ModHandler' self.modhandler.set_lock_button(self._encoder_button[1]) self.modhandler.layer = Layer(priority = 8, cntrlr_encoder_grid = self._dial_matrix, cntrlr_encoder_button_grid = self._dial_button_matrix, cntrlr_grid = self._matrix, cntrlr_keys = self._key_matrix,) #parameter_controls = self._dial_matrix) def _setup_instrument(self): self._grid_resolution = self.register_disconnectable(GridResolution()) self._c_instance.playhead.enabled = True self._playhead_element = PlayheadElement(self._c_instance.playhead) self._playhead_element.reset() self._instrument = CntrlrMonoInstrumentComponent(self, self._skin, grid_resolution = self._grid_resolution, name = 'InstrumentModes') # is_enabled = False) #self._instrument.layer = Layer(priority = 10, shift_mode_button = self._button[31]) self._instrument.shift_button_layer = AddLayerMode(self._instrument, Layer(priority = 5, shift_mode_button = self._button[31])) self._instrument.audioloop_layer = LayerMode(self._instrument, Layer(priority = 4, loop_selector_matrix = self._key_matrix.submatrix[:, :1])) self._instrument.keypad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 4, scale_up_button = self._button[13], scale_down_button = self._button[12], offset_up_button = self._button[11], offset_down_button = self._button[10], vertical_offset_up_button = self._button[9], vertical_offset_down_button = self._button[8], split_button = self._button[14], sequencer_button = self._button[15])) self._instrument.drumpad_shift_layer = AddLayerMode(self._instrument, Layer(priority = 4, scale_up_button = self._button[13], scale_down_button = self._button[12], drum_offset_up_button = self._button[11], drum_offset_down_button = self._button[10], drumpad_mute_button = self._button[9], drumpad_solo_button = self._button[8], split_button = self._button[14], sequencer_button = self._button[15])) self._instrument._keypad.main_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix)) self._instrument._keypad.sequencer_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, playhead = self._playhead_element, keypad_matrix = self._matrix, sequencer_matrix = self._key_matrix.submatrix[:,:1])) self._instrument._keypad.split_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix, split_matrix = self._key_matrix.submatrix[:8,:1])) self._instrument._keypad.sequencer_shift_layer = LayerMode(self._instrument._keypad, Layer(priority = 4, keypad_matrix = self._matrix, loop_selector_matrix = self._key_matrix.submatrix[:8, :1], quantization_buttons = self._key_matrix.submatrix[:7, 1:], follow_button = self._button[23])) self._instrument._drumpad.main_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix)) self._instrument._drumpad.sequencer_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, playhead = self._playhead_element, drumpad_matrix = self._matrix, sequencer_matrix = self._key_matrix.submatrix[:,:1])) self._instrument._drumpad.split_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix, split_matrix = self._key_matrix.submatrix[:8,:1])) self._instrument._drumpad.sequencer_shift_layer = LayerMode(self._instrument._drumpad, Layer(priority = 4, drumpad_matrix = self._matrix, loop_selector_matrix = self._key_matrix.submatrix[:8, :1], quantization_buttons = self._key_matrix.submatrix[:7, 1:], follow_button = self._button[23])) self._instrument.set_enabled(False) def _setup_modswitcher(self): self._modswitcher = ModesComponent(name = 'ModSwitcher') # is_enabled = False) #self._modswitcher.add_mode('instrument', [self._optional_translations]) self._modswitcher.add_mode('mod', [self.modhandler, self._optional_translations]) self._modswitcher.add_mode('instrument', [self._instrument, self._instrument.shift_button_layer, self._optional_translations]) self._modswitcher.set_enabled(False) def _setup_viewcontrol(self): self._view_control = ViewControlComponent(name='View_Control')# is_enabled = False) self._view_control.main_layer = AddLayerMode(self._view_control, Layer(prev_track_button=self._button[24], next_track_button= self._button[25], next_scene_button=self._button[27], prev_scene_button = self._button[26])) #self._view_control.set_enabled(False) self._view_control.selector_layer = AddLayerMode(self._view_control, Layer(priority = 8, prev_track_button = self._grid[12], next_track_button = self._grid[13], next_scene_button = self._grid[15], prev_scene_button = self._grid[14])) def _setup_modes(self): main_buttons=CompoundMode(self._mixer.main_buttons_layer, self._mixer.stop_layer, self._transport, self._send_reset, self._session.nav_layer) main_buttons_instrument=CompoundMode(self._mixer.main_buttons_layer, self._recorder, self._view_control.main_layer) main_faders=CompoundMode(self._mixer.main_faders_layer, self._mixer.master_fader_layer) bottom_buttons=CompoundMode(self._mixer.instrument_buttons_layer, self._recorder, self._view_control.main_layer) self._instrument._main_modes = ModesComponent(name = 'InstrumentModes') self._instrument._main_modes.add_mode('disabled', [main_buttons_instrument, main_faders, self._mixer.main_knobs_layer, self._device, self._session, self._recorder, self._view_control.main_layer, self._send_reset, self._session.nav_layer,]) self._instrument._main_modes.add_mode('drumpad', [self._instrument._drumpad.main_layer, main_buttons_instrument, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('drumpad_split', [self._instrument._drumpad.split_layer, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('drumpad_sequencer', [self._instrument._drumpad.sequencer_layer, bottom_buttons]) self._instrument._main_modes.add_mode('drumpad_shifted', [self._instrument._drumpad.main_layer, self._instrument.drumpad_shift_layer, main_buttons_instrument, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('drumpad_split_shifted', [self._instrument._drumpad.split_layer, self._instrument.drumpad_shift_layer, bottom_buttons, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('drumpad_sequencer_shifted', [self._instrument._drumpad.sequencer_shift_layer, self._instrument.drumpad_shift_layer, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('keypad', [self._instrument._keypad.main_layer, main_buttons_instrument, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('keypad_split', [self._instrument._keypad.split_layer, bottom_buttons, self._send_reset, self._session.nav_layer]) self._instrument._main_modes.add_mode('keypad_sequencer', [self._instrument._keypad.sequencer_layer, bottom_buttons]) self._instrument._main_modes.add_mode('keypad_shifted', [self._instrument._keypad.main_layer, self._instrument.keypad_shift_layer, main_buttons_instrument, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('keypad_split_shifted', [self._instrument._keypad.split_layer, self._instrument.keypad_shift_layer, bottom_buttons, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('keypad_sequencer_shifted', [self._instrument._keypad.sequencer_shift_layer, self._instrument.keypad_shift_layer, self._recorder, self._view_control.main_layer]) self._instrument._main_modes.add_mode('audioloop', [self._instrument.audioloop_layer, self._session, bottom_buttons, self._recorder, self._view_control.main_layer]) self._instrument.register_component(self._instrument._main_modes) self._instrument.set_enabled(False) self._session_modes = ModesComponent(name = 'SessionModes', is_enabled = False) self._session_modes.add_mode('Session', [self._session]) self._session_modes.add_mode('SessionZoom', [self._session_zoom.buttons_layer], behaviour = BicoloredMomentaryBehaviour(color = 'Session.ZoomOn', off_color = 'Session.ZoomOff')) self._session_modes.layer = Layer(priority = 4, SessionZoom_button = self._button[31]) self._session_modes.selected_mode = 'Session' self._main_modes = ModesComponent(name = 'MainModes') self._main_modes.add_mode('MixMode', [main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._session_modes, self._session.nav_layer,]) # self._session.dial_nav_layer, self._mixer.dial_nav_layer, self.encoder_navigation_on]) self._main_modes.add_mode('ModSwitcher', [main_faders, self._mixer.main_knobs_layer, self._modswitcher], behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.ModSwitcher', off_color = 'ModeButtons.ModSwitcherDisabled')) self._main_modes.add_mode('Translations', [main_faders, self._mixer.main_knobs_layer, self._translations, DelayMode(self._translations.selector_layer)], behaviour = DefaultedBehaviour(default_mode = 'MixMode', color = 'ModeButtons.Translations', off_color = 'ModeButtons.TranslationsDisabled')) self._main_modes.add_mode('DeviceSelector', [self._device_selector, main_buttons, main_faders, self._mixer.main_knobs_layer, self._device, self._device_navigator, self._view_control.selector_layer], behaviour = ColoredCancellableBehaviourWithRelease(color = 'ModeButtons.DeviceSelector', off_color = 'ModeButtons.DeviceSelectorDisabled')) self._main_modes.layer = Layer(priority = 4, ModSwitcher_button = self._encoder_button[0], Translations_button = self._encoder_button[3], DeviceSelector_button = self._encoder_button[2]) def _setup_m4l_interface(self): self._m4l_interface = MonoM4LInterfaceComponent(controls=self.controls, component_guard=self.component_guard, priority = 10) self._m4l_interface.name = "M4LInterface" self.get_control_names = self._m4l_interface.get_control_names self.get_control = self._m4l_interface.get_control self.grab_control = self._m4l_interface.grab_control self.release_control = self._m4l_interface.release_control def _can_auto_arm_track(self, track): routing = track.current_input_routing return routing == 'Ext: All Ins' or routing == 'All Ins' or routing.startswith('Cntrlr Input') @subject_slot('appointed_device') def _on_device_changed(self): debug('appointed device changed, script') self.schedule_message(2, self._update_modswitcher) def _on_selected_track_changed(self): super(Cntrlr, self)._on_selected_track_changed() self.schedule_message(2, self._update_modswitcher) def _update_modswitcher(self): debug('update modswitcher', self.modhandler.active_mod()) if self.modhandler.active_mod(): self._modswitcher.selected_mode = 'mod' else: self._modswitcher.selected_mode = 'instrument' def reset_controlled_track(self, track = None, *a): if not track: track = self.song().view.selected_track self.set_controlled_track(track) def set_controlled_track(self, track = None, *a): if isinstance(track, Live.Track.Track): super(Cntrlr, self).set_controlled_track(track) else: self.release_controlled_track() """called on timer""" def update_display(self): super(Cntrlr, self).update_display() #since we are overriding this from the inherited method, we need to call the original routine as well self._timer = (self._timer + 1) % 256 #each 100/60ms, increase the self._timer property by one. Start over at 0 when we hit 256 self.modhandler.send_ring_leds() #if local rings are turned off, then we need to send the new values if they've changed self.flash() #call the flash method below def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) """m4l lcd bridge""" def generate_strip_string(self, 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 += ' ' ret = ret.replace(' ', '_') assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return ret def notification_to_bridge(self, name, value, sender): if(isinstance(sender, (MonoEncoderElement, CodecEncoderElement))): pn = str(self.generate_strip_string(name)) pv = str(self.generate_strip_string(value)) self._monobridge._send(sender.name, 'lcd_name', pn) self._monobridge._send(sender.name, 'lcd_value', pv) 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 handle_sysex(self, midi_bytes): pass def disconnect(self): self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) + " log closed >>>>>>>>>>>>>>>>>>>>>>>>>") super(Cntrlr, self).disconnect() def restart_monomodular(self): #debug('restart monomodular') self.modhandler.disconnect() with self.component_guard(): self._setup_mod() def _get_num_tracks(self): return self.num_tracks """a closure fix for banking when we deassign the bank buttons and still want to change bank indexes""" def device_is_banking_enabled(self, device): def _is_banking_enabled(): return True return _is_banking_enabled
class MonoWing(ControlSurface): def __init__(self, *a, **k): super(MonoWing, self).__init__(*a, **k) self._monomod_version = 'b995' self._codec_version = 'b996' self._cntrlr_version = 'b996' self._cntrlr = None self._host_name = 'MonoWing' self._color_type = 'OhmRGB' self.hosts = [] self._timer = 0 self.flash_status = 0 self._touched = 0 self._last_main_mode = 'looper' with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_looper() self._setup_launcher() self._setup_device_control() self._setup_modes() self.schedule_message(1, self._open_log) #self._loop_selector.set_enabled(True) """script initialization methods""" def _open_log(self): self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._monomod_version) + " log opened =>>>>>>>>>>>>>>>>>>>") self.show_message(str(self._host_name) + ' Control Surface Loaded') def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_controls(self): self._pedal = [None for index in range(12)] for index in range(9): self._pedal[index] = DoublePressElement(MonoButtonElement(True, MIDI_NOTE_TYPE, 0, PEDAL_DEFS[index], 'Pedal_'+str(index), self)) #is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self self._pedal[index].name = 'Pedal_'+str(index) self._pedal[index]._report = False self._pedal[9] = LoopPedalExpressionElement(self, MIDI_CC_TYPE, 0, 3, Live.MidiMap.MapMode.absolute) self._pedal[9].name = 'Pedal_'+str(9) self._pedal[9]._report = False self._pedal[10] = LoopPedalExpressionElement(self, MIDI_CC_TYPE, 0, 1, Live.MidiMap.MapMode.absolute) self._pedal[10].name = 'Pedal_'+str(10) self._pedal[10]._report = False self._pedal[11] = LoopPedalExpressionElement(self, MIDI_CC_TYPE, 0, 2, Live.MidiMap.MapMode.absolute) self._pedal[11].name = 'Pedal_'+str(11) self._pedal[11]._report = False self._leds = [self._pedal[6], self._pedal[5], self._pedal[4], self._pedal[3]] self._side_buttons = [MonoButtonElement(True, MIDI_NOTE_TYPE, 0, SIDE_DEFS[index], 'Side_Button_'+str(index), self) for index in range(4)] self._select_buttons = ButtonMatrixElement() self._select_buttons.name = 'SelectMatrix' self._select_buttons.add_row([self._pedal[6], self._pedal[5], self._pedal[4], self._pedal[3]]) self._doublepress_select_buttons = ButtonMatrixElement() self._doublepress_select_buttons.name = 'DoublepressSelectMatrix' self._doublepress_select_buttons.add_row([self._pedal[6].double_press, self._pedal[5].double_press, self._pedal[4].double_press, self._pedal[3].double_press]) self._record_button = self._pedal[1] self._mute_button = self._pedal[2] self._overdub_button = self._pedal[0] self._clear_button = self._pedal[7] self._reverse_button = self._pedal[8] self._record_button.turn_off() self._mute_button.turn_off() self._overdub_button.turn_off() self._clear_button.turn_off() self._reverse_button.turn_off() def _setup_looper(self): self._looper = MonolooperComponent(self._leds, self) self._looper.layer = Layer(select_buttons = self._select_buttons, doublepress_select_buttons = self._doublepress_select_buttons, overdub_button = self._pedal[2], record_button = self._pedal[1], mute_button = self._pedal[0], clear_button = self._pedal[7], reverse_button = self._pedal[8], expression_pedal = self._pedal[9],) def _setup_launcher(self): self._launcher = LauncherComponent(self._leds, self) self._launcher.set_enabled(False) self._launcher.layer = Layer(select_buttons = self._select_buttons, doublepress_select_buttons = self._doublepress_select_buttons, fire1_button = self._pedal[2], fire2_button = self._pedal[1], fire3_button = self._pedal[0], fire4_button = self._pedal[8], expression_pedal = self._pedal[9]) def _setup_device_control(self): self._device_control = DeviceControlComponent(self._leds, self) self._device_control.set_enabled(False) self._device_control.layer = Layer(select_buttons = self._select_buttons, doublepress_select_buttons = self._doublepress_select_buttons, toggle1_button = self._pedal[2], toggle2_button = self._pedal[1], toggle3_button = self._pedal[0], toggle4_button = self._pedal[8], expression_pedal = self._pedal[9], expression2 = self._pedal[10], expression3 = self._pedal[11]) def _setup_modes(self): self._button_modes = ModesComponent(name='Button_Modes') self._button_modes.add_mode('launcher', self._launcher) self._button_modes.add_mode('looper', self._looper) self._button_modes.add_mode('device', self._device_control) self._button_modes.selected_mode = 'looper' self._button_modes.layer = Layer(looper_button = self._side_buttons[0], launcher_button = self._side_buttons[1], device_button = self._side_buttons[2]) self._button_modes.set_enabled(True) def receive_led(self, button, value): #self.log_message('receive led: ' + str(index) + ' ' + str(value)) pass def toggle_mode(self): self._button_modes.selected_mode = 'launcher' if self._button_modes.selected_mode is 'looper' else 'looper' self._last_main_mode = self._button_modes.selected_mode #self.log_message('toggle mode to: ' + str(self._button_modes.selected_mode)) def toggle_device_control(self, x): self._button_modes.selected_mode = 'device' if not self._button_modes.selected_mode is 'device' else self._last_main_mode if self._button_modes.selected_mode is 'device': self._device_control.set_bank(x) """called on timer""" def update_display(self): super(MonoWing, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer)
class Roland_A_PRO(ControlSurface): def __init__(self, *a, **k): super(Roland_A_PRO, self).__init__(*a, **k) with self.component_guard(): self._create_controls() self._create_transport() self._create_mixer() self._create_device() self._create_drums() self._create_modes() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[[ EncoderElement(MIDI_CC_TYPE, 0, identifier, Live.MidiMap.MapMode.absolute, name='Encoder_%d' % index) for index, identifier in enumerate(ENCODER_IDS) ]]) self._master_encoder = EncoderElement(MIDI_CC_TYPE, 0, 10, Live.MidiMap.MapMode.absolute, name='Master_Encoder') self._sliders = ButtonMatrixElement(rows=[[ SliderElement(MIDI_CC_TYPE, 0, identifier, name='Slider_%d' % index) for index, identifier in enumerate(SLIDER_IDS) ]]) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 7, name='Master_Slider') self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 26) self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 25) self._record_button = ButtonElement(True, MIDI_CC_TYPE, 0, 28) self._forward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 24) self._backward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 21) self._ff_button = ButtonElement(True, MIDI_CC_TYPE, 0, 23) self._rw_button = ButtonElement(True, MIDI_CC_TYPE, 0, 22) self._device_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 80) self._pan_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 81) self._send_a_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 82) self._send_b_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 83) self._pads = ButtonMatrixElement(rows=[ [ ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier) for identifier in row ] for row in PAD_ROWS ]) def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(play_button=self._play_button, stop_button=self._stop_button, record_button=self._record_button)) self._transport.set_enabled(True) def _create_mixer(self): mixer_size = self._sliders.width() self._mixer = MixerComponent(mixer_size, name='Mixer', is_enabled=False, layer=Layer(volume_controls=self._sliders, prehear_volume_control=self._master_encoder)) self._mixer.master_strip().layer = Layer(volume_control=self._master_slider) self._mixer.set_enabled(True) def _create_device(self): self._device = DeviceComponent(device_selection_follows_track_selection=True) self._device_navigation = DeviceNavigationComponent() self._device.set_enabled(True) self._device_navigation.set_enabled(True) self.set_device_component(self._device) def _create_drums(self): self._drums = DrumRackComponent(name='Drum_Rack', is_enabled=False, layer=Layer(pads=self._pads)) self._drums.set_enabled(True) def _create_modes(self): self._encoder_modes = ModesComponent() device_layer_mode = LayerMode(self._device, Layer(parameter_controls=self._encoders)) device_navigation_layer_mode = LayerMode(self._device_navigation, Layer(device_nav_right_button=self._forward_button, device_nav_left_button=self._backward_button)) self._encoder_modes.add_mode('device_mode', [device_layer_mode, device_navigation_layer_mode]) self._encoder_modes.add_mode('pan_mode', AddLayerMode(self._mixer, Layer(pan_controls=self._encoders, bank_up_button=self._forward_button, bank_down_button=self._backward_button, track_up_button=self._ff_button, track_down_button=self._rw_button))) send_layer_mode = AddLayerMode(self._mixer, Layer(send_controls=self._encoders, bank_up_button=self._forward_button, bank_down_button=self._backward_button, track_up_button=self._ff_button, track_down_button=self._rw_button)) self._encoder_modes.add_mode('send_a_mode', [send_layer_mode, partial(self._set_send_index, 0)]) self._encoder_modes.add_mode('send_b_mode', [send_layer_mode, partial(self._set_send_index, 1)]) self._encoder_modes.layer = Layer(device_mode_button=self._device_mode_button, pan_mode_button=self._pan_mode_button, send_a_mode_button=self._send_a_mode_button, send_b_mode_button=self._send_b_mode_button) self._encoder_modes.selected_mode = 'device_mode' self._encoder_modes.set_enabled(True) def _set_send_index(self, index): self._mixer.send_index = index
class Launchkey_MK2(OptimizedControlSurface): identity_request_delay = 0.5 def __init__(self, c_instance, *a, **k): super(Launchkey_MK2, self).__init__(c_instance=c_instance, *a, **k) self._is_25_key_model = False self._is_in_control_on = True with self.component_guard(): self._skin = make_skin() with inject(skin=const(self._skin)).everywhere(): self._create_controls() self._request_task = self._tasks.add(Task.sequence(Task.wait(self.identity_request_delay), Task.run(self._send_identity_request))) self._request_task.kill() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[[ make_encoder(identifier, name='Encoder_%d' % (index,)) for index, identifier in enumerate(xrange(21, 29)) ]]) self._top_pad_row = ButtonMatrixElement(rows=[[ make_button(identifier, name='Pad_0_%d' % (index,)) for index, identifier in enumerate(xrange(96, 104)) ]]) self._bottom_pad_row_raw = [ make_button(identifier, name='Pad_1_%d' % (index,)) for index, identifier in enumerate(xrange(112, 120)) ] self._bottom_pad_row = ButtonMatrixElement(rows=[self._bottom_pad_row_raw]) self._top_launch_button = make_button(104, name='Scene_Launch_Button') self._bottom_launch_button = make_button(120, name='Stop_All_Clips_Button') self._scene_up_button = make_button(112, MIDI_CC_TYPE, name='Scene_Up_Button') self._scene_down_button = make_button(113, MIDI_CC_TYPE, name='Scene_Down_Button') self._stop_button = make_button(114, MIDI_CC_TYPE, name='Stop_Button') self._play_button = make_button(115, MIDI_CC_TYPE, name='Play_Button') self._loop_button = make_button(116, MIDI_CC_TYPE, name='Loop_Button') self._record_button = make_button(117, MIDI_CC_TYPE, name='Record_Button') self._sliders = ButtonMatrixElement(rows=[[ make_slider(identifier, name='Slider_%d' % (index,)) for index, identifier in enumerate(xrange(41, 49)) ]]) self._master_slider = make_slider(7, name='Master_Slider') self._25_key_slider = make_slider(7, name='Slider', channel=0) self._mute_buttons_raw = [ make_button(identifier, MIDI_CC_TYPE, name='Mute_Button_%d' % (index,)) for index, identifier in enumerate(xrange(51, 59)) ] self._mute_buttons = ButtonMatrixElement(rows=[self._mute_buttons_raw]) self._master_button = make_button(59, MIDI_CC_TYPE, name='Master_Button') self._track_left_button = make_button(102, MIDI_CC_TYPE, name='Track_Left_Button') self._track_right_button = make_button(103, MIDI_CC_TYPE, name='Track_Right_Button') self._device_mode_button = self._bottom_pad_row_raw[0] self._pan_mode_button = self._bottom_pad_row_raw[1] self._send_mode_buttons = dict() for index in xrange(consts.MAX_SENDS): setattr(self, '_send_%d_button' % (index,), self._bottom_pad_row_raw[index + 2]) self._send_mode_buttons['send_%d_mode_button' % (index,)] = getattr(self, '_send_%d_button' % (index,)) self._extended_mode_button = make_button(12, name='Dummy_Extended_Mode_Button') self._extended_mode_button.add_value_listener(nop) self._encoder_incontrol_button = make_button(13, is_momentary=False, name='Encoder_InControl_Button') self._encoder_incontrol_button.add_value_listener(nop) self._slider_incontrol_button = make_button(14, is_momentary=False, name='Fader_InControl_Button') self._slider_incontrol_button.add_value_listener(nop) self._pad_incontrol_button = make_button(15, is_momentary=False, name='Pad_InControl_Button') self._pad_incontrol_button.add_value_listener(self._update_pads) self._encoder_incontrol_button2 = make_button(16, name='Encoder_InControl_Button') self._pad_in_control_status_button = make_button(11, name='Dummy_InControl_Button') def _create_session(self): self._session = SessionComponent(name='Session', is_enabled=False, num_tracks=self._top_pad_row.width(), num_scenes=self._top_pad_row.height(), enable_skinning=True, layer=Layer(clip_launch_buttons=self._top_pad_row, scene_launch_buttons=ButtonMatrixElement(rows=[[self._top_launch_button]]), stop_track_clip_buttons=self._bottom_pad_row, stop_all_clips_button=self._bottom_launch_button)) self._session.set_rgb_mode(CLIP_COLOR_TABLE, RGB_COLOR_TABLE) self._session.set_mixer(self._mixer) self._session.set_enabled(True) def _setup_navigation(self): self._session_navigation = SessionNavigationComponent(is_enabled=False, name='Session_Navigation', layer=Layer(next_track_button=self._track_right_button, prev_track_button=self._track_left_button, next_scene_button=self._scene_down_button, prev_scene_button=self._scene_up_button)) self._session_navigation.set_enabled(True) def _create_transport(self): self._transport = TransportComponent(is_enabled=False, name='Transport', layer=Layer(play_button=self._play_button, stop_button=self._stop_button, loop_button=self._loop_button, record_button=self._record_button)) self._transport.set_enabled(True) def _create_mixer(self): mixer_volume_layer = None if self._is_25_key_model: mixer_volume_layer = Layer(volume_control=self._25_key_slider) else: mixer_volume_layer = Layer(volume_controls=self._sliders) self._mixer = MixerComponent(is_enabled=False, name='Mixer', num_tracks=self._sliders.width(), layer=mixer_volume_layer) if not self._is_25_key_model: self._mixer.master_strip().layer = Layer(volume_control=self._master_slider) self._mixer.set_enabled(True) self._mute_button_modes = ModesComponent() mute_mode = AddLayerMode(self._mixer, Layer(mute_buttons=self._mute_buttons)) solo_mode = AddLayerMode(self._mixer, Layer(solo_buttons=self._mute_buttons)) self._mute_button_modes.add_mode('mute_mode', mute_mode) self._mute_button_modes.add_mode('solo_mode', solo_mode, behaviour=CancellableBehaviour()) self._mute_button_modes.layer = Layer(solo_mode_button=self._master_button) self._mute_button_modes.selected_mode = 'mute_mode' self._mute_button_modes.set_enabled(True) def _create_device(self): self._device = DeviceComponent(name='Device', is_enabled=False, device_selection_follows_track_selection=True) self.set_device_component(self._device) self._device.set_enabled(True) def _create_background(self): self._background = BackgroundComponent(name='BackgroundComponent') def _create_encoder_modes(self): self._encoder_modes = DisablingModesComponent() self._encoder_modes.default_behaviour = mixin(SkinableBehaviourMixin, ImmediateBehaviour)() device_mode = LayerMode(self._device, Layer(parameter_controls=self._encoders, bank_buttons=self._top_pad_row)) pan_mode = AddLayerMode(self._mixer, Layer(pan_controls=self._encoders)) sends_mode = AddLayerMode(self._mixer, Layer(send_controls=self._encoders)) background_mode = LayerMode(self._background, Layer(bank_buttons=self._top_pad_row)) self._encoder_modes.add_mode('device_mode', device_mode, is_enabled=True) self._encoder_modes.add_mode('pan_mode', [pan_mode, background_mode], is_enabled=True) for index in xrange(6): self._encoder_modes.add_mode('send_%d_mode' % (index,), [sends_mode, partial(self._set_send_index, index), background_mode], is_enabled=False) self._encoder_modes.selected_mode = 'device_mode' self._encoder_modes.set_enabled(True) def _create_mode_selector(self): self._mode_selector = ModesComponent() mode_selection = LayerMode(self._encoder_modes, Layer(device_mode_button=self._device_mode_button, pan_mode_button=self._pan_mode_button, **self._send_mode_buttons)) device_navigation = AddLayerMode(self._device, Layer(device_nav_left_button=self._track_left_button, device_nav_right_button=self._track_right_button)) self._mode_selector.add_mode('mode_selection', [partial(self._toggle_in_control, True), mode_selection, device_navigation], behaviour=MomentaryBehaviour()) session_control = AddLayerMode(self._session, Layer(clip_launch_buttons=self._top_pad_row)) self._mode_selector.add_mode('session_mode', [partial(self._toggle_in_control, False), session_control]) self._mode_selector.layer = Layer(mode_selection_button=self._encoder_incontrol_button2) def _create_in_control_status_listener(self): self._in_control_status = InControlStatusComponent(set_is_in_control_on=self._set_is_in_control_on, is_enabled=False, layer=Layer(in_control_status_button=self._pad_in_control_status_button)) self._in_control_status.set_enabled(True) @subject_slot('value') def _update_pads(self, value): if value: self.update() @subject_slot('return_tracks') def _on_return_tracks_changed(self): num_sends = self._mixer.num_sends for index in xrange(6): self._encoder_modes.set_mode_enabled('send_%d_mode' % (index,), True if index < num_sends else False) def _set_send_index(self, index): self._mixer.send_index = index def _set_is_in_control_on(self, value): self._is_in_control_on = value def _toggle_in_control(self, value): if not self._is_in_control_on: self._send_midi(consts.DRUM_IN_CONTROL_ON_MESSAGE if value else consts.DRUM_IN_CONTROL_OFF_MESSAGE) def port_settings_changed(self): self._disconnect_and_unregister_all_components() self._request_task.restart() def handle_sysex(self, midi_bytes): if self._is_identity_response(midi_bytes): product_id_bytes = self._extract_product_id_bytes(midi_bytes) if self._is_identity_response_valid(product_id_bytes): self._set_model_type(product_id_bytes) self._request_task.kill() self.on_identified() else: self.log_message('MIDI device responded with wrong product id (%s).' % (str(product_id_bytes),)) else: super(Launchkey_MK2, self).handle_sysex(midi_bytes) def _extract_product_id_bytes(self, midi_bytes): return midi_bytes[5:] def _is_identity_response(self, midi_bytes): return midi_bytes[3:5] == (6, 2) def _is_identity_response_valid(self, product_id_bytes): return product_id_bytes[:3] == consts.PRODUCT_ID_BYTE_PREFIX and product_id_bytes[3] in consts.PRODUCT_ID_BYTES def _set_model_type(self, product_id_bytes): self._is_25_key_model = product_id_bytes[3] == consts.LAUNCHKEY_25_ID_BYTE def _send_identity_request(self): self._send_midi(consts.IDENTITY_REQUEST) def on_identified(self): self._extended_mode_button.turn_on() with self.component_guard(): self._create_mixer() self._create_session() self._setup_navigation() self._create_transport() self._create_device() self._create_background() self._create_encoder_modes() self._create_mode_selector() self._create_in_control_status_listener() self._on_return_tracks_changed.subject = self.song() self._on_return_tracks_changed() self._mode_selector.selected_mode = 'session_mode' self.update() def disconnect(self): self._extended_mode_button.turn_off() super(Launchkey_MK2, self).disconnect()
class Launchpad_Pro(IdentifiableControlSurface, OptimizedControlSurface): identity_request = consts.SYSEX_IDENTITY_REQUEST def __init__(self, c_instance, *a, **k): product_id_bytes = consts.MANUFACTURER_ID + consts.DEVICE_CODE super(Launchpad_Pro, self).__init__(c_instance=c_instance, product_id_bytes=product_id_bytes, *a, **k) self._challenge = Live.Application.get_random_int( 0, 400000000) & 2139062143 with self.component_guard(): self._skin = make_default_skin() with inject(skin=const(self._skin)).everywhere(): self._midimap = MidiMap() self._target_track_component = TargetTrackComponent( name=u'Target_Track') self._create_background() self._create_global_component() self._last_sent_mode_byte = None with inject(layout_setup=const(self._layout_setup), should_arm=const(self._should_arm_track)).everywhere(): self._create_session() self._create_recording() self._create_actions() self._create_drums() self._create_mixer() self._create_device() self._create_modes() self._create_user() self._on_session_record_changed.subject = self.song() self.set_device_component(self._device) self._on_session_record_changed() def disconnect(self): self._send_midi(consts.TURN_OFF_LEDS) self._send_midi(consts.QUIT_MESSAGE) super(Launchpad_Pro, self).disconnect() def _create_background(self): self._modifier_background_component = ModifierBackgroundComponent( name=u'Background_Component', is_enabled=False, layer=Layer(shift_button=self._midimap[u'Shift_Button'])) self._shifted_background = BackgroundComponent( name=u'No_Op_Shifted_Buttons', is_enabled=False, layer=Layer( click_bitton=self._midimap.with_shift(u'Click_Button'), delete_button=self._midimap.with_shift(u'Delete_Button'), duplicate_button=self._midimap.with_shift(u'Duplicate_Button'), double_button=self._midimap.with_shift(u'Double_Loop_Button'), session_record_button=self._midimap.with_shift( u'Session_Record_Button'))) def _create_global_component(self): self._actions_component = ActionsComponent( name=u'Global_Actions', is_enabled=False, layer=Layer(undo_button=self._midimap[u'Undo_Button'], redo_button=self._midimap.with_shift(u'Undo_Button'), metronome_button=self._midimap[u'Click_Button'], quantization_on_button=self._midimap.with_shift( u'Quantize_Button'))) def _create_session(self): self._session = SessionComponent( NUM_TRACKS, NUM_SCENES, auto_name=True, is_enabled=False, enable_skinning=True, layer=Layer( track_bank_left_button=self._midimap[u'Arrow_Left_Button'], track_bank_right_button=self._midimap[u'Arrow_Right_Button'], scene_bank_up_button=self._midimap[u'Arrow_Up_Button'], scene_bank_down_button=self._midimap[u'Arrow_Down_Button'])) self._session.set_enabled(True) self._session.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES, RGB_COLOR_TABLE) SpecialClipSlotComponent.quantization_component = self._actions_component for scene_index in xrange(NUM_SCENES): scene = self._session.scene(scene_index) scene.layer = Layer( select_button=self._midimap[u'Shift_Button'], delete_button=self._midimap[u'Delete_Button'], duplicate_button=self._midimap[u'Duplicate_Button']) for track_index in xrange(NUM_TRACKS): slot = scene.clip_slot(track_index) slot.layer = Layer( select_button=self._midimap[u'Shift_Button'], delete_button=self._midimap[u'Delete_Button'], duplicate_button=self._midimap[u'Duplicate_Button'], double_loop_button=self._midimap[u'Double_Loop_Button'], quantize_button=self._midimap[u'Quantize_Button']) self._session_zoom = SessionZoomingComponent(self._session, name=u'Session_Overview', is_enabled=True, enable_skinning=True) def _create_recording(self): self._session_record = SpecialSessionRecordingComponent( self._target_track_component, name=u'Session_Recording', is_enabled=False, layer=Layer(record_button=self._midimap[u'Session_Record_Button'])) def _create_actions(self): self._clip_actions_component = ClipActionsComponent( self._target_track_component, name=u'Clip_Actions', is_enabled=False, layer=Layer(duplicate_button=self._midimap[u'Duplicate_Button'], double_button=self._midimap[u'Double_Loop_Button'], quantize_button=self._midimap[u'Quantize_Button'])) ClipActionsComponent.quantization_component = self._actions_component def _create_drums(self): self._drum_group_finder = DrumGroupFinderComponent( self._target_track_component, name=u'Drum_Group_Finder', is_enabled=False, layer=None) self._on_drum_group_changed.subject = self._drum_group_finder self._drum_group_finder.set_enabled(True) self._drum_group = DrumGroupComponent( self._clip_actions_component, name=u'Drum_Group_Control', translation_channel=consts.DR_MAP_CHANNEL) self._drum_group.set_enabled(True) def _create_mixer(self): self._mixer = SpecialMixerComponent(NUM_TRACKS, auto_name=True, is_enabled=True, invert_mute_feedback=True) self._mixer.name = u'Mixer_Control' self._session.set_mixer(self._mixer) def _create_device(self): self._device = SpecialDeviceComponent( name=u'Device_Control', is_enabled=False, device_selection_follows_track_selection=True) self._device_navigation = DeviceNavigationComponent( name=u'Device_Navigation') self._device_background = BackgroundComponent( name=u'Device_Background_Component') def _setup_drum_group(self): self._drum_group.set_drum_group_device( self._drum_group_finder.drum_group) def _create_translation(self, comp_name, channel, button_layer, should_enable=True, should_reset=True): translation_component = TranslationComponent( name=comp_name, translated_channel=channel, should_enable=should_enable, should_reset=should_reset, is_enabled=False, layer=button_layer) setattr(self, u'_' + comp_name.lower(), translation_component) return translation_component def _create_modes(self): self._modes = ModesComponent(name=u'Launchpad_Modes', is_enabled=False) self._session_layer_mode = AddLayerMode( self._session, Layer(scene_launch_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'], clip_launch_buttons=self._midimap[u'Main_Button_Matrix'], delete_button=self._midimap[u'Delete_Button'], duplicate_button=self._midimap[u'Duplicate_Button'], double_button=self._midimap[u'Double_Loop_Button'], quantize_button=self._midimap[u'Quantize_Button'])) action_button_background = BackgroundComponent(name=u'No_Op_Buttons') self._action_button_background_layer_mode = LayerMode( action_button_background, Layer(delete_button=self._midimap[u'Delete_Button'], quantize_button=self._midimap[u'Quantize_Button'], duplicate_button=self._midimap[u'Duplicate_Button'], double_button=self._midimap[u'Double_Loop_Button'])) self._clip_delete_layer_mode = AddLayerMode( self._clip_actions_component, layer=Layer(delete_button=self._midimap[u'Delete_Button'])) self._create_session_zooming_modes() self._create_session_mode() self._create_note_modes() self._create_device_mode() self._create_user_mode() self._create_record_arm_mode() self._create_track_select_mode() self._create_mute_mode() self._create_solo_mode() self._create_volume_mode() self._create_pan_mode() self._create_sends_mode() self._create_stop_clips_mode() self._modes.layer = Layer( session_mode_button=self._midimap[u'Session_Mode_Button'], note_mode_button=self._midimap[u'Note_Mode_Button'], device_mode_button=self._midimap[u'Device_Mode_Button'], user_mode_button=self._midimap[u'User_Mode_Button'], record_arm_mode_button=self._midimap[u'Record_Arm_Mode_Button'], track_select_mode_button=self. _midimap[u'Track_Select_Mode_Button'], mute_mode_button=self._midimap[u'Mute_Mode_Button'], solo_mode_button=self._midimap[u'Solo_Mode_Button'], volume_mode_button=self._midimap[u'Volume_Mode_Button'], pan_mode_button=self._midimap[u'Pan_Mode_Button'], sends_mode_button=self._midimap[u'Sends_Mode_Button'], stop_clip_mode_button=self._midimap[u'Stop_Clip_Mode_Button']) self._modes.selected_mode = u'session_mode' self._on_layout_changed.subject = self._modes def _create_session_zooming_modes(self): session_zoom_layer = Layer( button_matrix=self._midimap[u'Main_Button_Matrix'], nav_left_button=self._midimap[u'Arrow_Left_Button'], nav_right_button=self._midimap[u'Arrow_Right_Button'], nav_up_button=self._midimap[u'Arrow_Up_Button'], nav_down_button=self._midimap[u'Arrow_Down_Button']) session_zooming_layer_mode = LayerMode(self._session_zoom, session_zoom_layer) self._session_zooming_manager = SessionZoomingManagerComponent( self._modes, is_enabled=False) session_zooming_button_layer_mode = LayerMode( self._session_zooming_manager, Layer( session_zooming_button=self._midimap[u'Session_Mode_Button'])) self._prioritized_session_zooming_button_layer_mode = LayerMode( self._session_zooming_manager, Layer(session_zooming_button=self._midimap[u'Session_Mode_Button'], priority=1)) self._session_zooming_background = BackgroundComponent( name=u'Session_Zooming_Background') session_zooming_background_layer_mode = LayerMode( self._session_zooming_background, Layer(scene_launch_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'], delete_button=self._midimap[u'Delete_Button'], quantize_button=self._midimap[u'Quantize_Button'], duplicate_button=self._midimap[u'Duplicate_Button'], double_loop_button=self._midimap[u'Double_Loop_Button'])) self._modes.add_mode(u'session_zooming_mode', [ self._session_zooming_manager, session_zooming_button_layer_mode, session_zooming_layer_mode, session_zooming_background_layer_mode ]) self._modes.add_mode(u'prioritized_session_zooming_mode', [ partial(self._layout_switch, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, session_zooming_layer_mode, session_zooming_background_layer_mode, self.update ]) def _create_session_mode(self): self._modes.add_mode( u'session_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, self._session.update_navigation_buttons ], behaviour=CancelingReenterBehaviour(u'session_zooming_mode')) def _create_note_modes(self): note_mode_matrix_translation = self._create_translation( u'Note_Mode_Matrix_Translation', consts.CHROM_MAP_CHANNEL, Layer(button_matrix=self._midimap[u'Main_Button_Matrix'], note_button_matrix=self._midimap[u'Note_Button_Matrix'], drum_matrix=self._midimap[u'Drum_Button_Matrix'], mixer_button_matrix=self._midimap[u'Mixer_Button_Matrix']), should_enable=False) note_mode_scene_launch_translation = self._create_translation( u'Note_Mode_Scene_Launch_Translation', consts.CHROM_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'])) scale_setup_mode_button_lighting = LedLightingComponent( name=u'LED_Lighting_Component', is_enabled=False, layer=Layer(button=self._midimap.with_shift(u'Note_Mode_Button'))) drum_mode_note_matrix_translation = self._create_translation( u'Drum_Mode_Note_Button_Translation', 0, Layer(note_button_matrix=self._midimap[u'Note_Button_Matrix']), should_enable=False, should_reset=False) drum_group_layer_mode = LayerMode( self._drum_group, layer=Layer( scroll_up_button=self._midimap[u'Arrow_Left_Button'], scroll_down_button=self._midimap[u'Arrow_Right_Button'], scroll_page_up_button=self._midimap[u'Arrow_Up_Button'], scroll_page_down_button=self._midimap[u'Arrow_Down_Button'], drum_matrix=self._midimap[u'Drum_Button_Matrix'], select_button=self._midimap[u'Shift_Button'], delete_button=self._midimap[u'Delete_Button'])) self._note_modes = SpecialModesComponent(name=u'Note_Modes') self._note_modes.add_mode(u'chromatic_mode', [ partial(self._layout_setup, consts.NOTE_LAYOUT_SYSEX_BYTE), self._clip_delete_layer_mode, note_mode_matrix_translation, scale_setup_mode_button_lighting ]) self._note_modes.add_mode(u'drum_mode', [ partial(self._layout_setup, consts.DRUM_LAYOUT_SYSEX_BYTE), self._setup_drum_group, drum_group_layer_mode, drum_mode_note_matrix_translation ]) self._note_modes.add_mode(u'audio_mode', [ partial(self._layout_setup, consts.AUDIO_LAYOUT_SYSEX_BYTE), self._clip_delete_layer_mode ]) self._note_modes.set_enabled(False) self._modes.add_mode(u'note_mode', [ note_mode_scene_launch_translation, self._note_modes, self._select_note_mode, self._select_target_track, self._clip_actions_component, self._show_playing_clip, self._set_clip_actions_type ], behaviour=ReenterBehaviour( self.toggle_detail_view)) self._session_record.set_modes_component(self._modes) self._session_record.set_note_mode_name(u'note_mode') def _create_device_mode(self): device_mode_scene_launch_translation = self._create_translation( u'Device_Mode_Scene_Launch_Translation', consts.DEVICE_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'])) device_layer_mode = LayerMode( self._device, layer=Layer( parameter_controls=self._midimap[u'Slider_Button_Matrix'])) device_nav_layer_mode = LayerMode( self._device_navigation, layer=Layer( device_nav_left_button=self._midimap[u'Arrow_Left_Button'], device_nav_right_button=self._midimap[u'Arrow_Right_Button'])) device_background_layer_mode = LayerMode( self._device_background, layer=Layer(arrow_up_button=self._midimap[u'Arrow_Up_Button'], arrow_down_button=self._midimap[u'Arrow_Down_Button'])) self._modes.add_mode(u'device_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), self._device, device_layer_mode, device_nav_layer_mode, device_background_layer_mode, self._clip_actions_component, self._clip_delete_layer_mode, device_mode_scene_launch_translation, self._show_playing_clip, self._set_clip_actions_type ], behaviour=ReenterBehaviour( self.toggle_detail_view)) def _create_user_mode(self): self._modes.add_mode( u'user_mode', [partial(self._layout_setup, consts.USER_LAYOUT_SYSEX_BYTE)]) def _create_record_arm_mode(self): arm_layer_mode = LayerMode( self._mixer, layer=Layer(arm_buttons=self._midimap[u'Mixer_Button_Matrix'])) self._modes.add_mode( u'record_arm_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, arm_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_track_select_mode(self): track_select_layer_mode = LayerMode( self._mixer, layer=Layer( track_select_buttons=self._midimap[u'Mixer_Button_Matrix'])) self._modes.add_mode( u'track_select_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, track_select_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_mute_mode(self): mute_layer_mode = LayerMode( self._mixer, layer=Layer(mute_buttons=self._midimap[u'Mixer_Button_Matrix'])) self._modes.add_mode( u'mute_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, mute_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_solo_mode(self): solo_layer_mode = LayerMode( self._mixer, layer=Layer(solo_buttons=self._midimap[u'Mixer_Button_Matrix'])) self._modes.add_mode( u'solo_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, solo_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_volume_mode(self): volume_mode_scene_launch_translation = self._create_translation( u'Volume_Mode_Scene_Launch_Translation', consts.VOLUME_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'])) volume_layer_mode = LayerMode( self._mixer, layer=Layer( volume_controls=self._midimap[u'Slider_Button_Matrix'])) self._modes.add_mode( u'volume_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), volume_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, volume_mode_scene_launch_translation, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_pan_mode(self): pan_mode_scene_launch_translation = self._create_translation( u'Pan_Mode_Scene_Launch_Translation', consts.PAN_MAP_CHANNEL, Layer(scene_launch_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'])) pan_layer_mode = LayerMode( self._mixer, layer=Layer(pan_controls=self._midimap[u'Slider_Button_Matrix'])) self._modes.add_mode( u'pan_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), pan_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, pan_mode_scene_launch_translation, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_sends_mode(self): send_layer_mode = LayerMode( self._mixer, layer=Layer(send_controls=self._midimap[u'Slider_Button_Matrix'], send_select_buttons=self. _midimap[u'Scene_Launch_Button_Matrix'])) self._modes.add_mode( u'sends_mode', [ partial(self._layout_setup, consts.FADER_LAYOUT_SYSEX_BYTE), send_layer_mode, self._action_button_background_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def _create_stop_clips_mode(self): stop_layer_mode = AddLayerMode( self._session, Layer( stop_track_clip_buttons=self._midimap[u'Mixer_Button_Matrix'], stop_scene_clip_buttons=self. _midimap[u'Scene_Stop_Button_Matrix'], stop_all_clips_button=self._midimap[u'Stop_All_Clips_Button'])) self._modes.add_mode( u'stop_clip_mode', [ partial(self._layout_setup, consts.SESSION_LAYOUT_SYSEX_BYTE), self._session_layer_mode, stop_layer_mode, self._session_zooming_manager, self._prioritized_session_zooming_button_layer_mode, self._session.update_navigation_buttons ], behaviour=SpecialReenterBehaviour(u'session_mode')) def toggle_detail_view(self): view = self.application().view if view.is_view_visible(u'Detail'): if view.is_view_visible(u'Detail/DeviceChain'): view.show_view(u'Detail/Clip') else: view.show_view(u'Detail/DeviceChain') def _create_user(self): self._user_matrix_component = UserMatrixComponent( name=u'User_Matrix_Component', is_enabled=False, layer=Layer(user_button_matrix_ch_6=self. _midimap[u'User_Button_Matrix_Ch_6'], user_button_matrix_ch_7=self. _midimap[u'User_Button_Matrix_Ch_7'], user_button_matrix_ch_8=self. _midimap[u'User_Button_Matrix_Ch_8'], user_button_matrix_ch_14=self. _midimap[u'User_Button_Matrix_Ch_14'], user_button_matrix_ch_15=self. _midimap[u'User_Button_Matrix_Ch_15'], user_button_matrix_ch_16=self. _midimap[u'User_Button_Matrix_Ch_16'], user_left_side_button_matrix_ch_6=self. _midimap[u'User_Left_Side_Button_Matrix_Ch_6'], user_left_side_button_matrix_ch_7=self. _midimap[u'User_Left_Side_Button_Matrix_Ch_7'], user_left_side_button_matrix_ch_8=self. _midimap[u'User_Left_Side_Button_Matrix_Ch_8'], user_left_side_button_matrix_ch_14=self. _midimap[u'User_Left_Side_Button_Matrix_Ch_14'], user_left_side_button_matrix_ch_15=self. _midimap[u'User_Left_Side_Button_Matrix_Ch_15'], user_left_side_button_matrix_ch_16=self. _midimap[u'User_Left_Side_Button_Matrix_Ch_16'], user_right_side_button_matrix_ch_6=self. _midimap[u'User_Right_Side_Button_Matrix_Ch_6'], user_right_side_button_matrix_ch_7=self. _midimap[u'User_Right_Side_Button_Matrix_Ch_7'], user_right_side_button_matrix_ch_8=self. _midimap[u'User_Right_Side_Button_Matrix_Ch_8'], user_right_side_button_matrix_ch_14=self. _midimap[u'User_Right_Side_Button_Matrix_Ch_14'], user_right_side_button_matrix_ch_15=self. _midimap[u'User_Right_Side_Button_Matrix_Ch_15'], user_right_side_button_matrix_ch_16=self. _midimap[u'User_Right_Side_Button_Matrix_Ch_16'], user_bottom_button_matrix_ch_6=self. _midimap[u'User_Bottom_Button_Matrix_Ch_6'], user_bottom_button_matrix_ch_7=self. _midimap[u'User_Bottom_Button_Matrix_Ch_7'], user_bottom_button_matrix_ch_8=self. _midimap[u'User_Bottom_Button_Matrix_Ch_8'], user_bottom_button_matrix_ch_14=self. _midimap[u'User_Bottom_Button_Matrix_Ch_14'], user_bottom_button_matrix_ch_15=self. _midimap[u'User_Bottom_Button_Matrix_Ch_15'], user_bottom_button_matrix_ch_16=self. _midimap[u'User_Bottom_Button_Matrix_Ch_16'], user_arrow_button_matrix_ch_6=self. _midimap[u'User_Arrow_Button_Matrix_Ch_6'], user_arrow_button_matrix_ch_7=self. _midimap[u'User_Arrow_Button_Matrix_Ch_7'], user_arrow_button_matrix_ch_8=self. _midimap[u'User_Arrow_Button_Matrix_Ch_8'], user_arrow_button_matrix_ch_14=self. _midimap[u'User_Arrow_Button_Matrix_Ch_14'], user_arrow_button_matrix_ch_15=self. _midimap[u'User_Arrow_Button_Matrix_Ch_15'], user_arrow_button_matrix_ch_16=self. _midimap[u'User_Arrow_Button_Matrix_Ch_16'])) self._user_matrix_component.set_enabled(True) @subject_slot(u'drum_group') def _on_drum_group_changed(self): if self._note_modes.selected_mode == u'drum_mode': self._drum_group.set_drum_group_device( self._drum_group_finder.drum_group) if self._modes.selected_mode == u'note_mode': self._select_note_mode() else: self.release_controlled_track() self._update_note_mode_button( self._drum_group_finder.drum_group is not None) def _select_note_mode(self): u""" Selects which note mode to use depending on the kind of current target track and its device chain. Will also select the target if specified. """ track = self._target_track_component.target_track drum_device = self._drum_group_finder.drum_group if track is None or track.is_foldable or track in self.song( ).return_tracks or track == self.song( ).master_track or track.is_frozen or track.has_audio_input: self._note_modes.selected_mode = u'audio_mode' elif drum_device: self._note_modes.selected_mode = u'drum_mode' else: self._note_modes.selected_mode = u'chromatic_mode' self._modes.update() if self._note_modes.selected_mode == u'audio_mode': self.release_controlled_track() else: self.set_controlled_track( self._target_track_component.target_track) def _select_target_track(self): track = self._target_track_component.target_track if track != self.song().view.selected_track: self.song().view.selected_track = track def _update_note_mode_button(self, focused_track_is_drum_track): button = self._midimap[u'Note_Mode_Button'] if focused_track_is_drum_track: button.default_states = { True: u'Mode.Drum.On', False: u'Mode.Drum.Off' } else: button.default_states = { True: u'Mode.Chromatic.On', False: u'Mode.Chromatic.Off' } button.reset_state() self._modes.update() def _show_playing_clip(self): track = None if self._use_sel_track(): track = self.song().view.selected_track else: track = self._target_track_component.target_track if track in self.song().tracks: slot_index = track.fired_slot_index if slot_index < 0: slot_index = track.playing_slot_index if slot_index >= 0: clip_slot = track.clip_slots[slot_index] self.song().view.highlighted_clip_slot = clip_slot def _set_clip_actions_type(self): self._clip_actions_component.use_selected_track(self._use_sel_track()) self._clip_actions_component.update() def _use_sel_track(self): return self._modes.selected_mode == u'device_mode' def _should_arm_track(self): return self._modes.selected_mode == u'record_arm_mode' @subject_slot(u'selected_mode') def _on_layout_changed(self, mode): if mode == u'note_mode': self.set_controlled_track( self._target_track_component.target_track) else: self.release_controlled_track() self._session_record.set_enabled(mode != u'user_mode') @subject_slot(u'session_record') def _on_session_record_changed(self): status = self.song().session_record feedback_color = int(self._skin[u'Instrument.FeedbackRecord'] if status else self._skin[u'Instrument.Feedback']) self._c_instance.set_feedback_velocity(feedback_color) def _clear_send_cache(self): with self.component_guard(): for control in self.controls: control.clear_send_cache() def _update_hardware(self): self._clear_send_cache() self.update() def _update_global_components(self): self._actions_component.update() self._session_record.update() self._modifier_background_component.update() def _layout_setup(self, mode): self._layout_switch(mode) self._clear_send_cache() self._update_global_components() def _layout_switch(self, mode): prefix = consts.SYSEX_STANDARD_PREFIX + consts.SYSEX_PARAM_BYTE_LAYOUT suffix = consts.SYSEX_STANDARD_SUFFIX self._send_midi(prefix + mode + suffix) self._last_sent_mode_byte = mode def port_settings_changed(self): self.set_highlighting_session_component(None) super(Launchpad_Pro, self).port_settings_changed() def on_identified(self): self._send_challenge() def _send_challenge(self): challenge_bytes = [] for index in range(4): challenge_bytes.append(self._challenge >> 8 * index & 127) challenge = consts.CHALLENGE_PREFIX + tuple(challenge_bytes) + (247, ) self._send_midi(challenge) def _on_handshake_successful(self): self._do_send_midi(consts.LIVE_MODE_SWITCH_REQUEST) with self.component_guard(): self._modes.set_enabled(True) self._actions_component.set_enabled(True) self._session_record.set_enabled(True) self._modifier_background_component.set_enabled(True) self._shifted_background.set_enabled(True) self.release_controlled_track() self.set_feedback_channels(consts.FEEDBACK_CHANNELS) if self._last_sent_mode_byte is not None: self._layout_setup(self._last_sent_mode_byte) self.set_highlighting_session_component(self._session) self.update() def _is_challenge_response(self, midi_bytes): return len( midi_bytes ) == 10 and midi_bytes[:7] == consts.SYSEX_STANDARD_PREFIX + consts.SYSEX_CHALLENGE_RESPONSE_BYTE def _is_response_valid(self, midi_bytes): response = long(midi_bytes[7]) response += long(midi_bytes[8] << 8) return response == Live.Application.encrypt_challenge2(self._challenge) def handle_sysex(self, midi_bytes): if len(midi_bytes) < 7: pass elif self._is_challenge_response( midi_bytes) and self._is_response_valid(midi_bytes): self._on_handshake_successful() elif midi_bytes[6] == consts.SYSEX_STATUS_BYTE_LAYOUT and midi_bytes[ 7] == consts.NOTE_LAYOUT_SYSEX_BYTE[0]: self._update_hardware() elif midi_bytes[6] in (consts.SYSEX_STATUS_BYTE_MODE, consts.SYSEX_STATUS_BYTE_LAYOUT): pass else: super(Launchpad_Pro, self).handle_sysex(midi_bytes)
class Crate(ControlSurface): __module__ = __name__ __doc__ = " Monomodular controller script for Crate " def __init__(self, *a, **k): super(Crate, self).__init__(*a, **k) self._host_name = 'Crate' self._version_check = '1.0' self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_session() self._setup_next_buttons() self._setup_tempo() self._setup_modes() self._create_fallback_control_owner() self.schedule_message(1, self._open_log) self.schedule_message(3, self._initialize_surface) def _open_log(self): self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") self.show_message(str(self._host_name) + ' Control Surface Loaded') def _initialize_surface(self): debug('setting to main mode') #self._main_modes.selected_mod = 'Main' #self._session.set_enabled(True) def port_settings_changed(self): debug('port settings changed!') self._connected = False super(Crate, self).port_settings_changed() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _with_shift(self, button): return ComboElement(button, modifiers=[self._shift_button]) def _setup_controls(self): self._button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index, name = 'Button_' + str(index), script = self) for index in range(20)] self._track_button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index+50, name = 'Button_' + str(index+50), script = self) for index in range(6)] self._next_button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index+60, name = 'Button_' + str(index+60), script = self) for index in range(2)] self._crate_button = [CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index+70, name = 'Button_' + str(index+70), script = self) for index in range(3)] #self._tempo_slider = EncoderElement(MIDI_CC_TYPE, 0, 0, Live.MidiMap.MapMode.absolute, name = 'Slider') self._matrix = ButtonMatrixElement(name = 'Matrix', rows = [[self._button[index]] for index in range(20)]) self._left_matrix = ButtonMatrixElement(name = 'Left_Matrix', rows = [[self._button[index]] for index in range(10)]) self._right_matrix = ButtonMatrixElement(name = 'Right_Matrix', rows = [[self._button[index+10]] for index in range(10)]) self._track_select_matrix = ButtonMatrixElement(name = 'Track_Matrix', rows = [self._track_button]) def _setup_session(self): self._left_session = CrateSessionComponent(script = self, name = 'Session_Component_A', num_tracks = 1, num_scenes = 20, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._matrix, track_nav_buttons = self._track_select_matrix)) self._left_session.set_group_track('DECK A') self._left_session_zooming = SessionZoomingComponent(session = self._left_session) self._right_session = CrateSessionComponent(script = self, name = 'Session_Component_B', num_tracks = 1, num_scenes = 20, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._matrix, track_nav_buttons = self._track_select_matrix)) self._right_session.set_group_track('DECK B') self._right_session_zooming = SessionZoomingComponent(session = self._right_session) self._left_set_session = CrateSetSessionComponent(script = self, name = 'Session_Component_SETA', num_tracks = 1, num_scenes = 10, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._left_matrix)) self._left_set_session.set_group_track('SET A') self._left_set_session_zooming = SessionZoomingComponent(session = self._left_set_session) self._right_set_session = CrateSetSessionComponent(script = self, name = 'Session_Component_SETB', num_tracks = 1, num_scenes = 10, autonaming = True, is_enabled = False, layer = Layer(priority = 1, clip_launch_buttons = self._right_matrix)) self._right_set_session.set_group_track('SET B') self._right_set_session_zooming = SessionZoomingComponent(session = self._right_set_session) def _setup_next_buttons(self): self._next_a_button = FireNextClipComponent() self._next_a_button.set_track('SET A') self._next_a_button.layer = Layer(button = self._next_button[0]) self._next_b_button = FireNextClipComponent() self._next_b_button.set_track('SET B') self._next_b_button.layer = Layer(button = self._next_button[1]) def _setup_tempo(self): self._on_tempo_changed.subject = self.song() self._on_tempo_changed() @subject_slot('value') def _on_tempo_slider_value(self, value): self.song().tempo = ((value/127.)*979.)+20. @subject_slot('tempo') def _on_tempo_changed(self, *a, **k): debug('on tempo changed:', self.song().tempo) new_tempo = self.song().tempo #self._on_tempo_slider_value.subject and self._on_tempo_slider_value.subject.send_value(((new_tempo-20)/979)*127) self.send_tempo('Tempo '+str(new_tempo)) def _setup_modes(self): next_buttons = CompoundMode(self._next_a_button, self._next_a_button) self._main_modes = ModesComponent(name = 'MainModes') self._main_modes.add_mode('disabled', None) self._main_modes.add_mode('left_session', [self._left_session, next_buttons]) self._main_modes.add_mode('right_session', [self._right_session, next_buttons]) self._main_modes.add_mode('set_session', [self._left_set_session, self._right_set_session, next_buttons]) self._main_modes.layer = Layer(priority = 6, left_session_button = self._crate_button[0], right_session_button = self._crate_button[1], set_session_button = self._crate_button[2]) self._main_modes.selected_mode = 'set_session' self._main_modes.set_enabled(True) #self._next_a_button.set_enabled(True) #self._next_b_button.set_enabled(True) def _create_fallback_control_owner(self): self.register_disconnectable(SimpleLayerOwner(layer=Layer(_matrix=self._matrix, priority=0))) def update_display(self): super(Crate, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if(self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) @subject_slot('appointed_device') def _on_device_changed(self): debug('appointed device changed, script') def generate_strip_string(self, 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 += ' ' ret = ret.replace(' ', '_') assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return ret def notification_to_bridge(self, name, value, sender): if(isinstance(sender, (MonoEncoderElement, CodecEncoderElement))): pn = str(self.generate_strip_string(name)) pv = str(self.generate_strip_string(value)) self._monobridge._send(sender.name, 'lcd_name', pn) self._monobridge._send(sender.name, 'lcd_value', pv) 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 handle_sysex(self, midi_bytes): pass def disconnect(self): self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) + " log closed >>>>>>>>>>>>>>>>>>>>>>>>>") super(Crate, self).disconnect() def handle_sysex(self, midi_bytes): #debug('sysex: ', str(midi_bytes)) pass def clip_name(self, sender, name): offset = self._button.index(sender) shortname = encode_name_to_sysex(name) display_sysex = (240, 0, 0, 102, 1, offset) + tuple(shortname) + (247,) self._do_send_midi(display_sysex) def track_name(self, offset, name): shortname = encode_name_to_sysex(name) display_sysex = (240, 0, 0, 102, 2, offset) + tuple(shortname) + (247,) self._do_send_midi(display_sysex) def send_tempo(self, tempo): shortname = encode_name_to_sysex(tempo) display_sysex = (240, 0, 0, 102, 3,) + tuple(shortname) + (247,) self._do_send_midi(display_sysex) # a
class Roland_A_PRO(ControlSurface): def __init__(self, *a, **k): super(Roland_A_PRO, self).__init__(*a, **k) with self.component_guard(): self._create_controls() self._create_transport() self._create_mixer() self._create_device() self._create_drums() self._create_modes() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[[ EncoderElement(MIDI_CC_TYPE, 0, identifier, Live.MidiMap.MapMode.absolute, name=b'Encoder_%d' % index) for index, identifier in enumerate(ENCODER_IDS) ]]) self._master_encoder = EncoderElement(MIDI_CC_TYPE, 0, 10, Live.MidiMap.MapMode.absolute, name=b'Master_Encoder') self._sliders = ButtonMatrixElement(rows=[[ SliderElement( MIDI_CC_TYPE, 0, identifier, name=b'Slider_%d' % index) for index, identifier in enumerate(SLIDER_IDS) ]]) self._master_slider = SliderElement(MIDI_CC_TYPE, 0, 7, name=b'Master_Slider') self._play_button = ButtonElement(True, MIDI_CC_TYPE, 0, 26) self._stop_button = ButtonElement(True, MIDI_CC_TYPE, 0, 25) self._record_button = ButtonElement(True, MIDI_CC_TYPE, 0, 28) self._forward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 24) self._backward_button = ButtonElement(True, MIDI_CC_TYPE, 0, 21) self._ff_button = ButtonElement(True, MIDI_CC_TYPE, 0, 23) self._rw_button = ButtonElement(True, MIDI_CC_TYPE, 0, 22) self._device_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 80) self._pan_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 81) self._send_a_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 82) self._send_b_mode_button = ButtonElement(True, MIDI_CC_TYPE, 0, 83) self._pads = ButtonMatrixElement(rows=[[ ButtonElement(True, MIDI_NOTE_TYPE, 0, identifier) for identifier in row ] for row in PAD_ROWS]) def _create_transport(self): self._transport = TransportComponent( name=b'Transport', is_enabled=False, layer=Layer(play_button=self._play_button, stop_button=self._stop_button, record_button=self._record_button)) self._transport.set_enabled(True) def _create_mixer(self): mixer_size = self._sliders.width() self._mixer = MixerComponent( mixer_size, name=b'Mixer', is_enabled=False, layer=Layer(volume_controls=self._sliders, prehear_volume_control=self._master_encoder)) self._mixer.master_strip().layer = Layer( volume_control=self._master_slider) self._mixer.set_enabled(True) def _create_device(self): self._device = DeviceComponent( device_selection_follows_track_selection=True) self._device_navigation = DeviceNavigationComponent() self._device.set_enabled(True) self._device_navigation.set_enabled(True) self.set_device_component(self._device) def _create_drums(self): self._drums = DrumRackComponent(name=b'Drum_Rack', is_enabled=False, layer=Layer(pads=self._pads)) self._drums.set_enabled(True) def _create_modes(self): self._encoder_modes = ModesComponent() device_layer_mode = LayerMode(self._device, Layer(parameter_controls=self._encoders)) device_navigation_layer_mode = LayerMode( self._device_navigation, Layer(device_nav_right_button=self._forward_button, device_nav_left_button=self._backward_button)) self._encoder_modes.add_mode( b'device_mode', [device_layer_mode, device_navigation_layer_mode]) self._encoder_modes.add_mode( b'pan_mode', AddLayerMode( self._mixer, Layer(pan_controls=self._encoders, bank_up_button=self._forward_button, bank_down_button=self._backward_button, track_up_button=self._ff_button, track_down_button=self._rw_button))) send_layer_mode = AddLayerMode( self._mixer, Layer(send_controls=self._encoders, bank_up_button=self._forward_button, bank_down_button=self._backward_button, track_up_button=self._ff_button, track_down_button=self._rw_button)) self._encoder_modes.add_mode( b'send_a_mode', [send_layer_mode, partial(self._set_send_index, 0)]) self._encoder_modes.add_mode( b'send_b_mode', [send_layer_mode, partial(self._set_send_index, 1)]) self._encoder_modes.layer = Layer( device_mode_button=self._device_mode_button, pan_mode_button=self._pan_mode_button, send_a_mode_button=self._send_a_mode_button, send_b_mode_button=self._send_b_mode_button) self._encoder_modes.selected_mode = b'device_mode' self._encoder_modes.set_enabled(True) def _set_send_index(self, index): self._mixer.send_index = index
class Crate(ControlSurface): __module__ = __name__ __doc__ = " Monomodular controller script for Crate " def __init__(self, *a, **k): super(Crate, self).__init__(*a, **k) self._host_name = 'Crate' self._version_check = '1.0' self._rgb = 0 self._timer = 0 self._touched = 0 self.flash_status = 1 with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_session() self._setup_next_buttons() self._setup_tempo() self._setup_modes() self._create_fallback_control_owner() self.schedule_message(1, self._open_log) self.schedule_message(3, self._initialize_surface) def _open_log(self): self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._version_check) + " log opened =>>>>>>>>>>>>>>>>>>>") self.show_message(str(self._host_name) + ' Control Surface Loaded') def _initialize_surface(self): debug('setting to main mode') #self._main_modes.selected_mod = 'Main' #self._session.set_enabled(True) def port_settings_changed(self): debug('port settings changed!') self._connected = False super(Crate, self).port_settings_changed() def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _with_shift(self, button): return ComboElement(button, modifiers=[self._shift_button]) def _setup_controls(self): self._button = [ CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index, name='Button_' + str(index), script=self) for index in range(20) ] self._track_button = [ CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index + 50, name='Button_' + str(index + 50), script=self) for index in range(6) ] self._next_button = [ CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index + 60, name='Button_' + str(index + 60), script=self) for index in range(2) ] self._crate_button = [ CrateButtonElement(True, MIDI_NOTE_TYPE, 0, index + 70, name='Button_' + str(index + 70), script=self) for index in range(3) ] #self._tempo_slider = EncoderElement(MIDI_CC_TYPE, 0, 0, Live.MidiMap.MapMode.absolute, name = 'Slider') self._matrix = ButtonMatrixElement(name='Matrix', rows=[[self._button[index]] for index in range(20)]) self._left_matrix = ButtonMatrixElement(name='Left_Matrix', rows=[[self._button[index]] for index in range(10)]) self._right_matrix = ButtonMatrixElement( name='Right_Matrix', rows=[[self._button[index + 10]] for index in range(10)]) self._track_select_matrix = ButtonMatrixElement( name='Track_Matrix', rows=[self._track_button]) def _setup_session(self): self._left_session = CrateSessionComponent( script=self, name='Session_Component_A', num_tracks=1, num_scenes=20, autonaming=True, is_enabled=False, layer=Layer(priority=1, clip_launch_buttons=self._matrix, track_nav_buttons=self._track_select_matrix)) self._left_session.set_group_track('DECK A') self._left_session_zooming = SessionZoomingComponent( session=self._left_session) self._right_session = CrateSessionComponent( script=self, name='Session_Component_B', num_tracks=1, num_scenes=20, autonaming=True, is_enabled=False, layer=Layer(priority=1, clip_launch_buttons=self._matrix, track_nav_buttons=self._track_select_matrix)) self._right_session.set_group_track('DECK B') self._right_session_zooming = SessionZoomingComponent( session=self._right_session) self._left_set_session = CrateSetSessionComponent( script=self, name='Session_Component_SETA', num_tracks=1, num_scenes=10, autonaming=True, is_enabled=False, layer=Layer(priority=1, clip_launch_buttons=self._left_matrix)) self._left_set_session.set_group_track('SET A') self._left_set_session_zooming = SessionZoomingComponent( session=self._left_set_session) self._right_set_session = CrateSetSessionComponent( script=self, name='Session_Component_SETB', num_tracks=1, num_scenes=10, autonaming=True, is_enabled=False, layer=Layer(priority=1, clip_launch_buttons=self._right_matrix)) self._right_set_session.set_group_track('SET B') self._right_set_session_zooming = SessionZoomingComponent( session=self._right_set_session) def _setup_next_buttons(self): self._next_a_button = FireNextClipComponent() self._next_a_button.set_track('SET A') self._next_a_button.layer = Layer(button=self._next_button[0]) self._next_b_button = FireNextClipComponent() self._next_b_button.set_track('SET B') self._next_b_button.layer = Layer(button=self._next_button[1]) def _setup_tempo(self): self._on_tempo_changed.subject = self.song() self._on_tempo_changed() @subject_slot('value') def _on_tempo_slider_value(self, value): self.song().tempo = ((value / 127.) * 979.) + 20. @subject_slot('tempo') def _on_tempo_changed(self, *a, **k): debug('on tempo changed:', self.song().tempo) new_tempo = self.song().tempo #self._on_tempo_slider_value.subject and self._on_tempo_slider_value.subject.send_value(((new_tempo-20)/979)*127) self.send_tempo('Tempo ' + str(new_tempo)) def _setup_modes(self): next_buttons = CompoundMode(self._next_a_button, self._next_a_button) self._main_modes = ModesComponent(name='MainModes') self._main_modes.add_mode('disabled', None) self._main_modes.add_mode('left_session', [self._left_session, next_buttons]) self._main_modes.add_mode('right_session', [self._right_session, next_buttons]) self._main_modes.add_mode( 'set_session', [self._left_set_session, self._right_set_session, next_buttons]) self._main_modes.layer = Layer( priority=6, left_session_button=self._crate_button[0], right_session_button=self._crate_button[1], set_session_button=self._crate_button[2]) self._main_modes.selected_mode = 'set_session' self._main_modes.set_enabled(True) #self._next_a_button.set_enabled(True) #self._next_b_button.set_enabled(True) def _create_fallback_control_owner(self): self.register_disconnectable( SimpleLayerOwner(layer=Layer(_matrix=self._matrix, priority=0))) def update_display(self): super(Crate, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if (self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer) @subject_slot('appointed_device') def _on_device_changed(self): debug('appointed device changed, script') def generate_strip_string(self, 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 += ' ' ret = ret.replace(' ', '_') assert (len(ret) == NUM_CHARS_PER_DISPLAY_STRIP) return ret def notification_to_bridge(self, name, value, sender): if (isinstance(sender, (MonoEncoderElement, CodecEncoderElement))): pn = str(self.generate_strip_string(name)) pv = str(self.generate_strip_string(value)) self._monobridge._send(sender.name, 'lcd_name', pn) self._monobridge._send(sender.name, 'lcd_value', pv) 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 handle_sysex(self, midi_bytes): pass def disconnect(self): self.log_message("<<<<<<<<<<<<<<<<<<<<<<<<< " + str(self._host_name) + " log closed >>>>>>>>>>>>>>>>>>>>>>>>>") super(Crate, self).disconnect() def handle_sysex(self, midi_bytes): #debug('sysex: ', str(midi_bytes)) pass def clip_name(self, sender, name): offset = self._button.index(sender) shortname = encode_name_to_sysex(name) display_sysex = (240, 0, 0, 102, 1, offset) + tuple(shortname) + (247, ) self._do_send_midi(display_sysex) def track_name(self, offset, name): shortname = encode_name_to_sysex(name) display_sysex = (240, 0, 0, 102, 2, offset) + tuple(shortname) + (247, ) self._do_send_midi(display_sysex) def send_tempo(self, tempo): shortname = encode_name_to_sysex(tempo) display_sysex = ( 240, 0, 0, 102, 3, ) + tuple(shortname) + (247, ) self._do_send_midi(display_sysex) # a
class Launchkey_MK2(OptimizedControlSurface): identity_request_delay = 0.5 def __init__(self, c_instance, *a, **k): super(Launchkey_MK2, self).__init__(c_instance=c_instance, *a, **k) self._is_25_key_model = False self._is_in_control_on = True self._identity_response_pending = False with self.component_guard(): self._skin = make_skin() with inject(skin=const(self._skin)).everywhere(): self._create_controls() self._request_task = self._tasks.add( Task.sequence(Task.wait(self.identity_request_delay), Task.run(self._send_identity_request))) self._request_task.kill() def _create_controls(self): self._encoders = ButtonMatrixElement(rows=[[ make_encoder(identifier, name=u'Encoder_%d' % (index, )) for index, identifier in enumerate(range(21, 29)) ]]) self._top_pad_row = ButtonMatrixElement(rows=[[ make_button(identifier, name=u'Pad_0_%d' % (index, )) for index, identifier in enumerate(range(96, 104)) ]]) self._bottom_pad_row_raw = [ make_button(identifier, name=u'Pad_1_%d' % (index, )) for index, identifier in enumerate(range(112, 120)) ] self._bottom_pad_row = ButtonMatrixElement( rows=[self._bottom_pad_row_raw]) self._top_launch_button = make_button(104, name=u'Scene_Launch_Button') self._bottom_launch_button = make_button(120, name=u'Stop_All_Clips_Button') self._scene_up_button = make_button(112, MIDI_CC_TYPE, name=u'Scene_Up_Button') self._scene_down_button = make_button(113, MIDI_CC_TYPE, name=u'Scene_Down_Button') self._stop_button = make_button(114, MIDI_CC_TYPE, name=u'Stop_Button') self._play_button = make_button(115, MIDI_CC_TYPE, name=u'Play_Button') self._loop_button = make_button(116, MIDI_CC_TYPE, name=u'Loop_Button') self._record_button = make_button(117, MIDI_CC_TYPE, name=u'Record_Button') self._sliders = ButtonMatrixElement(rows=[[ make_slider(identifier, name=u'Slider_%d' % (index, )) for index, identifier in enumerate(range(41, 49)) ]]) self._master_slider = make_slider(7, name=u'Master_Slider') self._25_key_slider = make_slider(7, name=u'Slider', channel=0) self._mute_buttons_raw = [ make_button(identifier, MIDI_CC_TYPE, name=u'Mute_Button_%d' % (index, )) for index, identifier in enumerate(range(51, 59)) ] self._mute_buttons = ButtonMatrixElement(rows=[self._mute_buttons_raw]) self._master_button = make_button(59, MIDI_CC_TYPE, name=u'Master_Button') self._track_left_button = make_button(102, MIDI_CC_TYPE, name=u'Track_Left_Button') self._track_right_button = make_button(103, MIDI_CC_TYPE, name=u'Track_Right_Button') self._device_mode_button = self._bottom_pad_row_raw[0] self._pan_mode_button = self._bottom_pad_row_raw[1] self._send_mode_buttons = dict() for index in range(consts.MAX_SENDS): setattr(self, u'_send_%d_button' % (index, ), self._bottom_pad_row_raw[index + 2]) self._send_mode_buttons[u'send_%d_mode_button' % (index, )] = getattr( self, u'_send_%d_button' % (index, )) self._extended_mode_button = make_button( 12, name=u'Dummy_Extended_Mode_Button') self._extended_mode_button.add_value_listener(nop) self._encoder_incontrol_button = make_button( 13, is_momentary=False, name=u'Encoder_InControl_Button') self._encoder_incontrol_button.add_value_listener(nop) self._slider_incontrol_button = make_button( 14, is_momentary=False, name=u'Fader_InControl_Button') self._slider_incontrol_button.add_value_listener(nop) self._pad_incontrol_button = make_button(15, is_momentary=False, name=u'Pad_InControl_Button') self._pad_incontrol_button.add_value_listener(self._update_pads) self._encoder_incontrol_button2 = make_button( 16, name=u'Encoder_InControl_Button') self._pad_in_control_status_button = make_button( 11, name=u'Dummy_InControl_Button') def _create_session(self): self._session = SessionComponent( name=u'Session', is_enabled=False, num_tracks=self._top_pad_row.width(), num_scenes=self._top_pad_row.height(), enable_skinning=True, layer=Layer(clip_launch_buttons=self._top_pad_row, scene_launch_buttons=ButtonMatrixElement( rows=[[self._top_launch_button]]), stop_track_clip_buttons=self._bottom_pad_row, stop_all_clips_button=self._bottom_launch_button)) self._session.set_rgb_mode(LIVE_COLORS_TO_MIDI_VALUES, RGB_COLOR_TABLE) self._session.set_mixer(self._mixer) self._session.set_enabled(True) def _setup_navigation(self): self._session_navigation = SessionNavigationComponent( is_enabled=False, name=u'Session_Navigation', layer=Layer(next_track_button=self._track_right_button, prev_track_button=self._track_left_button, next_scene_button=self._scene_down_button, prev_scene_button=self._scene_up_button)) self._session_navigation.set_enabled(True) def _create_transport(self): self._transport = TransportComponent( is_enabled=False, name=u'Transport', layer=Layer(play_button=self._play_button, stop_button=self._stop_button, loop_button=self._loop_button, record_button=self._record_button)) self._transport.set_enabled(True) def _create_mixer(self): mixer_volume_layer = None if self._is_25_key_model: mixer_volume_layer = Layer(volume_control=self._25_key_slider) else: mixer_volume_layer = Layer(volume_controls=self._sliders) self._mixer = MixerComponent(is_enabled=False, name=u'Mixer', num_tracks=self._sliders.width(), layer=mixer_volume_layer) if not self._is_25_key_model: self._mixer.master_strip().layer = Layer( volume_control=self._master_slider) self._mixer.set_enabled(True) self._mute_button_modes = ModesComponent() mute_mode = AddLayerMode(self._mixer, Layer(mute_buttons=self._mute_buttons)) solo_mode = AddLayerMode(self._mixer, Layer(solo_buttons=self._mute_buttons)) self._mute_button_modes.add_mode(u'mute_mode', mute_mode) self._mute_button_modes.add_mode(u'solo_mode', solo_mode, behaviour=CancellableBehaviour()) self._mute_button_modes.layer = Layer( solo_mode_button=self._master_button) self._mute_button_modes.selected_mode = u'mute_mode' self._mute_button_modes.set_enabled(True) def _create_device(self): self._device = DeviceComponent( name=u'Device', is_enabled=False, device_selection_follows_track_selection=True) self.set_device_component(self._device) self._device.set_enabled(True) def _create_background(self): self._background = BackgroundComponent(name=u'BackgroundComponent') def _create_encoder_modes(self): self._encoder_modes = DisablingModesComponent() self._encoder_modes.default_behaviour = mixin(SkinableBehaviourMixin, ImmediateBehaviour)() device_mode = LayerMode( self._device, Layer(parameter_controls=self._encoders, bank_buttons=self._top_pad_row)) pan_mode = AddLayerMode(self._mixer, Layer(pan_controls=self._encoders)) sends_mode = AddLayerMode(self._mixer, Layer(send_controls=self._encoders)) background_mode = LayerMode(self._background, Layer(bank_buttons=self._top_pad_row)) self._encoder_modes.add_mode(u'device_mode', device_mode, is_enabled=True) self._encoder_modes.add_mode(u'pan_mode', [pan_mode, background_mode], is_enabled=True) for index in range(6): self._encoder_modes.add_mode(u'send_%d_mode' % (index, ), [ sends_mode, partial(self._set_send_index, index), background_mode ], is_enabled=False) self._encoder_modes.selected_mode = u'device_mode' self._encoder_modes.set_enabled(True) def _create_mode_selector(self): self._mode_selector = ModesComponent() mode_selection = LayerMode( self._encoder_modes, Layer(device_mode_button=self._device_mode_button, pan_mode_button=self._pan_mode_button, **self._send_mode_buttons)) device_navigation = AddLayerMode( self._device, Layer(device_nav_left_button=self._track_left_button, device_nav_right_button=self._track_right_button)) self._mode_selector.add_mode(u'mode_selection', [ partial(self._toggle_in_control, True), mode_selection, device_navigation ], behaviour=MomentaryBehaviour()) session_control = AddLayerMode( self._session, Layer(clip_launch_buttons=self._top_pad_row)) self._mode_selector.add_mode( u'session_mode', [partial(self._toggle_in_control, False), session_control]) self._mode_selector.layer = Layer( mode_selection_button=self._encoder_incontrol_button2) def _create_in_control_status_listener(self): self._in_control_status = InControlStatusComponent( set_is_in_control_on=self._set_is_in_control_on, is_enabled=False, layer=Layer( in_control_status_button=self._pad_in_control_status_button)) self._in_control_status.set_enabled(True) @subject_slot(u'value') def _update_pads(self, value): if value: self.update() @subject_slot(u'return_tracks') def _on_return_tracks_changed(self): num_sends = self._mixer.num_sends for index in range(6): self._encoder_modes.set_mode_enabled( u'send_%d_mode' % (index, ), True if index < num_sends else False) def _set_send_index(self, index): self._mixer.send_index = index def _set_is_in_control_on(self, value): self._is_in_control_on = value def _toggle_in_control(self, value): if not self._is_in_control_on: self._send_midi(consts.DRUM_IN_CONTROL_ON_MESSAGE if value else consts.DRUM_IN_CONTROL_OFF_MESSAGE) def port_settings_changed(self): self._disconnect_and_unregister_all_components() self._request_task.restart() def handle_sysex(self, midi_bytes): if self._is_identity_response(midi_bytes): product_id_bytes = self._extract_product_id_bytes(midi_bytes) if self._is_identity_response_valid(product_id_bytes): self._set_model_type(product_id_bytes) self._request_task.kill() if self._identity_response_pending: self.on_identified() self._identity_response_pending = False else: self.log_message( u'MIDI device responded with wrong product id (%s).' % (str(product_id_bytes), )) else: super(Launchkey_MK2, self).handle_sysex(midi_bytes) def _extract_product_id_bytes(self, midi_bytes): return midi_bytes[5:] def _is_identity_response(self, midi_bytes): return midi_bytes[3:5] == (6, 2) def _is_identity_response_valid(self, product_id_bytes): return product_id_bytes[: 3] == consts.PRODUCT_ID_BYTE_PREFIX and product_id_bytes[ 3] in consts.PRODUCT_ID_BYTES def _set_model_type(self, product_id_bytes): self._is_25_key_model = product_id_bytes[ 3] == consts.LAUNCHKEY_25_ID_BYTE def _send_identity_request(self): self._identity_response_pending = True self._send_midi(consts.IDENTITY_REQUEST) def on_identified(self): self._extended_mode_button.turn_on() with self.component_guard(): self._create_mixer() self._create_session() self._setup_navigation() self._create_transport() self._create_device() self._create_background() self._create_encoder_modes() self._create_mode_selector() self._create_in_control_status_listener() self._on_return_tracks_changed.subject = self.song() self._on_return_tracks_changed() self._mode_selector.selected_mode = u'session_mode' self.update() def disconnect(self): self._extended_mode_button.turn_off() super(Launchkey_MK2, self).disconnect()
class MonoPedal(ControlSurface): def __init__(self, *a, **k): super(MonoPedal, self).__init__(*a, **k) self._monomod_version = 'b995' self._codec_version = 'b996' self._cntrlr_version = 'b996' self._cntrlr = None self._host_name = 'MonoPedal' self._color_type = 'OhmRGB' self.hosts = [] self._timer = 0 self.flash_status = 1 self._touched = 0 self._last_main_mode = 'looper' with self.component_guard(): self._setup_monobridge() self._setup_controls() self._setup_looper() self._setup_launcher() self._setup_device_control() self._setup_modes() self.schedule_message(1, self._open_log) #self._loop_selector.set_enabled(True) """script initialization methods""" def _open_log(self): self.log_message("<<<<<<<<<<<<<<<<<<<<= " + str(self._host_name) + " " + str(self._monomod_version) + " log opened =>>>>>>>>>>>>>>>>>>>") self.show_message(str(self._host_name) + ' Control Surface Loaded') def _setup_monobridge(self): self._monobridge = MonoBridgeElement(self) self._monobridge.name = 'MonoBridge' def _setup_controls(self): self._pedal = [None for index in range(8)] for index in range(7): self._pedal[index] = DoublePressElement( MonoButtonElement(True, MIDI_CC_TYPE, 0, PEDAL_DEFS[index], 'Pedal_' + str(index), self)) #is_momentary, MIDI_NOTE_TYPE, CHANNEL, LIVID, 'Livid_Button', self self._pedal[index].name = 'Pedal_' + str(index) self._pedal[index]._report = False self._pedal[7] = LoopPedalExpressionElement( self, MIDI_CC_TYPE, 0, 1, Live.MidiMap.MapMode.absolute) self._pedal[7].name = 'Pedal_' + str(7) self._pedal[7]._report = False self._leds = [None for index in range(4)] for index in range(4): red_led = ButtonElement(True, MIDI_NOTE_TYPE, 0, LED_DEFS[index]) green_led = ButtonElement(True, MIDI_NOTE_TYPE, 0, LED_DEFS[index] + 4) blue_led = ButtonElement(True, MIDI_NOTE_TYPE, 0, LED_DEFS[index] + 8) self._leds[index] = RGB_LED(red_led, green_led, blue_led, True, MIDI_NOTE_TYPE, 0, index + 13, 'LED_' + str(index), self) self._select_buttons = ButtonMatrixElement() self._select_buttons.name = 'SelectMatrix' self._select_buttons.add_row( [self._pedal[6], self._pedal[5], self._pedal[4], self._pedal[3]]) self._doublepress_select_buttons = ButtonMatrixElement() self._doublepress_select_buttons.name = 'DoublepressSelectMatrix' self._doublepress_select_buttons.add_row([ self._pedal[6].double_press, self._pedal[5].double_press, self._pedal[4].double_press, self._pedal[3].double_press ]) self._record_button = self._pedal[1] self._mute_button = self._pedal[2] self._overdub_button = self._pedal[0] def _setup_looper(self): self._looper = MonolooperComponent(self._leds, self) self._looper.layer = Layer( select_buttons=self._select_buttons, doublepress_select_buttons=self._doublepress_select_buttons, overdub_button=self._pedal[2], record_button=self._pedal[1], mute_button=self._pedal[0], expression_pedal=self._pedal[7], ) def _setup_launcher(self): self._launcher = LauncherComponent(self._leds, self) self._launcher.set_enabled(False) self._launcher.layer = Layer( select_buttons=self._select_buttons, doublepress_select_buttons=self._doublepress_select_buttons, fire1_button=self._pedal[2], fire2_button=self._pedal[1], fire3_button=self._pedal[0], expression_pedal=self._pedal[7]) def _setup_device_control(self): self._device_control = DeviceControlComponent(self._leds, self) self._device_control.set_enabled(False) self._device_control.layer = Layer( select_buttons=self._select_buttons, doublepress_select_buttons=self._doublepress_select_buttons, toggle1_button=self._pedal[2], toggle2_button=self._pedal[1], toggle3_button=self._pedal[0], expression_pedal=self._pedal[7]) def _setup_modes(self): self._button_modes = ModesComponent(name='Button_Modes') self._button_modes.add_mode('launcher', self._launcher) self._button_modes.add_mode('looper', self._looper) self._button_modes.add_mode('device', self._device_control) self._button_modes.selected_mode = 'looper' self._button_modes.set_enabled(True) def receive_led(self, button, value): #self.log_message('receive led: ' + str(index) + ' ' + str(value)) pass def toggle_mode(self): self._button_modes.selected_mode = 'launcher' if self._button_modes.selected_mode is 'looper' else 'looper' self._last_main_mode = self._button_modes.selected_mode #self.log_message('toggle mode to: ' + str(self._button_modes.selected_mode)) def toggle_device_control(self, x): self._button_modes.selected_mode = 'device' if not self._button_modes.selected_mode is 'device' else self._last_main_mode if self._button_modes.selected_mode is 'device': self._device_control.set_bank(x) """called on timer""" def update_display(self): super(MonoPedal, self).update_display() self._timer = (self._timer + 1) % 256 self.flash() def flash(self): if (self.flash_status > 0): for control in self.controls: if isinstance(control, MonoButtonElement): control.flash(self._timer)
class PHAZE(APC40_MkII): """ APC40Mk2 script with step sequencer mode """ def __init__(self, *a, **k): self._double_press_context = DoublePressContext() APC40_MkII.__init__(self, *a, **k) with self.component_guard(): self._skin = make_default_skin() # self._create_session() self._clip_creator = ClipCreator() self._init_background() self._init_step_sequencer() self._init_drum_component() self._init_instrument() self._init_note_repeat() self._init_matrix_modes() self._create_device() # self._create_view_control() self._on_selected_track_changed() self.set_pad_translations(PAD_TRANSLATIONS) self.set_feedback_channels(FEEDBACK_CHANNELS) def _create_controls(self): """ Add some additional stuff baby """ super(PHAZE, self)._create_controls() self._grid_resolution = GridResolution() self._velocity_slider = ButtonSliderElement(tuple(self._scene_launch_buttons_raw[::-1])) double_press_rows = recursive_map(DoublePressElement, self._matrix_rows_raw) self._double_press_matrix = ButtonMatrixElement(name='Double_Press_Matrix', rows=double_press_rows) self._double_press_event_matrix = ButtonMatrixElement(name='Double_Press_Event_Matrix', rows=recursive_map(lambda x: x.double_press, double_press_rows)) self._playhead = PlayheadElement(self._c_instance.playhead) # Make these prioritized resources, which share between Layers() equally # Rather than building a stack """not sure but we greened out below on 05/11/17.. maybe work on order of definitions so as to tidy up some""" self._pan_button._resource_type = PrioritizedResource self._user_button._resource_type = PrioritizedResource # self._view_control = ViewControlComponent(name='View_Control') # self._view_control.set_enabled(False) # def _create_session(self): # def when_bank_on(button): # return self._bank_toggle.create_toggle_element(on_control=button) # def when_bank_off(button): # return self._bank_toggle.create_toggle_element(off_control=button) # self._session = SessionComponent(NUM_TRACKS, NUM_SCENES, # auto_name=True, is_enabled=False, enable_skinning=True, # layer=Layer(track_bank_left_button=when_bank_off(self._left_button), # track_bank_right_button=when_bank_off(self._right_button), # scene_bank_up_button=when_bank_off(self._up_button), # scene_bank_down_button=when_bank_off(self._down_button), # page_left_button=when_bank_on(self._left_button), # page_right_button=when_bank_on(self._right_button), # page_up_button=when_bank_on(self._up_button), # page_down_button=when_bank_on(self._down_button), # stop_track_clip_buttons=self._stop_buttons, # stop_all_clips_button=self._stop_all_button, # scene_launch_buttons=self._scene_launch_buttons, # clip_launch_buttons=self._session_matrix)) # clip_color_table = colors.CLIP_COLOR_TABLE.copy() # clip_color_table[16777215] = 119 # self._session.set_rgb_mode(clip_color_table, colors.RGB_COLOR_TABLE) # self._session_zoom = SessionZoomingComponent(self._session, name=u'Session_Overview', enable_skinning=True, is_enabled=False, layer=Layer(button_matrix=self._shifted_matrix, nav_left_button=self._with_shift(self._left_button), nav_right_button=self._with_shift(self._right_button), nav_up_button=self._with_shift(self._up_button), nav_down_button=self._with_shift(self._down_button), scene_bank_buttons=self._shifted_scene_buttons)) # def _init_session(self): # self._session_mode = LazyEnablingMode(self._create_session) def _create_device(self): self._device = DeviceComponent(name=u'Device', is_enabled=False, layer=Layer(parameter_controls=self._device_controls, bank_buttons=self._device_bank_buttons, bank_prev_button=self._device_prev_bank_button, bank_next_button=self._device_next_bank_button, on_off_button=self._device_on_off_button, lock_button=self._device_lock_button), device_selection_follows_track_selection=True) def _create_view_control(self): self._view_control = DetailViewCntrlComponent(name=u'View_Control', is_enabled=False, layer=Layer(device_nav_left_button=self._prev_device_button, device_nav_right_button=self._next_device_button, device_clip_toggle_button=self._clip_device_button, detail_toggle_button=self._detail_view_button)) self._view_control.device_clip_toggle_button.pressed_color = u'DefaultButton.On' def _init_background(self): self._background = BackgroundComponent(is_root=True) self._background.layer = Layer(velocity_slider = self._velocity_slider, stop_buttons = self._stop_buttons)#, display_line2=self._display_line2, display_line3=self._display_line3, display_line4=self._display_line4, top_buttons=self._select_buttons, bottom_buttons=self._track_state_buttons, scales_button=self._scale_presets_button, octave_up=self._octave_up_button, octave_down=self._octave_down_button, side_buttons=self._side_buttons, repeat_button=self._repeat_button, accent_button=self._accent_button, double_button=self._double_button, in_button=self._in_button, out_button=self._out_button, param_controls=self._global_param_controls, param_touch=self._global_param_touch_buttons, tempo_control_tap=self._tempo_control_tap, master_control_tap=self._master_volume_control_tap, touch_strip=self._touch_strip_control, touch_strip_tap=self._touch_strip_tap, nav_up_button=self._nav_up_button, nav_down_button=self._nav_down_button, nav_left_button=self._nav_left_button, nav_right_button=self._nav_right_button, aftertouch=self._aftertouch_control, pad_parameters=self._pad_parameter_control, _notification=self._notification.use_single_line(2), priority=consts.BACKGROUND_PRIORITY) self._matrix_background = BackgroundComponent() self._matrix_background.set_enabled(False) self._matrix_background.layer = Layer(matrix=self._session_matrix) # self._mod_background = ModifierBackgroundComponent(is_root=True) # self._mod_background.layer = Layer(shift_button=self._shift_button, velocity_slider = self._velocity_slider, stop_buttons = self._stop_buttons) def _init_step_sequencer(self): self._step_sequencer = StepSeqComponent(grid_resolution = self._grid_resolution) self._step_sequencer.layer = self._create_step_sequencer_layer() """added sunday PM 05/11/17""" def _init_note_repeat(self): self._note_repeat = NoteRepeatComponent(name='Note_Repeat') self._note_repeat.set_enabled(False) self._note_repeat.set_note_repeat(self._c_instance.note_repeat) self._note_repeat.layer = Layer( # aftertouch_control=self._aftertouch_control, select_buttons=self._stop_buttons, # pad_parameters=self._pad_parameter_control ) self._note_repeat.layer.priority = consts.DIALOG_PRIORITY self._note_repeat_enabler = EnablingModesComponent(name='Note_Repeat_Enabler', component=self._note_repeat, toggle_value='DefaultButton.Alert', disabled_value='DefaultButton.On') self._note_repeat_enabler.set_enabled(False) self._note_repeat_enabler.layer = Layer(toggle_button=self._bank_button) """added sunday PM 15:25 22/10/17""" def _init_drum_component(self): self._drum_component = DrumGroupComponent(name='Drum_Group', is_enabled=False) self._drum_component.layer = Layer( drum_matrix=self._session_matrix, # page_strip=self._touch_strip_control, # scroll_strip=self._with_shift(self._touch_strip_control), # solo_button=self._global_solo_button, select_button=self._metronome_button, # delete_button=self._delete_button, scroll_page_up_button=self._up_button, scroll_page_down_button=self._down_button, # quantize_button=self._quantize_button, # mute_button=self._global_mute_button, scroll_up_button=self._with_shift(self._up_button), scroll_down_button=self._with_shift(self._down_button)) # self._drum_component.select_drum_pad = self._selector.on_select_drum_pad # self._drum_component.quantize_pitch = self._quantize.quantize_pitch """lew sunday""" def _init_instrument(self): instrument_basic_layer = Layer( #octave_strip=self._with_shift(self._touch_strip_control), # scales_toggle_button=self._tap_tempo_button, # capture_button = self._tap_tempo_button, octave_up_button=self._up_button, octave_down_button=self._down_button, scale_up_button=self._with_shift(self._up_button), scale_down_button=self._with_shift(self._down_button)) self._instrument = MelodicComponent(skin=self._skin, is_enabled=False, clip_creator=self._clip_creator, name='Melodic_Component', grid_resolution=self._grid_resolution, #note_editor_settings=self._add_note_editor_setting(), layer=self._create_instrument_layer(), instrument_play_layer=instrument_basic_layer + Layer(matrix=self._session_matrix), #touch_strip=self._touch_strip_control, touch_strip_indication=self._with_firmware_version(1, 16, ComboElement(self._touch_strip_control, modifiers=[self._select_button])), #touch_strip_toggle=self._with_firmware_version(1, 16, ComboElement(self._touch_strip_tap, modifiers=[self._select_button])), #aftertouch_control=self._aftertouch_control, delete_button=self._delete_button), instrument_sequence_layer=instrument_basic_layer)# + Layer(note_strip=self._touch_strip_control)) self._on_note_editor_layout_changed.subject = self._instrument def _init_matrix_modes(self): """ Switch between Session and StepSequencer modes """ """here we go trying to switch.... lew 05:53 21/10/17""" self._auto_arm = AutoArmComponent(name='Auto_Arm') self._drum_group_finder = DrumGroupFinderComponent() self._on_drum_group_changed.subject = self._drum_group_finder self._drum_modes = ModesComponent(name='Drum_Modes', is_enabled=False) self._drum_modes.add_mode('sequencer', self._step_sequencer) self._drum_modes.add_mode('64pads', self._drum_component) # added 15:18 subday 22/10/17 can maybe look into this. causes issues when trying to scroll.(drumcomp1) self._drum_modes.selected_mode = 'sequencer' self._note_modes = ModesComponent(name='Note_Modes')#, is_enabled=False) self._note_modes.add_mode('drums', [self._note_repeat_enabler, self._drum_modes]) self._drum_modes.selected_mode = 'sequencer' self._note_modes.add_mode('looper', self._audio_loop if consts.PROTO_AUDIO_NOTE_MODE else self._matrix_background) self._note_modes.add_mode('instrument', [self._note_repeat_enabler, self._instrument]) self._note_modes.add_mode('disabled', self._matrix_background) self._note_modes.selected_mode = 'disabled' self._note_modes.set_enabled(False) def switch_note_mode_layout(): self._matrix_modes.selected_mode = 'note' if self._note_modes.selected_mode == 'instrument': getattr(self._instrument, 'cycle_mode', nop)() elif self._note_modes.selected_mode == 'drums': getattr(self._drum_modes, 'cycle_mode', nop)() self._matrix_modes = ModesComponent(name='Matrix_Modes', is_root=True) self._matrix_modes.add_mode('session', self._session_mode_layers()) self._matrix_modes.add_mode('note', [self._drum_group_finder, self._view_control, self._note_modes],behaviour=self._auto_arm.auto_arm_restore_behaviour(ReenterBehaviour, on_reenter=switch_note_mode_layout)) self._matrix_modes.selected_mode = 'note' self._matrix_modes.layer = Layer(session_button=self._pan_button, note_button=self._user_button) self._on_matrix_mode_changed.subject = self._matrix_modes self._matrix_modes.selected_mode = 'note' #added for looping capability #self._looper = LooperComponent(self) #self._looper.name = 'looper_Component' def _session_mode_layers(self): return [ self._session, self._session_zoom] def _create_step_sequencer_layer(self): return Layer( velocity_slider = self._velocity_slider, drum_matrix = self._session_matrix.submatrix[:4, 1:5], # [4, 1:5], mess with this for possible future 32 pad drum rack : button_matrix = self._double_press_matrix.submatrix[4:8, 1:5], # [4:8, 1:5], # next_page_button = self._bank_button, select_button = self._user_button, delete_button = self._stop_all_button, playhead = self._playhead, quantization_buttons = self._stop_buttons, shift_button = self._shift_button, loop_selector_matrix = self._double_press_matrix.submatrix[:4, :1], # changed from [:8, :1] so as to enable bottem row of rack . second value clip length rows short_loop_selector_matrix = self._double_press_event_matrix.submatrix[:4, :1], # changed from [:8, :1] no change noticed as of yet drum_bank_up_button = self._up_button, drum_bank_down_button = self._down_button) # capture_button = self._tap_tempo_button) """lew sunday""" def _create_instrument_layer(self): return Layer( playhead=self._playhead, #mute_button=self._global_mute_button, quantization_buttons=self._stop_buttons, loop_selector_matrix=self._double_press_matrix.submatrix[:8, :1],# [:, 0] short_loop_selector_matrix=self._double_press_event_matrix.submatrix[:, 0],# [:, 0] note_editor_matrices=ButtonMatrixElement([[ self._session_matrix.submatrix[:, 4 - row] for row in xrange(7) ]])) #note_editor_matrices=ButtonMatrixElement([[ self._session_matrix.submatrix[:, 7 - row] for row in xrange(7) ]])) def _session_layer(self): def when_bank_on(button): return self._bank_toggle.create_toggle_element(on_control=button) def when_bank_off(button): return self._bank_toggle.create_toggle_element(off_control=button) return Layer( track_bank_left_button = when_bank_off(self._left_button), track_bank_right_button = when_bank_off(self._right_button), scene_bank_up_button = when_bank_off(self._up_button), scene_bank_down_button = when_bank_off(self._down_button), page_left_button = when_bank_on(self._left_button), page_right_button = when_bank_on(self._right_button), page_up_button = when_bank_on(self._up_button), page_down_button = when_bank_on(self._down_button), # stop_track_clip_buttons = self._stop_buttons, stop_all_clips_button = self._stop_all_button, scene_launch_buttons = self._scene_launch_buttons, clip_launch_buttons = self._session_matrix) def _session_zoom_layer(self): return Layer(button_matrix=self._shifted_matrix, nav_left_button=self._with_shift(self._left_button), nav_right_button=self._with_shift(self._right_button), nav_up_button=self._with_shift(self._up_button), nav_down_button=self._with_shift(self._down_button), scene_bank_buttons=self._shifted_scene_buttons) @subject_slot('selected_mode') def _on_matrix_mode_changed(self, mode): self._update_auto_arm(selected_mode=mode) def _update_auto_arm(self, selected_mode = None): self._auto_arm.set_enabled(selected_mode or self._matrix_modes.selected_mode == 'note') @subject_slot('drum_group') def _on_drum_group_changed(self): self._select_note_mode() def _select_note_mode(self): """ Selects which note mode to use depending on the kind of current selected track and its device chain... """ track = self.song().view.selected_track drum_device = self._drum_group_finder.drum_group self._step_sequencer.set_drum_group_device(drum_device) self._drum_component.set_drum_group_device(drum_device) if track == None or track.is_foldable or track in self.song().return_tracks or track == self.song().master_track or track.is_frozen: self._note_modes.selected_mode = 'disabled' elif track and track.has_audio_input: self._note_modes.selected_mode = 'looper' elif drum_device: self._note_modes.selected_mode = 'drums' else: self._note_modes.selected_mode = 'instrument' self.reset_controlled_track() # added so as to have looping with pan_button held # self._select_modes = SelectComponent(self, tuple(self._raw_select_buttons), self._metronome_button, self._nudge_down_button, self._nudge_up_button, self._tap_tempo_button, self._transport, self._looper, self._session, self._session_matrix) # self._select_modes.name = 'Select_Modes' # self._select_modes.set_mode_toggle(self._pan_button) # commented to test 0:47 # EVENT HANDLING FUNCTIONS # def reset_controlled_track(self): # self.set_controlled_track(self.song().view.selected_track) """lew sunday""" @subject_slot('selected_mode') def _on_note_editor_layout_changed(self, mode): self.reset_controlled_track(mode) def reset_controlled_track(self, mode = None): if mode == None: mode = self._instrument.selected_mode if self._instrument.is_enabled() and mode == 'sequence': self.release_controlled_track() else: self.set_controlled_track(self.song().view.selected_track) def update(self): self.reset_controlled_track() self.set_feedback_channels(FEEDBACK_CHANNELS) # push added line super(PHAZE, self).update() def _on_selected_track_changed(self): super(PHAZE, self)._on_selected_track_changed() self.reset_controlled_track() self._select_note_mode() # self._main_modes.pop_groups(['add_effect']) self._note_repeat_enabler.selected_mode = 'disabled' @contextmanager def component_guard(self): """ Customized to inject additional things """ with super(PHAZE, self).component_guard(): with self.make_injector().everywhere(): yield def make_injector(self): """ Adds some additional stuff to the injector, used in BaseMessenger """ return inject( double_press_context = const(self._double_press_context), control_surface = const(self), log_message = const(self.log_message))