class ATOMSQ(ControlSurface): def __init__(self, *a, **k): super(ATOMSQ, self).__init__(*a, **k) with self.component_guard(): self._elements = Elements() with inject(element_container=const(self._elements)).everywhere(): self._create_background() self._create_transport() self._create_undo() self._create_view_toggle() self._create_device_parameters() self._create_translating_background() self._create_device_navigation() self._create_launch_and_stop() self._create_session() self._create_mixer() self._create_view_control() self._create_button_labels() self._create_record_modes() self._create_lower_pad_modes() self._create_main_modes() self.__on_main_view_changed.subject = self.application.view def disconnect(self): super(ATOMSQ, self).disconnect() self._send_midi(midi.NATIVE_MODE_OFF_MESSAGE) def port_settings_changed(self): self._send_midi(midi.NATIVE_MODE_ON_MESSAGE) if self._main_modes.selected_mode == b'instrument': self.schedule_message( 1, self._elements.upper_firmware_toggle_switch.send_value, 1) if self._main_modes.selected_mode != b'song': self.schedule_message( 1, self._elements.lower_firmware_toggle_switch.send_value, 1) super(ATOMSQ, self).port_settings_changed() def _create_background(self): self._background = BackgroundComponent( name=b'Background', is_enabled=False, add_nop_listeners=True, layer=Layer(**{name: name for name in BANK_BUTTON_NAMES})) self._background.set_enabled(True) def _create_transport(self): self._transport = TransportComponent( name=b'Transport', is_enabled=False, layer=Layer(scroll_encoder=b'display_encoder', play_button=b'play_button', loop_button=b'play_button_with_shift', stop_button=b'stop_button', metronome_button=b'click_button', capture_midi_button=b'record_button_with_shift', prev_cue_button=b'display_left_button', next_cue_button=b'display_right_button', shift_button=b'shift_button')) self._transport.set_enabled(True) def _create_undo(self): self._undo = UndoRedoComponent( name=b'Undo', is_enabled=False, layer=Layer(undo_button=b'stop_button_with_shift')) self._undo.set_enabled(True) def _create_view_toggle(self): self._view_toggle = ViewToggleComponent( name=b'View_Toggle', is_enabled=False, layer=Layer(main_view_toggle_button=b'bank_a_button', browser_view_toggle_button=b'bank_b_button', detail_view_toggle_button=b'bank_d_button', clip_view_toggle_button=b'bank_h_button')) def _create_device_parameters(self): self._device_parameters = SimpleDeviceParameterComponent( name=b'Device_Parameters', device_bank_registry=self._device_bank_registry, toggle_lock=self.toggle_lock, layer=Layer(device_name_display=b'device_name_display'), is_enabled=False) self._device_parameters.set_enabled(True) def _create_translating_background(self): self._translating_background = TranslatingBackgroundComponent( name=b'Translating_Background', is_enabled=False, add_nop_listeners=True, layer=Layer(encoders=b'encoders', channel_selection_buttons=b'display_buttons')) def _create_device_navigation(self): self._device_navigation = SimpleDeviceNavigationComponent( name=b'Device_Navigation', is_enabled=False, layer=Layer(prev_button=b'display_buttons_raw[1]', next_button=b'display_buttons_raw[2]')) def _create_launch_and_stop(self): self._launch_and_stop = LaunchAndStopComponent( name=b'Launch_And_Stop', is_enabled=False, layer=Layer(clip_launch_button=b'display_buttons_raw[3]', scene_launch_button=b'display_buttons_raw[4]', track_stop_button=b'display_buttons_raw[5]')) def _create_session(self): self._session_ring = SessionRingComponent(name=b'Session_Ring', num_tracks=SESSION_WIDTH, num_scenes=SESSION_HEIGHT) self._session = SessionComponent( name=b'Session', is_enabled=False, session_ring=self._session_ring, layer=Layer(clip_launch_buttons=b'upper_pads')) self._session_navigation = SessionNavigationComponent( name=b'Session_Navigation', is_enabled=False, session_ring=self._session_ring, layer=Layer(up_button=b'up_button_with_shift', down_button=b'down_button_with_shift')) self._session_navigation.set_enabled(True) def _create_mixer(self): self._mixer = MixerComponent( name=b'Mixer', auto_name=True, tracks_provider=self._session_ring, track_assigner=SimpleTrackAssigner(), channel_strip_component_type=ChannelStripComponent) self._mixer.selected_strip().layer = Layer( track_name_display=b'track_name_display') self._mixer.set_enabled(True) def _create_view_control(self): self._view_control = NotifyingViewControlComponent( name=b'View_Control', is_enabled=False, track_provider=self._session_ring, enable_skinning=False, layer=Layer(next_track_button=b'right_button', prev_track_button=b'left_button', next_scene_button=b'down_button', prev_scene_button=b'up_button')) self._view_control.set_enabled(True) self._session_ring_selection_linking = self.register_disconnectable( SessionRingSelectionLinking( session_ring=self._session_ring, selection_changed_notifier=self._view_control)) def _create_button_labels(self): self._button_labels = ButtonLabelsComponent( is_enabled=False, layer=Layer(display_lines=b'button_label_display_matrix')) self._button_labels.set_enabled(True) def _create_record_modes(self): self._session_record = SessionRecordingComponent( name=b'Session_Record', is_enabled=False, layer=Layer(record_button=b'record_button')) self._record_modes = ModesComponent(name=b'Record_Modes') self._record_modes.add_mode(b'session', EnablingMode(self._session_record)) self._record_modes.add_mode( b'arrange', AddLayerMode(self._transport, layer=Layer(record_button=b'record_button'))) self.__on_main_view_changed() def _create_lower_pad_modes(self): self._lower_pad_modes = ModesComponent( name=b'Lower_Pad_Modes', is_enabled=False, layer=Layer(cycle_mode_button=b'minus_button')) self._lower_pad_modes.add_mode( b'select', AddLayerMode(self._mixer, Layer(track_select_buttons=b'lower_pads')), cycle_mode_button_color=b'Session.StopClipDisabled') self._lower_pad_modes.add_mode( b'stop', AddLayerMode(self._session, Layer(stop_track_clip_buttons=b'lower_pads')), cycle_mode_button_color=b'Session.StopClip') self._lower_pad_modes.selected_mode = b'select' def _create_main_modes(self): self._main_modes = ModesComponent( name=b'Main_Modes', is_enabled=False, layer=Layer(song_button=b'song_mode_button', instrument_button=b'instrument_mode_button', editor_button=b'editor_mode_button', user_button=b'user_mode_button')) device_params_mode = AddLayerMode( self._device_parameters, Layer(parameter_controls=b'encoders')) enable_lower_fw_functions = partial( self._elements.lower_firmware_toggle_switch.send_value, 1) disable_upper_fw_functions = partial( self._elements.upper_firmware_toggle_switch.send_value, 0) self._main_modes.add_mode( b'song', (partial(self._elements.lower_firmware_toggle_switch.send_value, 0), disable_upper_fw_functions, self._elements.display_buttons.reset, self._view_toggle, self._launch_and_stop, self._session, self._lower_pad_modes, AddLayerMode(self._session.scene(0), Layer(launch_button=b'plus_button')), AddLayerMode( self._mixer.selected_strip(), Layer(volume_control=b'encoders_raw[0]', pan_control=b'encoders_raw[1]', send_controls=self._elements.encoders.submatrix[2:, :], solo_button=b'display_buttons_raw[0]', mute_button=b'display_buttons_raw[1]', arm_button=b'display_buttons_raw[2]')), AddLayerMode(self._mixer, Layer(crossfader_control=b'touch_strip')))) self._main_modes.add_mode( b'instrument', (enable_lower_fw_functions, partial(self._elements.upper_firmware_toggle_switch.send_value, 1), device_params_mode)) self._main_modes.add_mode( b'editor', (enable_lower_fw_functions, disable_upper_fw_functions, device_params_mode, self._device_navigation, AddLayerMode( self._device_parameters, Layer(device_lock_button=b'display_buttons_raw[0]', device_on_off_button=b'display_buttons_raw[3]', prev_bank_button=b'display_buttons_raw[4]', next_bank_button=b'display_buttons_raw[5]')))) self._main_modes.add_mode( b'user', (enable_lower_fw_functions, disable_upper_fw_functions, self._translating_background)) self._main_modes.selected_mode = b'instrument' self._main_modes.set_enabled(True) self.__on_main_modes_changed.subject = self._main_modes @listens(b'selected_mode') def __on_main_modes_changed(self, mode): self._button_labels.show_button_labels_for_mode(mode) self._elements.track_name_display.clear_send_cache() self._elements.device_name_display.clear_send_cache() @listens(b'is_view_visible', b'Session') def __on_main_view_changed(self): if self.application.view.is_view_visible(b'Session'): self._record_modes.selected_mode = b'session' else: self._record_modes.selected_mode = b'arrange'
class Oxygen_Pro(IdentifiableControlSurface): session_height = 2 session_width = 8 live_mode_byte = midi.LIVE_MODE_BYTE pad_ids = ((40, 41, 42, 43, 48, 49, 50, 51), (36, 37, 38, 39, 44, 45, 46, 47)) device_parameter_component = SimpleDeviceParameterComponent has_session_component = True def __init__(self, *a, **k): (super(Oxygen_Pro, self).__init__)(a, product_id_bytes=midi.M_AUDIO_MANUFACTURER_ID + (0, ), **k) self._last_selected_knob_mode = 'device' with self.component_guard(): self._elements = Elements(self.session_height, self.session_width, self.pad_ids) with inject(element_container=(const(self._elements))).everywhere(): self._create_background() self._create_transport() self._create_undo_redo() self._create_session() self._create_mixer() self._create_device_parameters() self._create_record_modes() self._create_button_modes() self._create_knob_modes() self._create_takeover_modes() self._Oxygen_Pro__on_main_view_changed.subject = self.application.view def on_identified(self, response_bytes): self._elements.firmware_mode_switch.send_value(self.live_mode_byte) self._elements.control_mode_switch.send_value(midi.RECORD_MODE_BYTE) self._elements.control_mode_switch.send_value(midi.DEVICE_MODE_BYTE) self._elements.led_control_switch.send_value(midi.LED_ENABLE_BYTE) self._elements.led_mode_switch.send_value(midi.SOFTWARE_CONTROL_BYTE) self._button_modes.selected_mode = 'arm' self._knob_modes.selected_mode = 'device' if self.has_session_component: self._session_ring.set_enabled(True) super(Oxygen_Pro, self).on_identified(response_bytes) def port_settings_changed(self): if self.has_session_component: self._session_ring.set_enabled(False) super(Oxygen_Pro, self).port_settings_changed() def _create_background(self): self._background = BackgroundComponent(name='Background', is_enabled=False, add_nop_listeners=True, layer=Layer(shift_button='shift_button')) self._background.set_enabled(True) def _create_transport(self): self._transport = TransportComponent(name='Transport', is_enabled=False, layer=Layer(loop_button='loop_button', stop_button='stop_button', play_button='play_button', metronome_button='metronome_button', seek_forward_button='fastforward_button', seek_backward_button='rewind_button')) self._transport.set_enabled(True) def _create_undo_redo(self): self._undo_redo = UndoRedoComponent(name='Undo_Redo', is_enabled=False, layer=Layer(undo_button='back_button')) self._undo_redo.set_enabled(True) def _create_session(self): self._session_ring = SessionRingComponent(name='Session_Ring', is_enabled=False, num_tracks=(self.session_width), num_scenes=(self.session_height)) if self.has_session_component: self._session = SessionComponent(name='Session', is_enabled=False, session_ring=(self._session_ring), layer=Layer(clip_launch_buttons='pads', scene_launch_buttons='scene_launch_buttons', selected_scene_launch_button='encoder_push_button', scene_encoder='encoder_with_encoder_push')) self._session.set_enabled(True) self._session_navigation = SessionNavigationComponent(name='Session_Navigation', is_enabled=False, session_ring=(self._session_ring), layer=Layer(left_button='bank_left_button', right_button='bank_right_button', scene_encoder='encoder')) self._session_navigation.set_enabled(True) def _create_mixer(self): self._mixer = MixerComponent(name='Mixer', is_enabled=False, auto_name=True, channel_strip_component_type=ChannelStripComponent, tracks_provider=(self._session_ring), track_assigner=(SimpleTrackAssigner()), layer=Layer(volume_controls='faders')) self._mixer.master_strip().set_volume_control(self._elements.master_fader) self._mixer.set_enabled(True) def _create_device_parameters(self): self._device_parameters = self.device_parameter_component(name='Device_Parameters', is_enabled=False, layer=Layer(parameter_controls='knobs')) def _create_record_modes(self): self._session_record = SessionRecordingComponent(name='Session_Record', is_enabled=False, layer=Layer(record_button='record_button')) self._record_modes = ModesComponent(name='Record_Modes') self._record_modes.add_mode('session', EnablingMode(self._session_record)) self._record_modes.add_mode('arrange', AddLayerMode((self._transport), layer=Layer(record_button='record_button'))) self._Oxygen_Pro__on_main_view_changed() def _create_button_modes(self): self._button_modes = ModesComponent(name='Button_Modes', is_enabled=False, layer=Layer(off_button='off_mode_button', arm_button='arm_mode_button', track_select_button='track_select_mode_button', mute_button='mute_mode_button', solo_button='solo_mode_button')) self._button_modes.add_mode('off', None, behaviour=(ImmediateBehaviour())) self._button_modes.add_mode('arm', AddLayerMode((self._mixer), layer=Layer(arm_buttons='fader_buttons')), behaviour=(ImmediateBehaviour())) self._button_modes.add_mode('track_select', AddLayerMode((self._mixer), layer=Layer(track_select_buttons='fader_buttons')), behaviour=(ImmediateBehaviour())) self._button_modes.add_mode('mute', AddLayerMode((self._mixer), layer=Layer(mute_buttons='fader_buttons')), behaviour=(ImmediateBehaviour())) self._button_modes.add_mode('solo', AddLayerMode((self._mixer), layer=Layer(solo_buttons='fader_buttons')), behaviour=(ImmediateBehaviour())) self._button_modes.selected_mode = 'arm' self._button_modes.set_enabled(True) def _create_knob_modes(self): self._knob_modes = ModesComponent(name='Knob_Modes', is_enabled=False, layer=Layer(volume_button='volume_mode_button', pan_button='pan_mode_button', sends_button='sends_mode_button', device_button='device_mode_button')) self._knob_modes.add_mode('volume', AddLayerMode((self._mixer), layer=Layer(volume_controls='knobs')), behaviour=(ImmediateBehaviour())) self._knob_modes.add_mode('pan', AddLayerMode((self._mixer), layer=Layer(pan_controls='knobs')), behaviour=(ImmediateBehaviour())) self._knob_modes.add_mode('sends', AddLayerMode((self._mixer), layer=Layer(send_controls='knobs')), behaviour=ReenterBehaviour(on_reenter=(self._on_reenter_sends_mode))) self._knob_modes.add_mode('device', (self._device_parameters), behaviour=(self._get_device_mode_behaviour())) self._knob_modes.add_mode('takeover', None) self._knob_modes.selected_mode = 'device' self._Oxygen_Pro__on_knob_mode_changed.subject = self._knob_modes self._knob_modes.set_enabled(True) def _get_device_mode_behaviour(self): return ImmediateBehaviour() def _on_reenter_sends_mode(self): new_send_index = 1 if self._mixer.send_index == 0 else 0 if new_send_index in range(self._mixer.num_sends): self._mixer.send_index = new_send_index def _create_takeover_modes(self): self._takeover_modes = ModesComponent(name='Takeover_Modes', is_enabled=False, layer=Layer(daw_button='daw_mode_button', preset_button='preset_mode_button')) self._takeover_modes.add_mode('daw', self._select_knob_mode) self._takeover_modes.add_mode('preset', ( self._select_knob_mode, AddLayerMode((self._background), layer=Layer(faders='faders', knobs='knobs')))) self._takeover_modes.selected_mode = 'daw' self._takeover_modes.set_enabled(True) def _select_knob_mode(self): if self._takeover_modes.selected_mode == 'daw': self._knob_modes.selected_mode = self._last_selected_knob_mode else: self._knob_modes.selected_mode = 'takeover' @listens('selected_mode') def __on_knob_mode_changed(self, mode): if mode != 'takeover': self._last_selected_knob_mode = mode @listens('is_view_visible', 'Session') def __on_main_view_changed(self): if self.application.view.is_view_visible('Session'): self._record_modes.selected_mode = 'session' else: self._record_modes.selected_mode = 'arrange'
class Launchpad_Pro_MK3(InstrumentControlMixin, NovationBase): model_family_code = ids.LP_PRO_MK3_FAMILY_CODE element_class = Elements session_class = SessionComponent mixer_class = MixerComponent channel_strip_class = ChannelStripComponent skin = skin suppress_layout_switch = False track_recording_class = FixedLengthTrackRecordingComponent def __init__(self, *a, **k): self._layout_to_restore = None self._can_restore_layout = False self._last_layout_bytes = ids.SESSION_LAYOUT_BYTES super(Launchpad_Pro_MK3, self).__init__(*a, **k) def disconnect(self): super(Launchpad_Pro_MK3, self).disconnect() self._auto_arm.set_enabled(False) self._elements.scale_feedback_switch.send_value(Rgb.GREEN.midi_value) def on_identified(self, midi_bytes): self._elements.firmware_mode_switch.send_value(sysex.DAW_MODE_BYTE) self._elements.layout_switch.send_value(self._last_layout_bytes) self._target_track_changed() self._drum_group_changed() self.set_feedback_channels( [DRUM_FEEDBACK_CHANNEL, SCALE_FEEDBACK_CHANNEL]) self._setup_faders() super(Launchpad_Pro_MK3, self).on_identified(midi_bytes) def port_settings_changed(self): self._auto_arm.set_enabled(False) super(Launchpad_Pro_MK3, self).port_settings_changed() def _setup_faders(self): for i, fader_mode in enumerate(FADER_MODES): orientation, polarity = ( sysex.FADER_HORIZONTAL_ORIENTATION, sysex.FADER_BIPOLAR) if fader_mode == u'pan' else ( sysex.FADER_VERTICAL_ORIENTATION, sysex.FADER_UNIPOLAR) self._elements.fader_setup_element.send_value( i, orientation, polarity) def _create_components(self): self._fixed_length_setting = FixedLengthSetting() self._fixed_length_recording = FixedLengthRecording( self.song, self._fixed_length_setting) with inject(fixed_length_recording=const( self._fixed_length_recording)).everywhere(): super(Launchpad_Pro_MK3, self)._create_components() self._create_recording_modes() self._create_session_overview() self._create_auto_arm() self._create_background() self._create_device_navigation() self._create_device_parameters() self._create_print_to_clip() self._create_undo_redo() self._create_transport() self._create_clip_actions() self._create_quantization() self._create_fixed_length() self._create_drum_group() self._create_scale_pad_translator() self._create_mixer_modes() self._create_session_modes() self._create_note_modes() self._create_main_modes() self.__on_layout_switch_value.subject = self._elements.layout_switch def _create_session_overview(self): self._session_overview = SessionOverviewComponent( name=u'Session_Overview', is_enabled=False, session_ring=self._session_ring, enable_skinning=True, layer=Layer(button_matrix=u'clip_launch_matrix')) def _create_auto_arm(self): self._auto_arm = AutoArmComponent(name=u'Auto_Arm', is_enabled=False) def _create_background(self): self._background = BackgroundComponent( name=u'Background', is_enabled=False, add_nop_listeners=True, layer=Layer(clear_button=u'clear_button', duplicate_button=u'duplicate_button', quantize_button=u'quantize_button', scene_launch_buttons=u'scene_launch_buttons', priority=-1) + Layer( duplicate_button_with_shift=u'duplicate_button_with_shift', track_select_buttons_with_shift= u'track_select_buttons_with_shift', up_button_with_shift=u'up_button_with_shift', down_button_with_shift=u'down_button_with_shift', left_button_with_shift=u'left_button_with_shift', right_button_with_shift=u'right_button_with_shift', double_button=u'duplicate_button_with_shift', clear_button_with_shift=u'clear_button_with_shift', volume_button_with_shift=u'volume_button_with_shift', pan_button_with_shift=u'pan_button_with_shift', sends_button_with_shift=u'sends_button_with_shift', device_button_with_shift=u'device_button_with_shift', stop_clip_button_with_shift=u'stop_clip_button_with_shift', fixed_length_button_with_shift=u'fixed_length_button_with_shift' )) self._background.set_enabled(True) def _create_print_to_clip(self): self._print_to_clip = PrintToClipComponent( name=u'Print_To_Clip', is_enabled=False, layer=Layer( print_to_clip_control=u'print_to_clip_element', print_to_clip_enabler=u'print_to_clip_enabler_element')) self._print_to_clip.set_enabled(True) def _create_undo_redo(self): self._undo_redo = UndoRedoComponent( name=u'Undo_Redo', is_enabled=False, layer=Layer(undo_button=u'record_arm_button_with_shift', redo_button=u'mute_button_with_shift')) self._undo_redo.undo_button.color = u'Action.Undo' self._undo_redo.undo_button.pressed_color = u'Action.UndoPressed' self._undo_redo.redo_button.color = u'Action.Redo' self._undo_redo.redo_button.pressed_color = u'Action.RedoPressed' self._undo_redo.set_enabled(True) def _create_transport(self): self._transport = TransportComponent( name=u'Transport', is_enabled=False, layer=Layer(play_button=u'play_button', continue_playing_button=u'play_button_with_shift', metronome_button=u'solo_button_with_shift', capture_midi_button=u'record_button_with_shift', tap_tempo_button=u'sends_button_with_shift')) self._transport.tap_tempo_button.color = u'Transport.TapTempo' self._transport.set_enabled(True) def _create_clip_actions(self): self._clip_actions = ClipActionsComponent( name=u'Clip_Actions', is_enabled=False, layer=Layer(duplicate_button=u'duplicate_button', quantize_button=u'quantize_button', double_loop_button=u'duplicate_button_with_shift')) def _create_quantization(self): self._quantization = QuantizationComponent( name=u'Quantization', is_enabled=False, layer=Layer( quantization_toggle_button=u'quantize_button_with_shift')) self._quantization.set_enabled(True) ClipActionsComponent.quantization_component = self._quantization ClipSlotComponent.quantization_component = self._quantization def _create_fixed_length(self): self._fixed_length = FixedLengthComponent( fixed_length_setting=self._fixed_length_setting, name=u'Fixed_Length', is_enabled=False, layer=Layer(fixed_length_button=u'fixed_length_button')) self._fixed_length.settings_component.layer = Layer( length_option_buttons=u'track_select_buttons') self._fixed_length.set_enabled(True) def _create_drum_group(self): self._drum_group = DrumGroupComponent( self._clip_actions, name=u'Drum_Group', is_enabled=False, translation_channel=DRUM_FEEDBACK_CHANNEL, layer=Layer(matrix=u'drum_pads')) self._drum_group.set_enabled(True) def _create_device_parameters(self): self._device_parameters = SimpleDeviceParameterComponent( name=u'Device_Parameters', is_enabled=False, device_bank_registry=self._device_bank_registry, layer=Layer( parameter_controls=u'device_button_faders', static_color_controls=u'device_button_fader_color_elements', stop_fader_control=u'stop_fader_element'), static_color_value=Rgb.DARK_BLUE.midi_value) self._device_parameters.set_enabled(True) def _create_device_navigation(self): self._device_navigation = SimpleDeviceNavigationComponent( name=u'Device_Navigation') def _create_scale_pad_translator(self): self._scale_pad_translator = ConfigurablePlayableComponent( SCALE_FEEDBACK_CHANNEL, name=u'Scale_Pads', is_enabled=False, layer=Layer(matrix=u'scale_pads')) self._scale_pad_translator.set_enabled(True) def _create_mixer_modes(self): self._mixer_modes = ModesComponent( name=u'Mixer_Modes', is_enabled=False, enable_skinning=True, layer=Layer(arm_button=u'record_arm_button', mute_button=u'mute_button', solo_button=u'solo_button', volume_button=u'volume_button', pan_button=u'pan_button', sends_button=u'sends_button', device_button=u'device_button', stop_button=u'stop_clip_button')) self._mixer.layer = Layer(volume_controls=u'volume_button_faders', pan_controls=u'pan_button_faders', send_controls=u'sends_button_faders') reselect_track_select_mode = partial(setattr, self._mixer_modes, u'selected_mode', u'track_select') def restore_main_layout(): if self._can_restore_layout and self._layout_to_restore: self._elements.layout_switch.send_value( self._layout_to_restore) def add_track_select_button_mode(name, control=None, component=self._mixer): control_key = control if control else u'{}_buttons'.format(name) control_dict = {control_key: u'track_select_buttons'} self._mixer_modes.add_mode( name, (AddLayerMode(component, Layer(**control_dict)), DelayMode(restore_main_layout, delay=0.1)), behaviour=ReenterBehaviour( on_reenter=reselect_track_select_mode)) add_track_select_button_mode(u'track_select') add_track_select_button_mode(u'arm') add_track_select_button_mode(u'mute') add_track_select_button_mode(u'solo') add_track_select_button_mode(u'stop', control=u'stop_track_clip_buttons', component=self._session) def switch_to_fader_layout(bank): fader_layout_bytes = (ids.FADER_LAYOUT_BYTE, bank, 0) self._elements.layout_switch.send_value(fader_layout_bytes) def add_fader_mode(name, bank, add_layer_mode, static_color=None): self._mixer_modes.add_mode( name, (add_layer_mode, AddLayerMode( self._mixer, Layer(track_select_buttons=u'track_select_buttons')), partial(self._mixer._update_send_control_colors), partial(self._mixer.set_static_color_value, static_color), partial(switch_to_fader_layout, bank)), behaviour=ReenterBehaviour( on_reenter=reselect_track_select_mode)) add_fader_mode( u'volume', 0, AddLayerMode( self._mixer, Layer( static_color_controls=u'volume_button_fader_color_elements' )), static_color=Rgb.GREEN.midi_value) add_fader_mode( u'pan', 1, AddLayerMode( self._mixer, Layer( track_color_controls=u'pan_button_fader_color_elements'))) add_fader_mode( u'sends', 2, AddLayerMode( self._mixer, Layer(send_select_buttons=u'scene_launch_buttons', return_track_color_controls= u'sends_button_fader_color_elements', stop_fader_control=u'stop_fader_element'))) add_fader_mode( u'device', 3, (AddLayerMode( self._background, Layer(up_button=u'up_button', down_button=u'down_button')), AddLayerMode( self._device_navigation, Layer(prev_button=u'left_button', next_button=u'right_button')), AddLayerMode(self._device_parameters, Layer(bank_select_buttons=u'scene_launch_buttons')))) self._mixer_modes.selected_mode = u'track_select' self._mixer_modes.set_enabled(True) def _create_session_modes(self): self._session_modes = ModesComponent( name=u'Session_Modes', is_enabled=False, layer=Layer(overview_button=u'session_mode_button')) self._session_modes.add_mode( u'launch', AddLayerMode( self._session, Layer(managed_select_button=u'shift_button', managed_delete_button=u'clear_button', managed_duplicate_button=u'duplicate_button', managed_quantize_button=u'quantize_button', managed_double_button=u'duplicate_button_with_shift', scene_launch_buttons=u'scene_launch_buttons'))) self._session_modes.add_mode( u'overview', (self._session_overview, AddLayerMode( self._session_navigation, Layer(page_up_button=u'up_button', page_down_button=u'down_button', page_left_button=u'left_button', page_right_button=u'right_button'))), behaviour=MomentaryBehaviour()) self._session_modes.selected_mode = u'launch' def _create_note_modes(self): self._note_modes = ModesComponent(name=u'Note_Modes', is_enabled=False) self._note_modes.add_mode( u'scale', AddLayerMode(self._clip_actions, Layer(delete_button=u'clear_button'))) self._note_modes.add_mode( u'drum', AddLayerMode( self._drum_group, Layer(scroll_up_button=u'left_button', scroll_down_button=u'right_button', scroll_page_up_button=u'up_button', scroll_page_down_button=u'down_button', delete_button=u'clear_button'))) def _create_main_modes(self): self._main_modes = ModesComponent(name=u'Main_Modes', is_enabled=False) suppressed_arrow_button_mode = (AddLayerMode( self._background, Layer(left_button=u'left_button', right_button=u'right_button', up_button=u'up_button', down_button=u'down_button')), ) self._main_modes.add_mode(u'none', suppressed_arrow_button_mode) self._main_modes.add_mode(u'fader', None) self._main_modes.add_mode(u'session', self._session_modes) self._main_modes.add_mode(u'note', (self._note_modes, self._clip_actions)) self._main_modes.add_mode(u'chord', suppressed_arrow_button_mode) self._main_modes.selected_mode = u'session' self._main_modes.set_enabled(True) self.__on_main_mode_changed.subject = self._main_modes @listens(u'selected_mode') def __on_main_mode_changed(self, mode): if mode == u'session': self._session_modes.selected_mode = u'launch' self._recording_modes.selected_mode = u'session' if mode == u'session' else u'track' self._update_controlled_track() self._auto_arm.set_enabled(self._is_instrument_mode()) @listens(u'value') def __on_layout_switch_value(self, value): self._can_restore_layout = value[0] in LIVE_LAYOUT_BYTES if not self._can_restore_layout: return if value[0] == ids.FADER_LAYOUT_BYTE: self._main_modes.selected_mode = u'fader' else: self._layout_to_restore = value if self._mixer_modes.selected_mode in FADER_MODES: self._mixer_modes.selected_mode = u'track_select' if value in LAYOUT_BYTES_TO_MODE_NAMES_MAP: self._main_modes.selected_mode = LAYOUT_BYTES_TO_MODE_NAMES_MAP[ value] else: self._main_modes.selected_mode = u'none' self._last_layout_bytes = value def _drum_group_changed(self): drum_group = self._drum_group_finder.drum_group drum_group_valid = liveobj_valid(drum_group) self._drum_group.set_drum_group_device(drum_group) self._elements.layout_switch.send_value( ids.DRUM_LAYOUT_BYTES if drum_group_valid else ids. SCALE_LAYOUT_BYTES) self._note_modes.selected_mode = u'drum' if drum_group_valid else u'scale' def _is_instrument_mode(self): return self._main_modes.selected_mode in NOTE_MODE_NAMES def _feedback_velocity_changed(self, feedback_velocity): self._elements.scale_feedback_switch.send_value(feedback_velocity)
class ATOM(ControlSurface): def __init__(self, *a, **k): super(ATOM, self).__init__(*a, **k) with self.component_guard(): with inject(skin=const(skin)).everywhere(): self._elements = Elements() with self.component_guard(): with inject(element_container=const(self._elements)).everywhere(): self._create_lighting() self._create_transport() self._create_record_modes() self._create_undo() self._create_view_toggle() self._create_background() self._create_session() self._create_mixer() self._create_encoder_modes() self._create_session_navigation_modes() self._create_keyboard() self._create_drum_group() self._create_note_modes() self._create_pad_modes() self._create_user_assignments_mode() self._target_track = ArmedTargetTrackComponent( name=u'Target_Track') self.__on_target_track_changed.subject = self._target_track self._drum_group_finder = self.register_disconnectable( PercussionInstrumentFinder( device_parent=self._target_track.target_track)) self.__on_drum_group_changed.subject = self._drum_group_finder self.__on_drum_group_changed() self.__on_main_view_changed.subject = self.application.view def disconnect(self): self._send_midi(midi.NATIVE_MODE_OFF_MESSAGE) super(ATOM, self).disconnect() def port_settings_changed(self): self._send_midi(midi.NATIVE_MODE_ON_MESSAGE) super(ATOM, self).port_settings_changed() def _create_lighting(self): self._lighting = LightingComponent(name=u'Lighting', is_enabled=False, layer=Layer( shift_button=u'shift_button', zoom_button=u'zoom_button')) self._lighting.set_enabled(True) def _create_transport(self): self._transport = TransportComponent( name=u'Transport', is_enabled=False, layer=Layer(play_button=u'play_button', loop_button=u'play_button_with_shift', stop_button=u'stop_button', metronome_button=u'click_button')) self._transport.set_enabled(True) def _create_record_modes(self): self._session_record = SessionRecordingComponent( name=u'Session_Record', is_enabled=False, layer=Layer(record_button=u'record_button')) self._record_modes = ModesComponent(name=u'Record_Modes') self._record_modes.add_mode(u'session', self._session_record) self._record_modes.add_mode( u'arrange', AddLayerMode(self._transport, layer=Layer(record_button=u'record_button'))) self.__on_main_view_changed() def _create_undo(self): self._undo = UndoRedoComponent( name=u'Undo', is_enabled=False, layer=Layer(undo_button=u'stop_button_with_shift')) self._undo.set_enabled(True) def _create_view_toggle(self): self._view_toggle = ViewToggleComponent( name=u'View_Toggle', is_enabled=False, layer=Layer(detail_view_toggle_button=u'show_hide_button', main_view_toggle_button=u'preset_button')) self._view_toggle.set_enabled(True) def _create_background(self): self._background = BackgroundComponent( name=u'Background', is_enabled=False, add_nop_listeners=True, layer=Layer(set_loop_button=u'set_loop_button', nudge_button=u'nudge_button', bank_button=u'bank_button')) self._background.set_enabled(True) def _create_session(self): self._session_ring = SessionRingComponent(name=u'Session_Ring', num_tracks=SESSION_WIDTH, num_scenes=SESSION_HEIGHT) self._session = SessionComponent(name=u'Session', session_ring=self._session_ring) self._session_navigation = SessionNavigationComponent( name=u'Session_Navigation', is_enabled=False, session_ring=self._session_ring, layer=Layer(left_button=u'left_button', right_button=u'right_button')) self._session_navigation.set_enabled(True) self._session_overview = SessionOverviewComponent( name=u'Session_Overview', is_enabled=False, session_ring=self._session_ring, enable_skinning=True, layer=Layer(button_matrix=u'pads_with_zoom')) def _create_mixer(self): self._mixer = MixerComponent( name=u'Mixer', auto_name=True, tracks_provider=self._session_ring, track_assigner=SimpleTrackAssigner(), invert_mute_feedback=True, channel_strip_component_type=ChannelStripComponent) def _create_encoder_modes(self): self._encoder_modes = ModesComponent(name=u'Encoder_Modes', enable_skinning=True) self._encoder_modes.add_mode( u'volume', AddLayerMode(self._mixer, Layer(volume_controls=u'encoders'))) self._encoder_modes.add_mode( u'pan', AddLayerMode(self._mixer, Layer(pan_controls=u'encoders'))) self._encoder_modes.add_mode( u'send_a', AddLayerMode(self._mixer, Layer(send_a_controls=u'encoders'))) self._encoder_modes.add_mode( u'send_b', AddLayerMode(self._mixer, Layer(send_b_controls=u'encoders'))) self._encoder_modes.selected_mode = u'volume' def _create_session_navigation_modes(self): self._session_navigation_modes = ModesComponent( name=u'Session_Navigation_Modes', is_enabled=False, layer=Layer(cycle_mode_button=u'bank_button')) self._session_navigation_modes.add_mode( u'default', AddLayerMode(self._session_navigation, layer=Layer(up_button=u'up_button', down_button=u'down_button')), cycle_mode_button_color=u'DefaultButton.Off') self._session_navigation_modes.add_mode( u'paged', AddLayerMode(self._session_navigation, layer=Layer(page_up_button=u'up_button', page_down_button=u'down_button', page_left_button=u'left_button', page_right_button=u'right_button')), cycle_mode_button_color=u'DefaultButton.On') self._session_navigation_modes.selected_mode = u'default' def _create_keyboard(self): self._keyboard = KeyboardComponent( midi.KEYBOARD_CHANNEL, name=u'Keyboard', is_enabled=False, layer=Layer(matrix=u'pads', scroll_up_button=u'up_button', scroll_down_button=u'down_button')) def _create_drum_group(self): self._drum_group = DrumGroupComponent( name=u'Drum_Group', is_enabled=False, translation_channel=midi.DRUM_CHANNEL, layer=Layer(matrix=u'pads', scroll_page_up_button=u'up_button', scroll_page_down_button=u'down_button')) def _create_note_modes(self): self._note_modes = ModesComponent(name=u'Note_Modes', is_enabled=False) self._note_modes.add_mode(u'keyboard', self._keyboard) self._note_modes.add_mode(u'drum', self._drum_group) self._note_modes.selected_mode = u'keyboard' def _create_pad_modes(self): self._pad_modes = ModesComponent( name=u'Pad_Modes', is_enabled=False, layer=Layer(session_button=u'full_level_button', note_button=u'note_repeat_button', channel_button=u'select_button', encoder_modes_button=u'setup_button')) self._pad_modes.add_mode( u'session', (AddLayerMode(self._background, Layer(unused_pads=u'pads_with_shift')), AddLayerMode( self._session, Layer(clip_launch_buttons=u'pads', scene_launch_buttons=self._elements.pads_with_shift. submatrix[3:, :])), self._session_overview, self._session_navigation_modes)) self._pad_modes.add_mode(u'note', self._note_modes) self._pad_modes.add_mode( u'channel', (self._elements.pads.reset, AddLayerMode( self._mixer, Layer( arm_buttons=self._elements.pads.submatrix[:, :1], solo_buttons=self._elements.pads.submatrix[:, 1:2], track_select_buttons=self._elements.pads.submatrix[:, 2:3])), AddLayerMode( self._session, Layer(stop_track_clip_buttons=self._elements.pads. submatrix[:, 3:])), self._session_navigation_modes)) self._pad_modes.add_mode( u'encoder_modes', (LayerMode( self._encoder_modes, Layer(volume_button=self._elements.pads_raw[0][0], pan_button=self._elements.pads_raw[0][1], send_a_button=self._elements.pads_raw[0][2], send_b_button=self._elements.pads_raw[0][3])), AddLayerMode( self._background, Layer(unused_pads=self._elements.pads.submatrix[:, 1:]))), behaviour=MomentaryBehaviour()) self._pad_modes.selected_mode = u'session' self._pad_modes.set_enabled(True) def _create_user_assignments_mode(self): self._translating_background = TranslatingBackgroundComponent( midi.USER_CHANNEL, name=u'Translating_Background', is_enabled=False, add_nop_listeners=True, layer=Layer(note_repeat_button=u'note_repeat_button', full_level_button=u'full_level_button', bank_button=u'bank_button', preset_button=u'preset_button', show_hide_button=u'show_hide_button', nudge_button=u'nudge_button', set_loop_button=u'set_loop_button', setup_button=u'setup_button', up_button=u'up_button', down_button=u'down_button', left_button=u'left_button', right_button=u'right_button', select_button=u'select_button', click_button=u'click_button', record_button=u'record_button', play_button=u'play_button', stop_button=u'stop_button', pads=u'pads', encoders=u'encoders')) self._top_level_modes = ModesComponent( name=u'Top_Level_Modes', is_enabled=False, support_momentary_mode_cycling=False, layer=Layer(cycle_mode_button=u'editor_button')) self._top_level_modes.add_mode( u'default', self.refresh_state, cycle_mode_button_color=u'DefaultButton.Off') self._top_level_modes.add_mode( u'user', self._translating_background, cycle_mode_button_color=u'DefaultButton.On') self._top_level_modes.selected_mode = u'default' self._top_level_modes.set_enabled(True) @listens(u'is_view_visible', u'Session') def __on_main_view_changed(self): if self.application.view.is_view_visible(u'Session'): self._record_modes.selected_mode = u'session' else: self._record_modes.selected_mode = u'arrange' @listens(u'target_track') def __on_target_track_changed(self): self._drum_group_finder.device_parent = self._target_track.target_track @listens(u'instrument') def __on_drum_group_changed(self): drum_group = self._drum_group_finder.drum_group self._drum_group.set_drum_group_device(drum_group) self._note_modes.selected_mode = u'drum' if liveobj_valid( drum_group) else u'keyboard'
class Oxygen_Pro(ControlSurface): def __init__(self, *a, **k): super(Oxygen_Pro, self).__init__(*a, **k) with self.component_guard(): self._elements = Elements() with inject(element_container=const(self._elements)).everywhere(): self._create_transport() self._create_undo_redo() self._create_device_parameters() self._create_session() self._create_mixer() self._create_record_modes() self.__on_main_view_changed.subject = self.application.view def _create_transport(self): self._transport = TransportComponent(name=u'Transport', is_enabled=False, layer=Layer( loop_button=u'loop_button', stop_button=u'stop_button', play_button=u'play_button')) self._transport.set_enabled(True) def _create_undo_redo(self): self._undo_redo = UndoRedoComponent( name=u'Undo_Redo', is_enabled=False, layer=Layer(undo_button=u'back_button')) self._undo_redo.set_enabled(True) def _create_device_parameters(self): self._device_parameters = SimpleDeviceParameterComponent( name=u'Device_Parameters', is_enabled=False, layer=Layer(parameter_controls=u'knobs')) self._device_parameters.set_enabled(True) def _create_session(self): self._session_ring = SessionRingComponent(name=u'Session_Ring', num_tracks=SESSION_WIDTH, num_scenes=SESSION_HEIGHT) self._session = SessionComponent( name=u'Session', is_enabled=False, session_ring=self._session_ring, layer=Layer(clip_launch_buttons=u'pads', scene_launch_buttons=u'scene_launch_buttons', scene_encoder=u'encoder')) self._session.selected_scene().set_launch_button( self._elements.encoder_push_button) self._session.set_enabled(True) self._session_navigation = SessionNavigationComponent( name=u'Session_Navigation', is_enabled=False, session_ring=self._session_ring, layer=Layer(left_button=u'bank_left_button', right_button=u'bank_right_button')) self._session_navigation.set_up_button(self._elements.rewind_button) self._session_navigation.set_down_button( self._elements.fastforward_button) self._session_navigation.set_enabled(True) def _create_mixer(self): self._mixer = MixerComponent(name=u'Mixer', is_enabled=False, auto_name=True, tracks_provider=self._session_ring, track_assigner=SimpleTrackAssigner(), layer=Layer(volume_controls=u'faders', arm_buttons=u'fader_buttons')) self._mixer.master_strip().set_volume_control( self._elements.master_fader) self._mixer.set_enabled(True) def _create_record_modes(self): self._session_record = SessionRecordingComponent( name=u'Session_Record', is_enabled=False, layer=Layer(record_button=u'record_button')) self._record_modes = ModesComponent(name=u'Record_Modes') self._record_modes.add_mode(u'session', EnablingMode(self._session_record)) self._record_modes.add_mode( u'arrange', AddLayerMode(self._transport, layer=Layer(record_button=u'record_button'))) self.__on_main_view_changed() @listens(u'is_view_visible', u'Session') def __on_main_view_changed(self): if self.application.view.is_view_visible(u'Session'): self._record_modes.selected_mode = u'session' else: self._record_modes.selected_mode = u'arrange'
class Launchkey_MK3(InstrumentControlMixin, NovationBase): element_class = Elements session_height = SESSION_HEIGHT mixer_class = MixerComponent channel_strip_class = ChannelStripComponent skin = skin suppress_layout_switch = False def __init__(self, *a, **k): self._is_small_model = False self._last_pad_layout_byte = midi.PAD_SESSION_LAYOUT self._last_pot_layout_byte = None self._last_fader_layout_byte = midi.VOLUME_LAYOUT super(Launchkey_MK3, self).__init__(*a, **k) def disconnect(self): self._elements.pad_layout_switch.send_value(midi.PAD_DRUM_LAYOUT) self._auto_arm.set_enabled(False) super(Launchkey_MK3, self).disconnect() def on_identified(self, midi_bytes): if self._last_pot_layout_byte is None: self._last_pot_layout_byte = midi.VOLUME_LAYOUT if self._is_small_model else midi.PAN_LAYOUT self._pot_modes.selected_mode = u'volume' if self._is_small_model else u'pan' self._elements.incontrol_mode_switch.send_value(midi.INCONTROL_ONLINE_VALUE) self._elements.pad_layout_switch.send_value(self._last_pad_layout_byte) self._elements.pot_layout_switch.send_value(self._last_pot_layout_byte) if not self._is_small_model: self._elements.fader_layout_switch.send_value(self._last_fader_layout_byte) self._target_track_changed() self._drum_group_changed() self._auto_arm.set_enabled(True) self.set_feedback_channels([DRUM_FEEDBACK_CHANNEL]) super(Launchkey_MK3, self).on_identified(midi_bytes) def port_settings_changed(self): self._auto_arm.set_enabled(False) super(Launchkey_MK3, self).port_settings_changed() def _create_components(self): super(Launchkey_MK3, self)._create_components() self.register_slot(self._elements.incontrol_mode_switch, nop, u'value') self._create_auto_arm() self._create_background() self._create_notification() self._create_view_control() self._create_transport() self._create_recording_modes() self._create_undo() self._create_quantization() self._create_device() self._create_drum_group() self._pot_modes = self._create_pot_or_fader_modes(u'pot') self._create_stop_solo_mute_modes() self._create_pad_modes() if not self._is_small_model: self._fader_modes = self._create_pot_or_fader_modes(u'fader') self._setup_master_fader() self._create_fader_button_modes() def _setup_master_fader(self): strip = self._mixer.master_strip() strip.set_volume_control(self._elements.master_fader) strip.volume_display.set_control_element(self._elements.master_fader_parameter_value_display) self._elements.master_fader_parameter_name_display.display_message(u'Master Volume') def _create_session_navigation_layer(self): return Layer(up_button=u'up_button', down_button=u'down_button') def _create_session_layer(self): return super(Launchkey_MK3, self)._create_session_layer() + Layer(scene_launch_buttons=u'scene_launch_buttons') def _create_auto_arm(self): self._auto_arm = AutoArmComponent(name=u'Auto_Arm', is_enabled=False) def _create_background(self): self._background = BackgroundComponent(name=u'Background', is_enabled=False, add_nop_listeners=True, layer=Layer(secondary_up_button=u'secondary_up_button', secondary_down_button=u'secondary_down_button', device_select_button=u'device_select_button', unused_matrix=self._elements.device_select_matrix.submatrix[:, 1:], pot_parameter_name_displays=u'pot_parameter_name_displays', pot_parameter_value_displays=u'pot_parameter_value_displays', fader_parameter_name_displays=u'fader_parameter_name_displays', fader_parameter_value_displays=u'fader_parameter_value_displays')) self._background.set_enabled(True) def _create_notification(self): self._notification_component = NotificationComponent(name=u'Notifications', is_enabled=False, layer=Layer(display_lines=u'notification_display')) self._notification_component.set_enabled(True) def _create_view_control(self): self._view_control = NotifyingViewControlComponent(name=u'Track_Scroller', is_enabled=False, track_provider=self._session_ring, layer=Layer(prev_track_button=u'left_button', next_track_button=u'right_button')) self._view_control.set_enabled(True) self._session_ring_selection_linking = self.register_disconnectable(SessionRingSelectionLinking(session_ring=self._session_ring, selection_changed_notifier=self._view_control)) def _create_transport(self): self._transport = TransportComponent(name=u'Transport', is_enabled=False, layer=Layer(play_button=u'play_button', alt_stop_button=u'stop_button', loop_button=u'loop_button', metronome_button=u'click_button', capture_midi_button=u'capture_midi_button')) self._transport.set_enabled(True) def _create_undo(self): self._undo = UndoRedoComponent(name=u'Undo', is_enabled=False, layer=Layer(undo_button=u'undo_button')) self._undo.set_enabled(True) def _create_quantization(self): self._quantization = QuantizationComponent(name=u'Quantization') self._clip_actions = ClipActionsComponent(name=u'Clip_Actions', is_enabled=False, layer=Layer(quantize_button=u'quantize_button')) self._clip_actions.set_enabled(True) ClipActionsComponent.quantization_component = self._quantization def _create_device(self): self._device = DeviceComponent(name=u'Device', is_enabled=False, show_notification=self._notification_component.show_notification, device_bank_registry=self._device_bank_registry, toggle_lock=self.toggle_lock, use_parameter_banks=True, layer=Layer(device_lock_button=u'device_lock_button')) self._device.set_enabled(True) def _create_drum_group(self): self._drum_group = DrumGroupComponent(name=u'Drum_Group', is_enabled=False, translation_channel=DRUM_FEEDBACK_CHANNEL, layer=Layer(matrix=u'drum_pads', scroll_page_up_button=u'up_button', scroll_page_down_button=u'down_button')) def _create_pot_or_fader_modes(self, modes_type_name): modes = ModesComponent(name=u'{}_Modes'.format(modes_type_name.title()), is_enabled=False, layer=Layer(mode_selection_control=u'{}_layout_switch'.format(modes_type_name))) elements_name = u'{}s'.format(modes_type_name) name_displays_element_name = u'{}_parameter_name_displays'.format(modes_type_name) value_displays_element_name = u'{}_parameter_value_displays'.format(modes_type_name) def add_pot_or_fader_mixer_mode(parameter_name): modes.add_mode(parameter_name, (partial(getattr(self._mixer, u'set_{}_parameter_name'.format(modes_type_name)), parameter_name.replace(u'_', u' ').title()), AddLayerMode(self._mixer, Layer(**{u'{}_controls'.format(parameter_name): elements_name, u'{}_parameter_name_displays'.format(modes_type_name): name_displays_element_name, u'{}_displays'.format(parameter_name): value_displays_element_name})))) modes.add_mode(u'dummy', None) add_pot_or_fader_mixer_mode(u'volume') modes.add_mode(u'device', AddLayerMode(self._device, Layer(parameter_controls=elements_name, parameter_name_displays=name_displays_element_name, parameter_value_displays=value_displays_element_name))) if modes_type_name == u'pot': add_pot_or_fader_mixer_mode(u'pan') else: modes.add_mode(u'pan', None) add_pot_or_fader_mixer_mode(u'send_a') add_pot_or_fader_mixer_mode(u'send_b') for i in range(4): modes.add_mode(u'custom{}'.format(i), None) modes.selected_mode = u'pan' if modes_type_name == u'pot' else u'volume' modes.set_enabled(True) self.register_slot(modes, getattr(self, u'_on_{}_mode_byte_changed'.format(modes_type_name)), u'mode_byte') return modes def _create_fader_button_modes(self): self._fader_button_modes = ModesComponent(name=u'Fader_Modes', is_enabled=False, support_momentary_mode_cycling=False, layer=Layer(cycle_mode_button=u'fader_button_modes_button')) self._fader_button_modes.add_mode(u'arm', AddLayerMode(self._mixer, Layer(arm_buttons=u'fader_buttons')), cycle_mode_button_color=u'DefaultButton.Off') self._fader_button_modes.add_mode(u'track_select', AddLayerMode(self._mixer, Layer(track_select_buttons=u'fader_buttons')), cycle_mode_button_color=u'DefaultButton.On') self._fader_button_modes.selected_mode = u'arm' self._fader_button_modes.set_enabled(True) def _create_stop_solo_mute_modes(self): self._stop_solo_mute_modes = ModesComponent(name=u'Stop_Solo_Mute_Modes', is_enabled=False, support_momentary_mode_cycling=False) lower_matrix_row = self._elements.clip_launch_matrix.submatrix[:, 1:] self._stop_solo_mute_modes.add_mode(u'launch', None, cycle_mode_button_color=u'Mode.Launch.On') self._stop_solo_mute_modes.add_mode(u'stop', AddLayerMode(self._session, Layer(stop_track_clip_buttons=lower_matrix_row)), cycle_mode_button_color=u'Session.StopClip') self._stop_solo_mute_modes.add_mode(u'solo', AddLayerMode(self._mixer, Layer(solo_buttons=lower_matrix_row)), cycle_mode_button_color=u'Mixer.SoloOn') self._stop_solo_mute_modes.add_mode(u'mute', AddLayerMode(self._mixer, Layer(mute_buttons=lower_matrix_row)), cycle_mode_button_color=u'Mixer.MuteOff') self._stop_solo_mute_modes.selected_mode = u'launch' self._stop_solo_mute_modes.set_enabled(True) self.__on_stop_solo_mute_mode_changed.subject = self._stop_solo_mute_modes def _create_pad_modes(self): self._pad_modes = ModesComponent(name=u'Pad_Modes', is_enabled=False, layer=Layer(mode_selection_control=u'pad_layout_switch')) suppress_scene_launch_buttons = AddLayerMode(self._background, layer=Layer(scene_launch_buttons=u'scene_launch_buttons')) suppress_all_buttons_around_pads = AddLayerMode(self._background, layer=Layer(scene_launch_buttons=u'scene_launch_buttons', up_button=u'up_button', down_button=u'down_button')) self._pad_modes.add_mode(u'dummy', suppress_all_buttons_around_pads) self._pad_modes.add_mode(u'drum', (suppress_scene_launch_buttons, self._drum_group)) self._pad_modes.add_mode(u'session', LayerMode(self._stop_solo_mute_modes, layer=Layer(cycle_mode_button=self._elements.scene_launch_buttons_raw[1]))) for i in range(6): self._pad_modes.add_mode(u'custom{}'.format(i), suppress_all_buttons_around_pads) upper_matrix_row = self._elements.device_select_matrix.submatrix[:, :1] self._pad_modes.add_mode(u'device_select', (suppress_scene_launch_buttons, self._device.show_device_name_and_bank, AddLayerMode(self._device, layer=Layer(bank_select_buttons=upper_matrix_row, prev_button=u'up_button', next_button=u'down_button')))) self._pad_modes.selected_mode = u'session' self._pad_modes.set_enabled(True) self.__on_pad_mode_changed.subject = self._pad_modes self.__on_pad_mode_byte_changed.subject = self._pad_modes @listens(u'selected_mode') def __on_pad_mode_changed(self, mode): self._recording_modes.selected_mode = u'track' if mode == u'drum' else u'session' self._update_controlled_track() @listens(u'selected_mode') def __on_stop_solo_mute_mode_changed(self, mode): if mode: self._notification_component.show_notification(u'Lower Pad Mode', mode.title()) @listens(u'mode_byte') def __on_pad_mode_byte_changed(self, mode_byte): self._last_pad_layout_byte = mode_byte def _on_pot_mode_byte_changed(self, mode_byte): self._last_pot_layout_byte = mode_byte def _on_fader_mode_byte_changed(self, mode_byte): self._last_fader_layout_byte = mode_byte def _drum_group_changed(self): self._drum_group.set_drum_group_device(self._drum_group_finder.drum_group) def _target_track_changed(self): super(Launchkey_MK3, self)._target_track_changed() self._notification_component.show_notification(u'Track', self._target_track.target_track.name) def _is_instrument_mode(self): return self._pad_modes.selected_mode == u'drum' def _extract_product_id_bytes(self, midi_bytes): u""" Extends standard to deal with each model having a different ID byte, determine whether the model is one of the small models and compose the target product ID bytes based on the bytes that were received. """ id_bytes = super(Launchkey_MK3, self)._extract_product_id_bytes(midi_bytes) model_id_byte = id_bytes[3] if id_bytes[:3] == sysex.NOVATION_MANUFACTURER_ID and model_id_byte in midi.MODEL_ID_BYTES and id_bytes[4:] == midi.MODEL_ID_BYTE_SUFFIX: self._is_small_model = model_id_byte in midi.SMALL_MODEL_ID_BYTES self._product_id_bytes = sysex.NOVATION_MANUFACTURER_ID + id_bytes[3:] return id_bytes